def on_message(client, userdata, msg): global _callback_event_loop #_LOGGER.info('{} has a message.'.format(_PLUGIN_NAME)) try: if not Ingest.is_available(): _LOGGER.error("Ingest is not availabe") else: inboundPayload = sparkplug_b_pb2.Payload() inboundPayload.ParseFromString(msg.payload) time_stamp = utils.local_timestamp() if _callback_event_loop is None: _LOGGER.debug("Message processing event doesn't yet exist - creating new event loop.") asyncio.set_event_loop(asyncio.new_event_loop()) _callback_event_loop = asyncio.get_event_loop() for metric in inboundPayload.metrics: readingKey = str(uuid.uuid4()) data = { 'asset' : metric.name, 'timestamp' : time_stamp, #metric.timestamp, 'key' : readingKey, 'readings' : { "value": metric.float_value, } } #_LOGGER.info("UUID: " + readingKey) #_LOGGER.info("Metric Name: " + str(metric.name)) #_LOGGER.info(metric) _callback_event_loop.run_until_complete(save_data(data)) #_LOGGER.info('Exiting message callback.') except Exception as e: _LOGGER.error(e)
async def render_post(request): """Store sensor readings from CoAP to FogLAMP Args: request: The payload is a cbor-encoded array that decodes to JSON similar to the following: .. code-block:: python { "timestamp": "2017-01-02T01:02:03.23232Z-05:00", "asset": "pump1", "key": "80a43623-ebe5-40d6-8d80-3f892da9b3b4", "readings": { "velocity": "500", "temperature": { "value": "32", "unit": "kelvin" } } } """ # aiocoap handlers must be defensive about exceptions. If an exception # is raised out of a handler, it is permanently disabled by aiocoap. # Therefore, Exception is caught instead of specific exceptions. # TODO: The payload is documented at # https://docs.google.com/document/d/1rJXlOqCGomPKEKx2ReoofZTXQt9dtDiW_BHU7FYsj-k/edit# # and will be moved to a .rst file code = aiocoap.numbers.codes.Code.VALID # TODO: Decide upon the correct format of message message = '' try: if not Ingest.is_available(): message = '{"busy": true}' raise aiocoap.error.CommunicationKilled(message) try: payload = cbor2.loads(request.payload) except Exception: raise ValueError('Payload must be a dictionary') asset = payload['asset'] timestamp = payload['timestamp'] key = payload['key'] # readings or sensor_values are optional try: readings = payload['readings'] except KeyError: readings = payload[ 'sensor_values'] # sensor_values is deprecated # if optional then # TODO: confirm, do we want to check this? if not isinstance(readings, dict): raise ValueError('readings must be a dictionary') await Ingest.add_readings(asset=asset, timestamp=timestamp, key=key, readings=readings) except (KeyError, ValueError, TypeError) as e: Ingest.increment_discarded_readings() _LOGGER.exception("%d: %s", aiocoap.numbers.codes.Code.BAD_REQUEST, str(e)) raise aiocoap.error.BadRequest(str(e)) except Exception as ex: Ingest.increment_discarded_readings() _LOGGER.exception("%d: %s", aiocoap.numbers.codes.Code.INTERNAL_SERVER_ERROR, str(ex)) raise aiocoap.error.ConstructionRenderableError(str(ex)) return aiocoap.Message(payload=message.encode('utf-8'), code=code)
async def render_post(request): """Store sensor readings from CoAP to FogLAMP Args: request: The payload decodes to JSON similar to the following: .. code-block:: python { "timestamp": "2017-01-02T01:02:03.23232Z-05:00", "asset": "pump1", "key": "80a43623-ebe5-40d6-8d80-3f892da9b3b4", "readings": {"humidity": 0.0, "temperature": -40.0} } } Example: curl -X POST http://localhost:6683/sensor-reading -d '{"timestamp": "2017-01-02T01:02:03.23232Z-05:00", "asset": "pump1", "key": "80a43623-ebe5-40d6-8d80-3f892da9b3b4", "readings": {"humidity": 0.0, "temperature": -40.0}}' """ # TODO: The payload is documented at # https://docs.google.com/document/d/1rJXlOqCGomPKEKx2ReoofZTXQt9dtDiW_BHU7FYsj-k/edit# # and will be moved to a .rst file # TODO: Decide upon the correct format of message message = {'result': 'success'} try: if not Ingest.is_available(): message = {'busy': True} raise web.HTTPServiceUnavailable(reason=message) try: payload = await request.json() except Exception: raise ValueError('Payload must be a dictionary') asset = payload['asset'] timestamp = payload['timestamp'] key = payload['key'] # readings or sensor_values are optional try: readings = payload['readings'] except KeyError: readings = payload[ 'sensor_values'] # sensor_values is deprecated # if optional then # TODO: confirm, do we want to check this? if not isinstance(readings, dict): raise ValueError('readings must be a dictionary') await Ingest.add_readings(asset=asset, timestamp=timestamp, key=key, readings=readings) except (KeyError, ValueError, TypeError) as e: Ingest.increment_discarded_readings() _LOGGER.exception("%d: %s", web.HTTPBadRequest.status_code, str(e)) raise web.HTTPBadRequest(reason=str(e)) except Exception as ex: Ingest.increment_discarded_readings() _LOGGER.exception("%d: %s", web.HTTPInternalServerError.status_code, str(ex)) raise web.HTTPInternalServerError(reason=str(ex)) return web.json_response(message)
async def render_post(request): """Store sensor readings from CoAP to FogLAMP Args: request: The payload decodes to JSON similar to the following: .. code-block:: python { "timestamp": "2017-01-02T01:02:03.23232Z-05:00", "asset": "pump1", "key": "80a43623-ebe5-40d6-8d80-3f892da9b3b4", "readings": { "velocity": "500", "temperature": { "value": "32", "unit": "kelvin" } } } Example: curl -X POST http://localhost:6683/sensor-reading -d '{"timestamp": "2017-01-02T01:02:03.23232Z-05:00", "asset": "pump1", "key": "80a43623-ebe5-40d6-8d80-3f892da9b3b4", "readings": {"velocity": "500", "temperature": {"value": "32", "unit": "kelvin"}}}' """ # TODO: The payload is documented at # https://docs.google.com/document/d/1rJXlOqCGomPKEKx2ReoofZTXQt9dtDiW_BHU7FYsj-k/edit# # and will be moved to a .rst file increment_discarded_counter = False # TODO: Decide upon the correct format of message message = {'result': 'success'} code = web.HTTPOk.status_code try: if not Ingest.is_available(): increment_discarded_counter = True message = {'busy': True} else: payload = await request.json() if not isinstance(payload, dict): raise ValueError('Payload must be a dictionary') asset = payload.get('asset') timestamp = payload.get('timestamp') key = payload.get('key') # readings and sensor_readings are optional try: readings = payload.get('readings') except KeyError: readings = payload.get('sensor_values') # sensor_values is deprecated if not isinstance(readings, dict): raise ValueError('readings must be a dictionary') await Ingest.add_readings(asset=asset, timestamp=timestamp, key=key, readings=readings) except (ValueError, TypeError) as e: increment_discarded_counter = True code = web.HTTPBadRequest.status_code message = {'error': str(e)} _LOGGER.exception(str(e)) except Exception as e: increment_discarded_counter = True code = web.HTTPInternalServerError.status_code message = {'error': str(e)} _LOGGER.exception(str(e)) if increment_discarded_counter: Ingest.increment_discarded_readings() # expect keys in response: # (code = 2xx) result Or busy # (code = 4xx, 5xx) error message['status'] = code return web.json_response(message)
async def render_post(request): """Store sensor readings from CoAP to FogLAMP Args: request: The payload is a cbor-encoded array that decodes to JSON similar to the following: .. code-block:: python { "timestamp": "2017-01-02T01:02:03.23232Z-05:00", "asset": "pump1", "key": "80a43623-ebe5-40d6-8d80-3f892da9b3b4", "readings": { "velocity": "500", "temperature": { "value": "32", "unit": "kelvin" } } } """ # aiocoap handlers must be defensive about exceptions. If an exception # is raised out of a handler, it is permanently disabled by aiocoap. # Therefore, Exception is caught instead of specific exceptions. # TODO: The payload is documented at # https://docs.google.com/document/d/1rJXlOqCGomPKEKx2ReoofZTXQt9dtDiW_BHU7FYsj-k/edit# # and will be moved to a .rst file code = aiocoap.numbers.codes.Code.INTERNAL_SERVER_ERROR increment_discarded_counter = True message = '' try: if not Ingest.is_available(): message = '{"busy": true}' else: payload = cbor2.loads(request.payload) if not isinstance(payload, dict): raise ValueError('Payload must be a dictionary') asset = payload.get('asset') timestamp = payload.get('timestamp') key = payload.get('key') # readings and sensor_readings are optional try: readings = payload['readings'] except KeyError: readings = payload.get( 'sensor_values') # sensor_values is deprecated increment_discarded_counter = False await Ingest.add_readings(asset=asset, timestamp=timestamp, key=key, readings=readings) # Success code = aiocoap.numbers.codes.Code.VALID except (ValueError, TypeError) as e: code = aiocoap.numbers.codes.Code.BAD_REQUEST message = json.dumps({message: str(e)}) except Exception: _LOGGER.exception('Add readings failed') if increment_discarded_counter: Ingest.increment_discarded_readings() return aiocoap.Message(payload=message.encode('utf-8'), code=code)