Initial commit
This commit is contained in:
commit
e82ad574ab
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
venv/
|
||||
*.bak
|
||||
64
assethandler.py
Executable file
64
assethandler.py
Executable file
@ -0,0 +1,64 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import asyncio
|
||||
import uuid
|
||||
import aioserial
|
||||
import aiomqtt
|
||||
|
||||
SERIAL_PORT = "/tmp/ttyV0"
|
||||
BAUD = 115200
|
||||
|
||||
SERIAL_PUBLISH_TOPIC = "serial/data"
|
||||
SERIAL_COMMAND_TOPIC = "serial/command"
|
||||
|
||||
|
||||
async def serial_reader(ser, client):
|
||||
while True:
|
||||
data = await ser.read_async(64)
|
||||
if data:
|
||||
await client.publish(SERIAL_PUBLISH_TOPIC, data)
|
||||
# Hand back to event loop
|
||||
await asyncio.sleep(0)
|
||||
|
||||
|
||||
async def mqtt_command_writer(ser, client):
|
||||
async for message in client.messages:
|
||||
topic = str(message.topic)
|
||||
print(message.topic, message.payload)
|
||||
|
||||
if str(topic) == SERIAL_COMMAND_TOPIC:
|
||||
await ser.write_async(message.payload)
|
||||
|
||||
|
||||
async def main():
|
||||
client_id = f"jono-test-{uuid.uuid4()}"
|
||||
interval = 5
|
||||
|
||||
ser = aioserial.AioSerial(
|
||||
port=SERIAL_PORT,
|
||||
baudrate=BAUD,
|
||||
timeout=0.05, # 50 ms
|
||||
)
|
||||
|
||||
while True:
|
||||
try:
|
||||
async with aiomqtt.Client(
|
||||
"127.0.0.1",
|
||||
port=1883,
|
||||
identifier=client_id,
|
||||
) as client:
|
||||
await client.subscribe(SERIAL_COMMAND_TOPIC)
|
||||
|
||||
await asyncio.gather(
|
||||
serial_reader(ser, client),
|
||||
mqtt_command_writer(ser, client),
|
||||
)
|
||||
|
||||
except aiomqtt.MqttError as e:
|
||||
print(e)
|
||||
print(f"Connection lost; reconnecting in {interval} seconds...")
|
||||
await asyncio.sleep(interval)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@ -0,0 +1,5 @@
|
||||
aiomqtt
|
||||
aioserial
|
||||
black
|
||||
pyubx2
|
||||
pyubxutils
|
||||
5
tunnel.sh
Executable file
5
tunnel.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#! /bin/bash
|
||||
|
||||
socat -d -d \
|
||||
pty,raw,echo=0,link=/tmp/ttyV0 \
|
||||
pty,raw,echo=0,link=/tmp/ttyV1
|
||||
42
ubx.py
Executable file
42
ubx.py
Executable file
@ -0,0 +1,42 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import asyncio
|
||||
import aioserial
|
||||
import pyubxutils
|
||||
import pyubx2
|
||||
|
||||
SERIAL_PORT = "/tmp/ttyV1"
|
||||
BAUD = 115200
|
||||
|
||||
|
||||
async def simulator_to_serial(stream, ser):
|
||||
ubr = pyubx2.UBXReader(stream)
|
||||
|
||||
for raw, parsed in ubr:
|
||||
await ser.write_async(raw)
|
||||
|
||||
|
||||
async def serial_to_simulator(stream, ser):
|
||||
while True:
|
||||
data = await ser.read_async(1024)
|
||||
if data:
|
||||
stream.write(data)
|
||||
|
||||
|
||||
async def main():
|
||||
ser = aioserial.AioSerial(port=SERIAL_PORT, baudrate=BAUD)
|
||||
|
||||
with pyubxutils.UBXSimulator(
|
||||
configfile="./ubxsimulator.json",
|
||||
interval=1000,
|
||||
timeout=3,
|
||||
) as stream:
|
||||
|
||||
await asyncio.gather(
|
||||
simulator_to_serial(stream, ser),
|
||||
serial_to_simulator(stream, ser),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
300
ubxsimulator.json
Normal file
300
ubxsimulator.json
Normal file
@ -0,0 +1,300 @@
|
||||
{
|
||||
"interval": 1000,
|
||||
"timeout": 3,
|
||||
"logfile": "./ubxsimulator.log",
|
||||
"simVector": 1,
|
||||
"global": {
|
||||
"lat": 52.477311,
|
||||
"lon": 13.391426,
|
||||
"alt": 50.034,
|
||||
"height": 47494,
|
||||
"sep": 2.54,
|
||||
"hMSL": 50034,
|
||||
"NS": "N",
|
||||
"EW": "E",
|
||||
"gSpeed": 100000,
|
||||
"headMot": 135,
|
||||
"spd": 194.3844,
|
||||
"cog": 126
|
||||
},
|
||||
"ubxmessages": [
|
||||
{
|
||||
"msgCls": 1,
|
||||
"msgId": 7,
|
||||
"rate": 1,
|
||||
"attrs": {
|
||||
"validDate": 1,
|
||||
"validTime": 1,
|
||||
"validMag": 1,
|
||||
"fixType": 3,
|
||||
"numSV": 12,
|
||||
"gnssFixOk": 1,
|
||||
"pDOP": 0.843,
|
||||
"hAcc": 585,
|
||||
"vAcc": 543,
|
||||
"diffSoln": 1,
|
||||
"carrSoln": 1,
|
||||
"lastCorrectionAge": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"msgCls": 1,
|
||||
"msgId": 4,
|
||||
"rate": 1,
|
||||
"attrs": {
|
||||
"gDOP": 0.45,
|
||||
"pDOP": 0.356,
|
||||
"tDOP": 0.3864,
|
||||
"vDOP": 0.98733,
|
||||
"hDOP": 0.96763,
|
||||
"nDOP": 0.9873476,
|
||||
"eDOP": 0.834
|
||||
}
|
||||
},
|
||||
{
|
||||
"msgCls": 1,
|
||||
"msgId": 53,
|
||||
"rate": 4,
|
||||
"attrs": {
|
||||
"version": 1,
|
||||
"numSvs": 13,
|
||||
"reserved0": 0,
|
||||
"gnssId_01": 0,
|
||||
"svId_01": 4,
|
||||
"cno_01": 0,
|
||||
"elev_01": 16,
|
||||
"azim_01": 302,
|
||||
"prRes_01": 0.0,
|
||||
"qualityInd_01": 1,
|
||||
"svUsed_01": 0,
|
||||
"health_01": 1,
|
||||
"diffCorr_01": 0,
|
||||
"smoothed_01": 0,
|
||||
"orbitSource_01": 2,
|
||||
"ephAvail_01": 0,
|
||||
"almAvail_01": 1,
|
||||
"gnssId_02": 0,
|
||||
"svId_02": 5,
|
||||
"cno_02": 48,
|
||||
"elev_02": 15,
|
||||
"azim_02": 73,
|
||||
"prRes_02": 0.0,
|
||||
"qualityInd_02": 4,
|
||||
"svUsed_02": 0,
|
||||
"health_02": 1,
|
||||
"diffCorr_02": 0,
|
||||
"smoothed_02": 0,
|
||||
"orbitSource_02": 2,
|
||||
"ephAvail_02": 0,
|
||||
"almAvail_02": 1,
|
||||
"gnssId_03": 0,
|
||||
"svId_03": 14,
|
||||
"cno_03": 0,
|
||||
"elev_03": -91,
|
||||
"azim_03": 0,
|
||||
"prRes_03": 0.0,
|
||||
"qualityInd_03": 1,
|
||||
"svUsed_03": 0,
|
||||
"health_03": 1,
|
||||
"diffCorr_03": 0,
|
||||
"smoothed_03": 0,
|
||||
"orbitSource_03": 0,
|
||||
"gnssId_04": 0,
|
||||
"svId_04": 18,
|
||||
"cno_04": 50,
|
||||
"elev_04": -91,
|
||||
"azim_04": 0,
|
||||
"prRes_04": 0.0,
|
||||
"qualityInd_04": 4,
|
||||
"svUsed_04": 0,
|
||||
"health_04": 1,
|
||||
"diffCorr_04": 0,
|
||||
"smoothed_04": 0,
|
||||
"orbitSource_04": 0,
|
||||
"gnssId_05": 0,
|
||||
"svId_05": 25,
|
||||
"cno_05": 0,
|
||||
"elev_05": 19,
|
||||
"azim_05": 116,
|
||||
"prRes_05": 0.0,
|
||||
"qualityInd_05": 1,
|
||||
"svUsed_05": 0,
|
||||
"health_05": 1,
|
||||
"diffCorr_05": 0,
|
||||
"smoothed_05": 0,
|
||||
"orbitSource_05": 1,
|
||||
"ephAvail_05": 1,
|
||||
"almAvail_05": 1,
|
||||
"gnssId_06": 0,
|
||||
"svId_06": 26,
|
||||
"cno_06": 45,
|
||||
"elev_06": 61,
|
||||
"azim_06": 285,
|
||||
"prRes_06": 3.5,
|
||||
"qualityInd_06": 7,
|
||||
"svUsed_06": 1,
|
||||
"health_06": 1,
|
||||
"diffCorr_06": 0,
|
||||
"smoothed_06": 0,
|
||||
"orbitSource_06": 1,
|
||||
"ephAvail_06": 1,
|
||||
"almAvail_06": 1,
|
||||
"gnssId_07": 0,
|
||||
"svId_07": 27,
|
||||
"cno_07": 0,
|
||||
"elev_07": 4,
|
||||
"azim_07": 245,
|
||||
"prRes_07": 0.0,
|
||||
"qualityInd_07": 1,
|
||||
"svUsed_07": 0,
|
||||
"health_07": 1,
|
||||
"diffCorr_07": 0,
|
||||
"smoothed_07": 0,
|
||||
"orbitSource_07": 2,
|
||||
"ephAvail_07": 0,
|
||||
"almAvail_07": 1,
|
||||
"gnssId_08": 0,
|
||||
"svId_08": 28,
|
||||
"cno_08": 52,
|
||||
"elev_08": 39,
|
||||
"azim_08": 196,
|
||||
"prRes_08": 2.1,
|
||||
"qualityInd_08": 7,
|
||||
"svUsed_08": 1,
|
||||
"health_08": 1,
|
||||
"diffCorr_08": 0,
|
||||
"smoothed_08": 0,
|
||||
"orbitSource_08": 1,
|
||||
"ephAvail_08": 1,
|
||||
"almAvail_08": 1,
|
||||
"gnssId_09": 0,
|
||||
"svId_09": 29,
|
||||
"cno_09": 43,
|
||||
"elev_09": 56,
|
||||
"azim_09": 67,
|
||||
"prRes_09": 1.8,
|
||||
"qualityInd_09": 7,
|
||||
"svUsed_09": 1,
|
||||
"health_09": 1,
|
||||
"diffCorr_09": 0,
|
||||
"smoothed_09": 0,
|
||||
"orbitSource_09": 1,
|
||||
"ephAvail_09": 1,
|
||||
"almAvail_09": 1,
|
||||
"gnssId_10": 0,
|
||||
"svId_10": 31,
|
||||
"cno_10": 54,
|
||||
"elev_10": 55,
|
||||
"azim_10": 230,
|
||||
"prRes_10": 0.3,
|
||||
"qualityInd_10": 7,
|
||||
"svUsed_10": 1,
|
||||
"health_10": 1,
|
||||
"diffCorr_10": 0,
|
||||
"smoothed_10": 0,
|
||||
"orbitSource_10": 1,
|
||||
"ephAvail_10": 1,
|
||||
"gnssId_11": 2,
|
||||
"svId_11": 120,
|
||||
"cno_11": 0,
|
||||
"elev_11": 28,
|
||||
"azim_11": 196,
|
||||
"prRes_11": 0.0,
|
||||
"qualityInd_11": 1,
|
||||
"svUsed_11": 0,
|
||||
"health_11": 0,
|
||||
"diffCorr_11": 0,
|
||||
"smoothed_11": 0,
|
||||
"orbitSource_11": 7,
|
||||
"gnssId_12": 2,
|
||||
"svId_12": 123,
|
||||
"cno_12": 0,
|
||||
"elev_12": 22,
|
||||
"azim_12": 140,
|
||||
"prRes_12": 0.0,
|
||||
"qualityInd_12": 1,
|
||||
"svUsed_12": 0,
|
||||
"health_12": 0,
|
||||
"diffCorr_12": 0,
|
||||
"smoothed_12": 0,
|
||||
"orbitSource_12": 7,
|
||||
"gnssId_13": 2,
|
||||
"svId_13": 136,
|
||||
"cno_13": 0,
|
||||
"elev_13": 29,
|
||||
"azim_13": 171,
|
||||
"prRes_13": 0.0,
|
||||
"qualityInd_13": 1,
|
||||
"svUsed_13": 0,
|
||||
"health_13": 0,
|
||||
"diffCorr_13": 0,
|
||||
"smoothed_13": 0,
|
||||
"orbitSource_13": 7
|
||||
}
|
||||
}
|
||||
],
|
||||
"nmeamessages": [
|
||||
{
|
||||
"talker": "GN",
|
||||
"msgId": "GGA",
|
||||
"rate": 1,
|
||||
"attrs": {
|
||||
"status": "A",
|
||||
"posMode": "A",
|
||||
"navStatus": "V",
|
||||
"sepUnit": "M",
|
||||
"altUnit": "M",
|
||||
"quality": 5,
|
||||
"numSV": 12,
|
||||
"HDOP": 0.9873476,
|
||||
"diffAge": 10,
|
||||
"diffStation": 2746
|
||||
}
|
||||
},
|
||||
{
|
||||
"talker": "GN",
|
||||
"msgId": "RMC",
|
||||
"rate": 1,
|
||||
"attrs": {
|
||||
"status": "A",
|
||||
"posMode": "A",
|
||||
"navStatus": "V"
|
||||
}
|
||||
},
|
||||
{
|
||||
"talker": "P",
|
||||
"msgId": "QTMVERNO",
|
||||
"rate": 1,
|
||||
"attrs": {
|
||||
"verstr": "LG290P03AANR01A03S",
|
||||
"builddate": "2025/03/23",
|
||||
"buildtime": "12:02:34"
|
||||
}
|
||||
},
|
||||
{
|
||||
"talker": "P",
|
||||
"msgId": "QTMPVT",
|
||||
"rate": 1,
|
||||
"attrs": {
|
||||
"msgver": 1,
|
||||
"tow": 1000,
|
||||
"date": "20221225",
|
||||
"time": 83737.000,
|
||||
"fixtype": 3,
|
||||
"numsv": 22,
|
||||
"leaps": 3,
|
||||
"lat": 52.477311,
|
||||
"lon": 13.391426,
|
||||
"alt": 45.287,
|
||||
"sep": 31.075,
|
||||
"veln": 0.034,
|
||||
"vele": 0.016,
|
||||
"veld": 0.065,
|
||||
"spd": 23.48,
|
||||
"hdg": 182.12,
|
||||
"hdop": 1.23,
|
||||
"pdop": 1.18
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user