Skip to content

Commit

Permalink
Merge pull request #5 from IQTLabs/egi-testing
Browse files Browse the repository at this point in the history
Egi testing
  • Loading branch information
luke-iqt committed Feb 3, 2021
2 parents 59d6a2e + d286a80 commit 4e520a4
Show file tree
Hide file tree
Showing 11 changed files with 197 additions and 108 deletions.
12 changes: 10 additions & 2 deletions adsb-mqtt/adsb-mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
import mqtt_wrapper
import pandas as pd


ID = str(random.randint(1,100001))

# Clean out observations this often
OBSERVATION_CLEAN_INTERVAL = 30
# Socket read timeout
Expand Down Expand Up @@ -423,11 +426,15 @@ def dump1090Read(self) -> str:
def run(self):
"""Run the flight tracker.
"""
self.__mqtt_bridge = mqtt_wrapper.bridge(host = self.__mqtt_broker, port = self.__mqtt_port, client_id = "skyscan-adsb-mqtt-%d" % (os.getpid())) # TOOD: , user_id = args.mqtt_user, password = args.mqtt_password)
timeHeartbeat = 0
self.__mqtt_bridge = mqtt_wrapper.bridge(host = self.__mqtt_broker, port = self.__mqtt_port, client_id = "skyscan-adsb-mqtt-%s" % (ID)) # TOOD: , user_id = args.mqtt_user, password = args.mqtt_password)
#threading.Thread(target = self.__publish_thread, daemon = True).start()

self.__mqtt_bridge.publish("skyscan/registration", "skyscan-adsb-mqtt-"+ID+" Registration", 0, False)

while True:
if timeHeartbeat < time.mktime(time.gmtime()):
timeHeartbeat = time.mktime(time.gmtime()) + 10
self.__mqtt_bridge.publish("skyscan/heartbeat", "skyscan-adsb-mqtt-"+ID+" Heartbeat", 0, False)
if not self.dump1090Connect():
continue
for data in self.dump1090Read():
Expand All @@ -446,6 +453,7 @@ def run(self):
retain = False
self.__mqtt_bridge.publish(self.__mqtt_topic, self.__observations[icao24].json(), 0, retain)
#logging.info("%s alt %5d trk %3d spd %3d %s" % (self.__observations[icao24].getIcao24(), self.__observations[icao24].getAltitude(), self.__observations[icao24].getHeading(), self.__observations[icao24].getGroundSpeed(), self.__observations[icao24].getType()))
time.sleep(0.01)

