import sys
import time
import json
from SX127x.LoRa import
import LoRaWAN
from LoRaWAN.MHDR import MHDR
from SX127x.board_config import BOARD
from SX127x.constants import
from MergeImage import *
from paho.mqtt import client as mqtt_client
import logging
import random
import threading
import queue
def publish(client):
while not FLAG_EXIT:
if not client.is_connected():
logging.error("publish: MQTT client is not connected!")
time.sleep(1)
continue
if not lora_message_queue.empty():
msg = lora_message_queue.get()
if msg:
msg_json = json.dumps(msg)
result = client.publish(TOPIC1, msg_json, qos=2)
status = result[0]
if status == 0:
print(f'Send {msg_json} to topic {TOPIC1}')
else:
print(f'Failed to send message to topic {TOPIC1}')
time.sleep(1)
import sys import time import json from SX127x.LoRa import import LoRaWAN from LoRaWAN.MHDR import MHDR from SX127x.board_config import BOARD from SX127x.constants import from MergeImage import * from paho.mqtt import client as mqtt_client import logging import random import threading import queue
BOARD.setup()
BROKER = 'broker.emqx.io' PORT = 8883 TOPIC1 = "SANSLAB/gateway/send-data" TOPIC2 = "SANSLAB/user/send-command" TOPIC3 = "SANSLAB/disconnected/server"
CLIENT_ID = f'gateway-{random.randint(0, 1000)}' USERNAME = 'hieu' PASSWORD = '1'
FIRST_RECONNECT_DELAY = 1 RECONNECT_RATE = 2 MAX_RECONNECT_COUNT = 12 MAX_RECONNECT_DELAY = 60
FLAG_EXIT = False global_data = {}
Create a queue to synchronize LoRa and MQTT operations
lora_message_queue = queue.Queue()
MQTT client setup and callback functions
def on_connect(client, userdata, flags, rc): if rc == 0: print("Connected to MQTT Broker!") client.subscribe(TOPIC2, qos=2) client.subscribe(TOPIC3) else: print(f'Failed to connect, return code {rc}')
def on_disconnect(client, userdata, rc): logging.info("Disconnected with result code: %s", rc) reconnect_count, reconnect_delay = 0, FIRST_RECONNECT_DELAY while reconnect_count < MAX_RECONNECT_COUNT: logging.info("Reconnecting in %d seconds...", reconnect_delay) time.sleep(reconnect_delay) try: client.reconnect() logging.info("Reconnected successfully!") return except Exception as err: logging.error("%s. Reconnect failed. Retrying...", err)
def on_message(client, userdata, msg): print(f'Received {msg.payload.decode()} from {msg.topic} topic')
def connect_mqtt(): client = mqtt_client.Client(mqtt_client.CallbackAPIVersion.VERSION1, CLIENT_ID) client.tls_set(ca_certs='./broker.emqx.io-ca.crt') client.username_pw_set(USERNAME, PASSWORD) client.on_connect = on_connect client.on_message = on_message client.acknowledge = 1 client.will_set("SANSLAB/disconnected/gateway", payload="Gateway suddenly disconnected...", qos=1, retain=False) client.connect(BROKER, PORT, keepalive=120) client.on_disconnect = on_disconnect return client
def publish(client): while not FLAG_EXIT: if not client.is_connected(): logging.error("publish: MQTT client is not connected!") time.sleep(1) continue if not lora_message_queue.empty(): msg = lora_message_queue.get() if msg: msg_json = json.dumps(msg) result = client.publish(TOPIC1, msg_json, qos=2) status = result[0] if status == 0: print(f'Send {msg_json} to topic {TOPIC1}') else: print(f'Failed to send message to topic {TOPIC1}') time.sleep(1)
class LoRaGW(LoRa): def init(self, devaddr=[], nwkey=[], appkey=[], verbose=False): super(LoRaGW, self).init(verbose) self.devaddr = devaddr self.nwkey = nwkey self.appkey = appkey self.set_mode(MODE.SLEEP) self.set_dio_mapping([0, 0, 0, 0, 0, 0]) self.receive_frame = 0 self.image_frame = []
Setup LoRaGW instance
devaddr = [0xFF, 0xFF, 0xFF, 0x00] nwskey = [0xC3, 0x24, 0x64, 0x98, 0xDE, 0x56, 0x5D, 0x8C, 0x55, 0x88, 0x7C, 0x05, 0x86, 0xF9, 0x82, 0x26] appskey = [0x15, 0xF6, 0xF4, 0xD4, 0x2A, 0x95, 0xB0, 0x97, 0x53, 0x27, 0xB7, 0xC1, 0x45, 0x6E, 0xC5, 0x45] lora = LoRaGW(devaddr, nwskey, appskey)
lora.set_mode(MODE.SLEEP) lora.set_dio_mapping([0, 0, 0, 0, 0, 0]) lora.set_freq(915) lora.set_pa_config(pa_select=1) lora.set_spreading_factor(7) lora.set_pa_config(max_power=0x0F, output_power=0x0E) lora.set_sync_word(0x63) lora.set_rx_crc(True) lora.set_bw(BW.BW125) lora.set_coding_rate(CODING_RATE.CR4_5) lora.set_preamble(😎 print(lora) lora.start()
Define the main threads for LoRa and MQTT
def run_mqtt(client): logging.basicConfig(format='%(asctime)s - %(levelname)s: %(message)s', level=logging.DEBUG) client.loop_start() time.sleep(1) if client.is_connected(): publish(client) else: client.loop_stop()
def run_lora(lora_instance): lora_instance.start()
Main function to initiate threads
def main(): client = connect_mqtt() mqtt_thread = threading.Thread(target=run_mqtt, args=(client,)) lora_thread = threading.Thread(target=run_lora, args=(lora,))
if name == "main": main() `