diff --git a/projects/iot-cloud/software/lora2mqtt/src/main.py b/projects/iot-cloud/software/lora2mqtt/src/main.py index 99ebf167..001ceec4 100644 --- a/projects/iot-cloud/software/lora2mqtt/src/main.py +++ b/projects/iot-cloud/software/lora2mqtt/src/main.py @@ -14,6 +14,7 @@ from utils.exceptions import RestException from utils.functions import resolve_mapping +from utils.libelium_decoder import decode_libelium app = Flask(__name__) @@ -37,7 +38,6 @@ def publish_data(): raise RestException(400, "Bad request", "Payload is not a valid JSON.") try: - metrics = data['payload_fields'] metic_time = data['metadata']['time'] app_id = data['app_id'] dev_id = data['dev_id'] @@ -49,9 +49,19 @@ def publish_data(): raise RestException(401, 'Not authorized', 'token authorization HTTP header is missing.') mqtt_topic = resolve_mapping(app.config['mapping']['applications'], app_id, dev_id, authorization) + format = request.args.get('format') + if not format: + try: + metrics = data['payload_fields'] + result = flatten(metrics) + result['timestamp'] = metic_time + except KeyError: + raise RestException(400, 'Bad request', 'Mandatory key is missing from the JSON.') + elif format == 'libelium': + # Define result + result = decode_libelium(data) + - result = flatten(metrics) - result['timestamp'] = metic_time payload = json.dumps(result) app.logger.info('New topic: {}\nPayload: {}'.format(mqtt_topic, payload)) @@ -98,6 +108,24 @@ def __get_config(silent=False, timeout=5): when the Exception becomes silent and None is returned in case of error :return: the decoded config. None if there is an error. """ + return { + "applications": { + + "pysensetest": { + "devices": { + "fakedevice1": { + "mqtt_topic": "lora/fakedevice1" + }, + "lopy1": { + "mqtt_topic": "lora/lopy1" + } + }, + "tokens": [ + "betapasswordbeia" + ] + } + } +} try: r = requests.get(CONFIG_URL, timeout=timeout) return r.json() @@ -144,4 +172,4 @@ def clean_app(app): if __name__ == '__main__': - app.run(host='0.0.0.0', debug=False, port=80) + app.run(host='0.0.0.0', debug=True, port=80) diff --git a/projects/iot-cloud/software/lora2mqtt/src/utils/libelium_decoder.py b/projects/iot-cloud/software/lora2mqtt/src/utils/libelium_decoder.py new file mode 100644 index 00000000..1e75642a --- /dev/null +++ b/projects/iot-cloud/software/lora2mqtt/src/utils/libelium_decoder.py @@ -0,0 +1,70 @@ +import base64 +# de importat log + +def decode_libelium(ttn_json): + authorization_header = ttn_json.headers['authorization'] + if authorization_header == "beiawasp29032021": + APP_ID, params_GW = overtake_metadata(ttn_json) + payload_B=turn_payload_to_bytes(ttn_json) + start_payload_decoded = base64.b64decode(payload_B)[0:3].decode() + print(start_payload_decoded) + log.info('Payload decoded:' + str(start_payload_decoded)) + + if start_payload_decoded == "<=>": + print("Start corect") + log.info('Correct payload') + device_id, key_values = decode_payload(payload_B) + new_key_values = dict(key_values, **params_GW) + print(new_key_values) + mqtt_payload = json.dumps(key_values) + return mqtt_payload + else: + log.error('Incorrect payload') + # return sanic.response.json({'status': 'invalid payload'}) + return None + +def turn_payload_to_bytes(request): + # payload-bytes + payload_str = request.json['payload_raw'] + payload_bytes = bytes(payload_str, 'ascii') + return payload_bytes + +def decode_payload(payload_bytes): + payload_decoded = base64.b64decode(payload_bytes)[5:].decode() + # print(payload_decoded.split('#')) + token_list = payload_decoded.split('#') + device_id = token_list[2] + print(device_id) + key_values = {t.split(':')[0]: t.split(':')[1] for t in token_list if len(t.split(':')) == 2} + print(key_values) + return device_id, key_values + +def overtake_metadata(request): + # chestii relevante (RSSI, ID gateway...) -- nu prea multe + METADATE = request.json['metadata'] + APP_ID = request.json['app_id'] + print(METADATE) + print("////////////////") + # print(APP_ID) + GATEWAYS = METADATE['gateways'] + dictfilt = lambda x, y: dict([(i, x[i]) for i in x if i in set(y)]) + wanted_keys = ('gtw_id', 'snr', 'rssi') + print(range(len(GATEWAYS))) + for i in range(len(GATEWAYS)): + gw_dict = GATEWAYS[i] + params = dictfilt(gw_dict, wanted_keys) + if params['gtw_id'] == GW_ID_BEAM: + params_our_GW = params + print('Parameters of our gateway:') + log.info('Parameters of our gateway:'+params) + print(params) + else: + print('Parameters of other gateway:') + log.info('Parameters of other gateway:' + params) + print(params) + return APP_ID, params_our_GW + + + + +