MQTT bridged LoRa networks - demo

Start a Mosquitto container first. For example:

  • Use codes\_demo\1_start_broker.sh to start a Mosquitto container on Raspberry Pi.
  • Config files are in mqtt_config\mqtt.
  • set allow_anonymous true in mqtt_config\mqtt\config\mosquitto.conf to allow anonymous client.

Getting Started

What this notebook does:

  • Using a client on PC
  • List connected nodes
  • Send messages to remote nodes:
    • Return results (read GPIOs)via RPC mechanism.
    • Write data to remote nodes (write GPIOs).
    • Execute arbitrary code on remote nodes.

In [1]:
import os
import sys
import time
import json
 
sys.path.append(os.path.abspath(os.path.join(os.path.pardir, os.path.sep.join(['..', 'codes']), 'client')))
sys.path.append(os.path.abspath(os.path.join(os.path.pardir, os.path.sep.join(['..', 'codes']), 'node')))
sys.path.append(os.path.abspath(os.path.join(os.path.pardir, os.path.sep.join(['..', 'codes']), 'shared')))
sys.path.append(os.path.abspath(os.path.join(os.path.pardir, os.path.sep.join(['..', 'codes']), 'micropython')))
 
import client
from collections import OrderedDict

Start client


In [2]:
the_client = client.Client()
the_client.start()

while not the_client.status['Is connected']:            
    time.sleep(1)
    print('Node not ready yet.')


My name is Client_366

Sending 277 bytes
Message:
OrderedDict([('command', 'set connection name'), ('correlation_id', '2017-09-15 20:27:01.527900'), ('kwargs', {'name': 'Client_366'}), ('message_id', '2017-09-15 20:27:01.527900'), ('message_type', 'command'), ('need_result', True), ('receiver', 'Hub'), ('reply_to', 'Client_366'), ('sender', 'Client_366')])


[Connected: ('123.240.78.187', 1883)]
[Listen to messages]

