Skip to content

Commit

Permalink
Merge pull request #1141 from lk-iqt/dev-mavlink
Browse files Browse the repository at this point in the history
mavlink bug fixes and mqtt-publisher
  • Loading branch information
anarkiwi authored Feb 4, 2024
2 parents 3020602 + 5221a50 commit b04bee6
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker-extras.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: utils/mavlink-api
file: utils/mavlink-api/Dockerfile
file: utils/mavlink-api/Dockerfile.mavlink-api
platforms: linux/amd64
push: true
tags: iqtlabs/gamutrf-mavlink-api:${{ steps.change_version.outputs.VERSION }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v4
- name: docker build
run: |
docker build -f utils/mavlink-api/Dockerfile utils/mavlink-api -t iqtlabs/gamutrf-mavlink-api:latest
docker build -f utils/mavlink-api/Dockerfile.mavlink-api utils/mavlink-api -t iqtlabs/gamutrf-mavlink-api:latest
test-gamutrf-images:
runs-on: ubuntu-latest
steps:
Expand Down
File renamed without changes.
15 changes: 15 additions & 0 deletions utils/mavlink-api/Dockerfile.mqtt-publisher
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# nosemgrep:github.workflows.config.dockerfile-source-not-pinned
FROM python:3.11-slim

WORKDIR /app
ENV PYTHONPATH=${PYTHONPATH}:${PWD}

RUN pip3 install poetry==1.1.5
COPY pyproject.toml .
RUN poetry config virtualenvs.create false
RUN poetry install --no-dev

COPY mqtt-publisher.py .

# nosemgrep:github.workflows.config.missing-user
CMD ["python3", "mqtt-publisher.py"]
20 changes: 18 additions & 2 deletions utils/mavlink-api/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,28 @@ services:
mavlink-api:
image: iqtlabs/gamutrf-mavlink-api:latest
build:
context: utils/mavlink-api
dockerfile: utils/mavlink-api/Dockerfile
context: .
dockerfile: Dockerfile.mavlink-api
ports:
- "8888:8888"
devices:
- "/dev/pixhawk_serial:/dev/tty.serial1"
networks:
- gamutrf
restart: unless-stopped
#mqtt-publisher:
# image: iqtlabs/gamutrf-mavlink-mqtt-publisher:latest
# build:
# context: .
# dockerfile: Dockerfile.mqtt-publisher
# networks:
# - gamutrf
# environment:
# - MQTT_IP=127.0.0.1
# - MQTT_PORT=1883
# - MQTT_TOPIC=gamutrf/targets
# - QUERY_INTERVAL=1
# - URL_LIST=[["drone", "http://127.0.0.1:8888/gps-data"], ["controller", "http://127.0.0.1:8889/gps-data"]] # Example: [["target1", "https://example1.com"], ["target2", "https://example2.com"]]
# restart: unless-stopped


98 changes: 98 additions & 0 deletions utils/mavlink-api/mqtt-publisher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import os
import time
import logging
import json
import httpx
from paho.mqtt import client as mqtt_client

MQTT_BROKER = os.environ.get("MQTT_IP", "localhost")
MQTT_PORT = os.environ.get("MQTT_PORT", "1883")
MQTT_TOPIC = os.environ.get("MQTT_TOPIC", "/targets")
QUERY_INTERVAL = int(os.environ.get("QUERY_INTERVAL", 1))
URL_LIST = json.loads(
os.environ.get("URL_LIST", '[["default_target", "http://127.0.0.1:8888/gps-data"]]')
)


def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker")
else:
print(f"Failed to connect, return code {rc}")


def publish_data(client, target_name, data):
topic = f"{MQTT_TOPIC}"
try:
client.publish(topic, data)
print(f"Published data to {topic}: {data}")

except Exception as err:
print("could not publish data: %s", err)


def fetch_and_publish(client, target_name, target_url):
try:
response = json.loads(httpx.get(f"{target_url}").text)

data = {
"target_name": target_name,
"gps_stale": response["gps_stale"],
"gps_fix_type": response["gps_fix_type"],
"time_boot_ms": response["time_boot_ms"], # mm
"time_usec": response["time_usec"],
"latitude": response["latitude"], # decimal degrees
"longitude": response["longitude"], # decimal degrees
"altitude": response["altitude"], # mm
"relative_alt": response["relative_alt"], # mm
"heading": response["heading"], # decimal degrees
"vx": response["vx"], # meters/second
"vy": response["vy"], # meters/second
"vz": response["vz"], # meters/second
}

except Exception as err:
print("could not update with external GPS: %s", err)
data = {
"target_name": target_name,
"gps_stale": None,
"gps_fix_type": None,
"time_boot_ms": None, # mm
"time_usec": None,
"latitude": None, # decimal degrees
"longitude": None, # decimal degrees
"altitude": None, # mm
"relative_alt": None, # mm
"heading": None, # decimal degrees
"vx": None, # meters/second
"vy": None, # meters/second
"vz": None, # meters/second
}
publish_data(client, target_name, json.dumps(data))


def main():
try:
client = mqtt_client.Client()
client.on_connect = on_connect
client.connect(MQTT_BROKER, int(MQTT_PORT))
print("Connected to MQTT Broker")
except Exception as err:
logging.error(
f"Could not connect to MQTT broker ({MQTT_BROKER}:{MQTT_PORT}): {err}"
)

while True:
for target in URL_LIST:
if len(target) == 2:
print(f"Attepting to retrieve data from {target}")
target_name, target_url = target
fetch_and_publish(client, target_name, target_url)
else:
print("Invalid entry in URL_LIST. Each entry should be a 2-entry list.")

time.sleep(QUERY_INTERVAL)


if __name__ == "__main__":
main()
31 changes: 17 additions & 14 deletions utils/mavlink-api/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion utils/mavlink-api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ python = ">=3.10,<3.13"
Flask = "^3.0.0"
pymavlink = "^2.4.40"
pyserial = "^3.5"
httpx = "0.26.0"
httpx = "0.25.2"
paho-mqtt = "^1.6.1"

[build-system]
requires = ["poetry-core"]
Expand Down

0 comments on commit b04bee6

Please sign in to comment.