def cleanObservations(self):
"""Clean observations for planes not seen in a while
Expand Down
10 changes: 8 additions & 2 deletions axis-ptz/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from sensecam_control import vapix_control,vapix_config



ID = str(random.randint(1,100001))
tiltCorrect = 15
args = None
camera = None
Expand Down Expand Up @@ -238,17 +238,23 @@ def main():
# Sleep for a bit so we're not hammering the HAT with updates
time.sleep(0.005)
print("connecting to MQTT broker at "+ args.mqtt_host+", channel '"+args.mqtt_topic+"'")
client = mqtt.Client("skyscan-axis-ptz-camera") #create new instance
client = mqtt.Client("skyscan-axis-ptz-camera-" + ID) #create new instance

client.on_message=on_message #attach function to callback

client.connect(args.mqtt_host) #connect to broker
client.loop_start() #start the loop
client.subscribe(args.mqtt_topic+"/#")
client.publish("skyscan/registration", "skyscan-axis-ptz-camera-"+ID+" Registration", 0, False)

#############################################
## Main Loop ##
#############################################
timeHeartbeat = 0
while True:
if timeHeartbeat < time.mktime(time.gmtime()):
timeHeartbeat = time.mktime(time.gmtime()) + 10
client.publish("skyscan/heartbeat", "skyscan-axis-ptz-camera-"+ID+" Heartbeat", 0, False)
time.sleep(0.1)


Expand Down
13 changes: 5 additions & 8 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,9 @@ services:

egi:
build: ./egi
entrypoint: "/app/egi.py -m mqtt"
environment:
- LAT=${LAT}
- LONG=${LONG}
- ALT=${ALT}
- ROLL=${ROLL}
- PITCH=${PITCH}
- YAW=${YAW}
entrypoint: bash -c "gpsd ${GPS_SERIAL} -F /var/run/gpsd.sock && python3 egi_mqtt.py -m mqtt -l ${LAT} -L ${LONG} -a ${ALT} -r ${ROLL} -p ${PITCH} -y ${YAW}"
devices:
- /dev/ttyACM0
depends_on:
- mqtt
restart: unless-stopped
10 changes: 6 additions & 4 deletions egi/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
FROM debian

RUN apt update && \
apt install -y python3 python3-pip && \
pip3 install paho-mqtt
apt install -y python3 python3-pip gpsd-clients gpsd

RUN mkdir -p /app/
WORKDIR /app
ADD *.txt /app/
RUN pip3 install -r requirements.txt
ADD *.py /app/

#ENTRYPOINT python3 /tmp/egi.py
ENTRYPOINT sh -c "gpsd /dev/ttyACM0 -F /var/run/gpsd.sock && bash"

#docker run -d --restart unless-stopped --network=host -v /home/pi/:/tmp/ --name lamp docker-registry.iqt.org/mission-capabilities/rpi-stats-reporting/lamp-control
#docker run -it --device=/dev/ttyACM0 skyscan_egi
#python3 egi_mqtt.py -h
79 changes: 0 additions & 79 deletions egi/egi.py

This file was deleted.

137 changes: 137 additions & 0 deletions egi/egi_mqtt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#!/usr/bin/env python3

from gps import *
import paho.mqtt.client as mqtt #import the client1
import time
import random
import json
import os
import argparse
import logging
import coloredlogs
import threading

gpsd = None #seting the global variable
Active = True
styles = {'critical': {'bold': True, 'color': 'red'}, 'debug': {'color': 'green'}, 'error': {'color': 'red'}, 'info': {'color': 'white'}, 'notice': {'color': 'magenta'}, 'spam': {'color': 'green', 'faint': True}, 'success': {'bold': True, 'color': 'green'}, 'verbose': {'color': 'blue'}, 'warning': {'color': 'yellow'}}
level = logging.INFO
coloredlogs.install(level=level, fmt='%(asctime)s.%(msecs)03d \033[0;90m%(levelname)-8s '
''
'\033[0;36m%(filename)-18s%(lineno)3d\033[00m '
'%(message)s',
level_styles = styles)
logging.info("Initializing EGI")

#######################################################
## Initialize Variables ##
#######################################################
config = {}
config['Local'] = ["127.0.0.1", "skyscan/egi", "Local MQTT Bus"] # updated based on naming convention here: https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/
timeTrigger = time.mktime(time.gmtime()) + 10
timeHeartbeat = time.mktime(time.gmtime()) + 10
ID = str(random.randint(1,100001))


class GpsPoller(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
global gpsd #bring it in scope
gpsd = gps(mode=WATCH_ENABLE|WATCH_NEWSTYLE)
self.current_value = None
self.running = True #setting the thread running to true

def run(self):
global gpsd
while self.running:
gpsd.next() #this will continue to loop and grab EACH set of gpsd info to clear the buffer


LLA = [38.9510808,-77.3841834,130.1337]
RPY = [0,0,0]

parser = argparse.ArgumentParser(description='An MQTT based camera controller')
parser.add_argument('-m', '--mqtt-host', help="MQTT broker hostname", default='127.0.0.1')
parser.add_argument('-l', '--latitude', help="Latitude (decimal degrees)", default=LLA[0])
parser.add_argument('-L', '--longitude', help="Longitude (decimal degrees)", default=LLA[1])
parser.add_argument('-a', '--altitude', help="Altitude (meters)", default=LLA[2])
parser.add_argument('-r', '--roll', help="Roll Angle of Camera (degrees)", default=RPY[0])
parser.add_argument('-p', '--pitch', help="Pitch Angle of Camera (degrees)", default=RPY[1])
parser.add_argument('-y', '--yaw', help="Yaw Angle of Camera (degrees from True North)", default=RPY[2])
try:
args = parser.parse_args()
except:
logging.critical("Error in Command Line Argument Parsing. Are all environment variables set?", exc_info=True)
raise


state = {}
state['time'] = time.strftime("%Y-%m-%dT%H:%M:%SZ",time.gmtime())
state['lat'] = float(args.latitude)
state['long'] = float(args.longitude)
state['alt'] = float(args.altitude)
state['roll'] = float(args.roll)
state['pitch'] = float(args.pitch)
state['yaw'] = float(args.yaw)
state['fix'] = 0
logging.info("Initial State Array: " + str(state))


#######################################################
## Local MQTT Callback Function ##
#######################################################
def on_message_local(client, userdata, message):
payload = str(message.payload.decode("utf-8"))
logging.info('Message Received: ' + message.topic + ' | ' + payload)

def on_disconnect(client, userdata, rc):
global Active
Active = False

#############################################
## Initialize Local MQTT Bus ##
#############################################
Unit = 'Local'
broker_address=config[Unit][0]
broker_address=args.mqtt_host
local_topic= config[Unit][1]
logging.info("connecting to MQTT broker at "+broker_address+", channel '"+local_topic+"'")
clientLocal = mqtt.Client("EGI-"+ID) #create new instance
clientLocal.on_message = on_message_local #attach function to callback
clientLocal.on_disconnect = on_disconnect
try:
clientLocal.connect(broker_address) #connect to broker
except:
logging.critical("Could not connect to MQTT Broker.", exc_info=True)
raise
clientLocal.loop_start() #start the loop
clientLocal.publish("skyscan/registration","EGI-"+ID+" Registration")

gpsp = GpsPoller() # create the thread
try:
gpsp.start() # start it up
#############################################
## Main Loop ##
#############################################
while Active:
state['fix'] = gpsd.fix.status
if gpsd.fix.status:
state['time'] = gpsd.fix.time
state['lat'] = gpsd.fix.latitude
state['long'] = gpsd.fix.longitude
state['alt'] = gpsd.fix.altitude
if timeTrigger < time.mktime(time.gmtime()):
timeTrigger = time.mktime(time.gmtime()) + 10
clientLocal.publish(local_topic,json.dumps(state))
if timeHeartbeat < time.mktime(time.gmtime()):
timeHeartbeat = time.mktime(time.gmtime()) + 30
logging.info("Current EGI State: " + json.dumps(state))
time.sleep(0.01)
except (KeyboardInterrupt, SystemExit): #when you press ctrl+c
logging.info("Killing GPS Thread...")
gpsp.running = False
gpsp.join(2)
except:
logging.critical("Error starting GPS.", exc_info=True)
gpsp.running = False
gpsp.join(2)
raise
3 changes: 3 additions & 0 deletions egi/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
paho-mqtt==1.5.0
coloredlogs
gps
3 changes: 2 additions & 1 deletion env-example
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ CAMERA_MOVE_SPEED=50 # The speed at which the Axis will move for Pan/Tilt
CAMERA_DELAY=0.5 # How many seconds after issuing a Pan/Tilt command should a picture be taken
CAMERA_ZOOM=9999 # The zoom setting for the camera (0-9999)
CAMERA_LEAD=0.25 # How many seconds ahead of a plane's predicted location should the camera be positioned
RTL_DEV=1 # The device ID for the RTL-SDR - set using the rtl_eeprom program
RTL_DEV=1 # The device ID for the RTL-SDR - set using the rtl_eeprom program
GPS_SERIAL=/dev/ttyACM0 # GPS module serial port
9 changes: 8 additions & 1 deletion pan-tilt-pi/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import pantilthat
from picamera import PiCamera

ID = str(random.randint(1,100001))

camera = PiCamera()

tiltCorrect = 15
Expand Down Expand Up @@ -183,17 +185,22 @@ def main():
# Sleep for a bit so we're not hammering the HAT with updates
time.sleep(0.005)
print("connecting to MQTT broker at "+ args.mqtt_host+", channel '"+args.mqtt_topic+"'")
client = mqtt.Client("pan-tilt-pi-camera") #create new instance
client = mqtt.Client("pan-tilt-pi-camera-" + ID) #create new instance

client.on_message=on_message #attach function to callback

client.connect(args.mqtt_host) #connect to broker
client.loop_start() #start the loop
client.subscribe(args.mqtt_topic+"/#")
client.publish("skyscan/registration", "pan-tilt-pi-camera-"+ID+" Registration", 0, False)
#############################################
## Main Loop ##
#############################################
timeHeartbeat = 0
while True:
if timeHeartbeat < time.mktime(time.gmtime()):
timeHeartbeat = time.mktime(time.gmtime()) + 10
client.publish("Heartbeat", "pan-tilt-pi-camera-"+ID+" Heartbeat", 0, False)
time.sleep(0.1)


Expand Down
Loading

0 comments on commit 4e520a4

Please sign in to comment.