Data received: 280 bytes
Message:
OrderedDict([('correlation_id', '601981'), ('function', 'update_link'), ('kwargs', {'node_eui': '32aea4fffe054928', 'rssi': -67, 'gateway_eui': '32aea4fffe809528'}), ('message_id', '601981'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'update_link'

Data received: 280 bytes
Message:
OrderedDict([('correlation_id', '639981'), ('function', 'update_link'), ('kwargs', {'node_eui': '32aea4fffe054928', 'rssi': -22, 'gateway_eui': '260ac4fffe0c1764'}), ('message_id', '639981'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '260ac4fffe0c1764'), ('sender', '260ac4fffe0c1764')])

'Worker' object has no attribute 'update_link'
Node not ready yet.

List of nodes


In [3]:
# NODE1_EUI = 'f3d308fffe00'
# GATEWAY1_EUI = '32aea4fffe809528'
# NODE2_EUI = '32aea4fffe054928'
# GATEWAY2_EUI = '260ac4fffe0c1764'

gateways = ['32aea4fffe809528', '260ac4fffe0c1764']
gateways


Out[3]:
['32aea4fffe809528', '260ac4fffe0c1764']

In [4]:
gateway = '260ac4fffe0c1764'
gateway


Out[4]:
'260ac4fffe0c1764'

Prepare messages


In [5]:
messages = OrderedDict();


Data received: 276 bytes
Message:
OrderedDict([('correlation_id', '603472'), ('function', 'update_link'), ('kwargs', {'node_eui': 'f3d308fffe00', 'rssi': -19, 'gateway_eui': '32aea4fffe809528'}), ('message_id', '603472'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'update_link'

Data received: 276 bytes
Message:
OrderedDict([('correlation_id', '641520'), ('function', 'update_link'), ('kwargs', {'node_eui': 'f3d308fffe00', 'rssi': -65, 'gateway_eui': '260ac4fffe0c1764'}), ('message_id', '641520'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '260ac4fffe0c1764'), ('sender', '260ac4fffe0c1764')])

'Worker' object has no attribute 'update_link'

Data received: 326 bytes

DEMOs



In [6]:
messages['blink_led'] = {'message_type': 'command',
                         'command': 'blink led',
                         'kwargs': {'times': 3, 'on_seconds': 0.1, 'off_seconds': 0.1}}

the_client.request('Hub', messages['blink_led']);


Message:
OrderedDict([('correlation_id', '603993'), ('function', 'transmit_payload'), ('kwargs', {'payload_string': '{"message": "ESP8266_f1d30800 199", "time": 606065, "to": null, "from": "f3d308fffe00"}'}), ('message_id', '603993'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'transmit_payload'

Sending 275 bytes
Message:
OrderedDict([('command', 'blink led'), ('correlation_id', '2017-09-15 20:27:04.309300'), ('kwargs', {'on_seconds': 0.1, 'times': 3, 'off_seconds': 0.1}), ('message_id', '2017-09-15 20:27:04.309300'), ('message_type', 'command'), ('receiver', 'Hub'), ('reply_to', 'Client_366'), ('sender', 'Client_366')])


Data received: 275 bytes
Message:
OrderedDict([('command', 'blink led'), ('correlation_id', '2017-09-15 20:27:04.309300'), ('kwargs', {'on_seconds': 0.1, 'times': 3, 'off_seconds': 0.1}), ('message_id', '2017-09-15 20:27:04.309300'), ('message_type', 'command'), ('receiver', 'Hub'), ('reply_to', 'Client_366'), ('sender', 'Client_366')])


Data received: 280 bytes
Message:
OrderedDict([('correlation_id', '605184'), ('function', 'update_link'), ('kwargs', {'node_eui': '32aea4fffe054928', 'rssi': -66, 'gateway_eui': '32aea4fffe809528'}), ('message_id', '605184'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'update_link'

Send LoRa Packets


In [29]:
# SF8_NODE_EUI = 'f3d308fffe00'
# SF8_GATEWAY_EUI = '32aea4fffe809528'
# SF9_NODE_EUI = '32aea4fffe054928'
# SF9_GATEWAY_EUI = '260ac4fffe0c1764'

pay_load = {"message": "LoRa packet sent via MQTT.", "time": int(time.time()), "to": "32aea4fffe054928", "from": the_client.node.worker.name }
pay_load_json = json.dumps(pay_load) 
pay_load_json


Out[29]:
'{"time": 1505486572, "to": "32aea4fffe054928", "from": "Client_366", "message": "LoRa packet sent via MQTT."}'

In [38]:
# transmit_payload: gateway will transmit the LoRa payload regardless of routing table.

messages['LoRa test'] = {'message_type': 'function',
                         'function': 'transmit_payload',
                         'kwargs': {'payload_string': pay_load_json}}

the_client.request(gateway, messages['LoRa test']);


Sending 391 bytes
Message:
OrderedDict([('correlation_id', '2017-09-15 22:49:32.665500'), ('function', 'transmit_payload'), ('kwargs', {'payload_string': '{"time": 1505486572, "to": "32aea4fffe054928", "from": "Client_366", "message": "LoRa packet sent via MQTT."}'}), ('message_id', '2017-09-15 22:49:32.665500'), ('message_type', 'function'), ('receiver', '260ac4fffe0c1764'), ('reply_to', 'Client_366'), ('sender', 'Client_366')])


Data received: 280 bytes
Message:
OrderedDict([('correlation_id', '511229'), ('function', 'update_link'), ('kwargs', {'node_eui': '32aea4fffe054928', 'rssi': -22, 'gateway_eui': '260ac4fffe0c1764'}), ('message_id', '511229'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '260ac4fffe0c1764'), ('sender', '260ac4fffe0c1764')])

'Worker' object has no attribute 'update_link'

Data received: 280 bytes
Message:
OrderedDict([('correlation_id', '534948'), ('function', 'update_link'), ('kwargs', {'node_eui': '32aea4fffe054928', 'rssi': -77, 'gateway_eui': '32aea4fffe809528'}), ('message_id', '534948'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'update_link'

Data received: 346 bytes
Message:
OrderedDict([('correlation_id', '511834'), ('function', 'transmit_payload'), ('kwargs', {'payload_string': '{"via": null, "message": "ESP32_30aea4054928 36", "time": 497137, "from": "32aea4fffe054928", "to": null}'}), ('message_id', '511834'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '260ac4fffe0c1764'), ('sender', '260ac4fffe0c1764')])

'Worker' object has no attribute 'transmit_payload'

Data received: 265 bytes
Message:
OrderedDict([('correlation_id', '536650'), ('function', 'update_link'), ('kwargs', {'node_eui': None, 'rssi': -9, 'gateway_eui': '32aea4fffe809528'}), ('message_id', '536650'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'update_link'

Data received: 356 bytes
Message:
OrderedDict([('correlation_id', '540014'), ('function', 'transmit_payload'), ('kwargs', {'payload_string': '{"via": "260ac4fffe0c1764", "message": "ESP8266_f1d30800 34", "time": 519363, "from": "f3d308fffe00", "to": null}'}), ('message_id', '540014'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'transmit_payload'

Data received: 280 bytes
Message:
OrderedDict([('correlation_id', '552149'), ('function', 'update_link'), ('kwargs', {'node_eui': '32aea4fffe054928', 'rssi': -75, 'gateway_eui': '32aea4fffe809528'}), ('message_id', '552149'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'update_link'

Data received: 280 bytes
Message:
OrderedDict([('correlation_id', '528959'), ('function', 'update_link'), ('kwargs', {'node_eui': '32aea4fffe054928', 'rssi': -23, 'gateway_eui': '260ac4fffe0c1764'}), ('message_id', '528959'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '260ac4fffe0c1764'), ('sender', '260ac4fffe0c1764')])

'Worker' object has no attribute 'update_link'

Data received: 346 bytes
Message:
OrderedDict([('correlation_id', '529648'), ('function', 'transmit_payload'), ('kwargs', {'payload_string': '{"via": null, "message": "ESP32_30aea4054928 37", "time": 514273, "from": "32aea4fffe054928", "to": null}'}), ('message_id', '529648'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '260ac4fffe0c1764'), ('sender', '260ac4fffe0c1764')])

'Worker' object has no attribute 'transmit_payload'

Data received: 276 bytes
Message:
OrderedDict([('correlation_id', '531762'), ('function', 'update_link'), ('kwargs', {'node_eui': 'f3d308fffe00', 'rssi': -69, 'gateway_eui': '260ac4fffe0c1764'}), ('message_id', '531762'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '260ac4fffe0c1764'), ('sender', '260ac4fffe0c1764')])

'Worker' object has no attribute 'update_link'

Data received: 276 bytes
Message:
OrderedDict([('correlation_id', '555308'), ('function', 'update_link'), ('kwargs', {'node_eui': 'f3d308fffe00', 'rssi': -19, 'gateway_eui': '32aea4fffe809528'}), ('message_id', '555308'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'update_link'

Data received: 340 bytes
Message:
OrderedDict([('correlation_id', '556057'), ('function', 'transmit_payload'), ('kwargs', {'payload_string': '{"via": null, "message": "ESP8266_f1d30800 36", "time": 557711, "from": "f3d308fffe00", "to": null}'}), ('message_id', '556057'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'transmit_payload'

In [41]:
# dispatch_payload_json: 
    # find the nearest gateway to the destination node.
    # forward the payload data, and deligate to the nearest gateway to transmit the LoRa payload. 

messages['LoRa test'] = {'message_type': 'function',
                         'function': 'dispatch_payload_json',
                         'kwargs': {'pay_load_json': pay_load_json}}

the_client.request(gateway, messages['LoRa test']);



Sending 395 bytesMessage:
OrderedDict([('correlation_id', '588815'), ('function', 'update_link'), ('kwargs', {'node_eui': 'f3d308fffe00', 'rssi': -20, 'gateway_eui': '32aea4fffe809528'}), ('message_id', '588815'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])


'Worker' object has no attribute 'update_link'
Message:
OrderedDict([('correlation_id', '2017-09-15 22:50:34.705300'), ('function', 'dispatch_payload_json'), ('kwargs', {'pay_load_json': '{"time": 1505486572, "to": "32aea4fffe054928", "from": "Client_366", "message": "LoRa packet sent via MQTT."}'}), ('message_id', '2017-09-15 22:50:34.705300'), ('message_type', 'function'), ('receiver', '260ac4fffe0c1764'), ('reply_to', 'Client_366'), ('sender', 'Client_366')])


Data received: 340 bytes
Message:
OrderedDict([('correlation_id', '589431'), ('function', 'transmit_payload'), ('kwargs', {'payload_string': '{"via": null, "message": "ESP8266_f1d30800 38", "time": 590835, "from": "f3d308fffe00", "to": null}'}), ('message_id', '589431'), ('message_type', 'function'), ('receiver', 'Hub'), ('reply_to', '32aea4fffe809528'), ('sender', '32aea4fffe809528')])

'Worker' object has no attribute 'transmit_payload'

Stop the demo


In [ ]:
# Stopping
the_client.stop()
the_client = None
print('\n[________________ Demo stopped ________________]\n')