2018-11-15 18:21:45 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import base64
|
|
|
|
import json
|
|
|
|
import logging
|
|
|
|
from random import randint
|
|
|
|
import socket
|
|
|
|
|
|
|
|
from board_config import LoraBoardDraguino
|
|
|
|
import RPi.GPIO as GPIO
|
|
|
|
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
|
|
|
2018-11-15 19:56:17 +00:00
|
|
|
# TODO: Move these to a settings file
|
|
|
|
GATEWAY_SEND_ENABLED = False
|
2018-11-15 18:21:45 +00:00
|
|
|
GATEWAY_HOST = "router.eu.thethings.network"
|
|
|
|
GATEWAY_PORT = 1700
|
|
|
|
|
|
|
|
|
2018-11-15 19:50:38 +00:00
|
|
|
def log_packet(self, board, packet):
|
2018-11-15 19:56:17 +00:00
|
|
|
print("[{}] [receive] freq: {}, crc: {}, signal-noise-ratio: {}, signal strength: {} (packet: {}), {}".format(
|
2018-11-15 19:50:38 +00:00
|
|
|
payload['datetime'].isoformat(),
|
|
|
|
board.frequency,
|
|
|
|
payload.get('crc'),
|
|
|
|
payload.get('pkt_snr'),
|
|
|
|
payload.get('rssi'),
|
|
|
|
payload.get('pkt_rssi'),
|
2018-11-15 19:56:17 +00:00
|
|
|
payload['payload'].hex()
|
2018-11-15 19:50:38 +00:00
|
|
|
))
|
2018-11-15 18:21:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
def construct_semtec_udp(board, payload):
|
|
|
|
# https://github.com/Lora-net/packet_forwarder/blob/d0226eae6e7b6bbaec6117d0d2372bf17819c438/PROTOCOL.TXT#L99
|
|
|
|
frame = bytearray()
|
|
|
|
frame.append(2) # Protocol version = 2
|
|
|
|
frame.extend([randint(0, 255), randint(0, 255)]) # Random numbers
|
2018-11-15 19:33:42 +00:00
|
|
|
frame.extend([
|
|
|
|
0x80, 0xFA, 0x5C, 0xFF,
|
|
|
|
0xFF, 0x69, 0x33, 0xBB
|
|
|
|
]) # TODO: construct from hardware
|
2018-11-15 18:21:45 +00:00
|
|
|
|
|
|
|
data = {
|
|
|
|
"rxpk":
|
|
|
|
{
|
|
|
|
"time": payload['datetime'].isoformat(),
|
|
|
|
"freq": board.frequency / 1000 / 1000,
|
|
|
|
"stat": 1 if payload['crc'] is True else -1,
|
|
|
|
"modu": "LORA",
|
|
|
|
"datr": "SF7BW125", # TODO: configurable
|
|
|
|
"codr": "4/5",
|
|
|
|
"rssi": payload['pkt_rssi'],
|
|
|
|
"lsnr": payload['pkt_snr'],
|
|
|
|
"size": len(payload['payload']),
|
2018-11-15 19:33:42 +00:00
|
|
|
"data": base64.standard_b64encode(payload['payload'])
|
|
|
|
.decode("utf-8")
|
2018-11-15 18:21:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
frame.extend(map(ord, json.dumps(data)))
|
|
|
|
|
|
|
|
return bytes(frame)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2018-11-15 19:56:17 +00:00
|
|
|
sock = None
|
|
|
|
if GATEWAY_SEND_ENABLED:
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
|
2018-11-15 19:50:38 +00:00
|
|
|
|
2018-11-15 18:21:45 +00:00
|
|
|
with LoraBoardDraguino(433300000, 7) as board:
|
|
|
|
board.set_mode_rx()
|
2018-11-15 19:33:42 +00:00
|
|
|
print("Listening at SF{} on {} MHz".format(
|
|
|
|
board.sf,
|
|
|
|
board.frequency / 1000000
|
|
|
|
))
|
2018-11-15 19:50:38 +00:00
|
|
|
|
2018-11-15 18:21:45 +00:00
|
|
|
while True:
|
2018-11-15 19:50:38 +00:00
|
|
|
if GPIO.input(board._pin_dio0) != 1:
|
|
|
|
continue
|
|
|
|
|
|
|
|
payload = board.receive_package()
|
|
|
|
|
2018-11-15 19:56:17 +00:00
|
|
|
if GATEWAY_SEND_ENABLED:
|
|
|
|
semtec_udp = construct_semtec_udp(board, payload)
|
|
|
|
sock.sendto(semtec_udp, (GATEWAY_HOST, GATEWAY_PORT))
|
|
|
|
logging.info(semtec_udp)
|
2018-11-15 19:50:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
log_packet(board, payload)
|