def publish_current_observation(data, ch): co = data['current_observation'] current_obs = { 'timestamp' : time_util.dt_from_epoch_with_tz(int(co['local_epoch']), co['local_tz_long']), 'station_id' : co['station_id'], 'temp_C' : co['temp_c'], 'windchill_C' : _float(co['windchill_c']), 'dewpoint_C' : co['dewpoint_c'], 'rel_humid' : _float(co['relative_humidity'].replace("%", "")), 'windspeed_mph' : co['wind_mph'], 'windgust_mph' : co['wind_gust_mph'], 'wind_dir' : co['wind_degrees'], 'pressure_mb' : _float(co['pressure_mb']), 'visibility_mi' : _float(co['visibility_mi']), 'weather' : co['weather'], 'precip_mm' : { '1hr' : _float(co['precip_1hr_metric']), 'today' : _float(co['precip_today_metric']), }, } # publish to wx.current_observation ch.basic_publish( exchange='weather', routing_key='current_observation', properties = pika.BasicProperties( content_type = 'application/json' ), body = serializer_utils.serialize(current_obs, 'application/json') )
def publish_hourly_forecast(data, ch): hourly_forecast = [] for hf in data['hourly_forecast']: hf['FCTTIME'] = fcttime_to_datetime(hf['FCTTIME']) hourly_forecast.append({ 'timestamp' : hf['FCTTIME'], 'condition' : (hf['condition'], hf['fctcode']), 'temp_C' : _float(hf['temp']['metric']), 'dewpoint_C' : _float(hf['dewpoint']['metric']), 'windchill_C' : _float(hf['windchill']['metric']), 'rel_humid' : _float(hf['humidity']), 'windspeed_mph' : _float(hf['wspd']['english']), 'wind_dir' : _float(hf['wdir']['degrees']), 'pct_of_precip' : _float(hf['pop']), 'qpf_mm' : _float(hf['qpf']['metric']), 'snow_mm' : _float(hf['snow']['metric']), 'sky' : _float(hf['sky']), 'uvi' : _float(hf['uvi']), }) # publish to wx.hourly_forecast ch.basic_publish( exchange='weather', routing_key='hourly_forecast', properties = pika.BasicProperties( content_type = 'application/json' ), body = serializer_utils.serialize(hourly_forecast, 'application/json') )
def publish_sensor_data(self, routing_key, body): with self.__publisher_chan_lock: self.__publisher_chan.basic_publish( exchange = 'sensor_data', routing_key = routing_key, properties = pika.BasicProperties( content_type = serializer_utils.CONTENT_TYPE_JSON ), body = serializer_utils.serialize(body, serializer_utils.CONTENT_TYPE_JSON) )
def publish_event(self, routing_key, event, **kwargs): with self.__publisher_chan_lock: self.__publisher_chan.basic_publish( exchange = 'events', routing_key = routing_key, properties = pika.BasicProperties( content_type = serializer_utils.CONTENT_TYPE_JSON ), body = serializer_utils.serialize( { 'name' : event, 'data' : kwargs, }, serializer_utils.CONTENT_TYPE_JSON ) )
def __runner(self): """ The thread target; handles RPC invocations and publishes the result """ conn = pika.BlockingConnection(self.__connection_params) chan = conn.channel() chan.add_on_return_callback(self.__on_returned_msg) while not self.__shutdown_event.is_set(): try: req = self.__pending_requests.get(True, 5) self._logger.debug("invoking %r", req) response = {} try: response['result'] = req.callback(*req.args) except: self._logger.warn("exception invoking %r", req, exc_info = True) # the exception value response['exception'] = sys.exc_info()[1] resp_body = serializer_utils.serialize(response, req.content_type) chan.basic_publish( exchange='', routing_key = req.reply_to, properties = pika.BasicProperties( correlation_id = req.correlation_id, content_type = req.content_type, ), body = resp_body ) except Queue.Empty: pass conn.close()
def __handle_timeout(self): # self._logger.debug("timeout fired") if not self.__shutdown: self.__connection.add_timeout(0.5, self.__handle_timeout) while not self.__rpc_queue.empty(): request = self.__pending_requests[self.__rpc_queue.get()] self._logger.debug("publishing message for ticket %s", request.ticket) self.__channel.basic_publish( exchange="", routing_key=request.queue, mandatory=True, properties=pika.BasicProperties( reply_to=self.__private_queue_name, correlation_id=request.ticket, content_type=_CONTENT_TYPE ), body=serializer_utils.serialize({"command": request.command, "args": request.args}, _CONTENT_TYPE), )
def __dispatch_xb_frame(self, frame): """handles incoming XBee frames""" # @todo make utctime, but this will affect the db logger, and the # plotter, too! frame['_timestamp'] = SYSTEM_TZ.localize(datetime.datetime.now()) try: if 'frame_id' in frame: # this is a response of some kind self._logger.debug( "found reply of type %s with frame_id %02x", frame['id'], ord(frame['frame_id']) ) with self.__correlation_lock: if frame['frame_id'] in self.__correlations: correlation = self.__correlations[frame['frame_id']] props = correlation['props'] keep_alive = correlation['keep_alive'] self._xb_rx_chan.basic_publish( exchange = '', routing_key = props.reply_to, properties = pika.BasicProperties( correlation_id = props.correlation_id, content_type = _CONTENT_TYPE ), body = serializer_utils.serialize(frame, _CONTENT_TYPE) ) if not keep_alive: del self.__correlations[frame['frame_id']] else: self._logger.error( "no correlation found for response: %r", frame ) # this needs to get called every now and then self.__reap_unfinished_requests() else: frame_addr = 'unknown' if 'source_addr' in frame: frame_addr = format_addr(frame['source_addr']) if 'source_addr_long' in frame: frame_addr = format_addr(frame['source_addr_long']) # something like "zb_rx.00:11:22:33:44:55:66:0a" routing_key = '%s.%s' % (frame['id'], frame_addr) self._logger.debug("routing_key: %s", routing_key) self._xb_rx_chan.basic_publish( exchange = self.RAW_XBEE_PACKET_EXCHANGE, routing_key = routing_key, properties = pika.BasicProperties( content_type = _CONTENT_TYPE ), body = serializer_utils.serialize(frame, _CONTENT_TYPE) ) except: self._logger.error( "unhandled exception processing incoming frame", exc_info = True )
with self.__rpc_chan_lock: # keep_alive tells the remote end to keep the request around for # multiple replies self.__rpc_chan.basic_publish( exchange = '', routing_key = 'xbee_tx', properties = pika.BasicProperties( reply_to = self.__queue_name, correlation_id = req.ticket, content_type = serializer_utils.CONTENT_TYPE_BINARY, headers = dict(keep_alive = str(async)) ), immediate = True, mandatory = True, body = serializer_utils.serialize(req.msg_body, serializer_utils.CONTENT_TYPE_BINARY) ) if not async: # wait 30s for the reply to our call to be received req.event.wait(30) if not req.event.is_set(): raise NoResponse("no reply received for %r" % req) return req.response else: return req # }}}