Sensor route initial working version, less ugly code

This commit is contained in:
Philip Trauner 2016-12-07 19:14:02 +01:00
parent 60b9b26d28
commit 5d1aba5e55

View file

@ -1,7 +1,7 @@
from Highway import Route, Pipe, Client from Highway import Route, Pipe, Client
import Logging import Logging
import Config import Config
from Utils import is_wallaby, set_hostname, get_hostname import Utils
import socket import socket
@ -9,10 +9,11 @@ import time
import os import os
import sys import sys
import subprocess import subprocess
import _thread from random import randint
from _thread import start_new_thread
CHANNEL = 2 CHANNEL = 2
IS_WALLABY = is_wallaby() IS_WALLABY = Utils.is_wallaby()
PATH = "/home/root/Documents/KISS/bin/" if IS_WALLABY else (sys.argv[1] if len(sys.argv) > 1 else None) PATH = "/home/root/Documents/KISS/bin/" if IS_WALLABY else (sys.argv[1] if len(sys.argv) > 1 else None)
LIB_WALLABY = "/usr/lib/libwallaby.so" LIB_WALLABY = "/usr/lib/libwallaby.so"
@ -28,12 +29,18 @@ if not IS_WALLABY:
class SensorReadout: class SensorReadout:
ANALOG = 1 ANALOG = 1
DIGITAL = 2 DIGITAL = 2
NAMED_MODES = {ANALOG : "analog", DIGITAL : "digital"}
MODES = tuple(NAMED_MODES.keys())
def __init__(self, handler, poll_rate=0.2): def __init__(self, handler, poll_rate=0.2):
self.poll_rate = poll_rate self.poll_rate = poll_rate
self.handler = handler self.handler = handler
self.peers = {} self.peers = {}
self.readout_required = {SensorReadout.ANALOG : [],
SensorReadout.DIGITAL : []}
self.generate_random_values = False self.generate_random_values = False
# Running on actual hardware?
if Utils.is_wallaby(): if Utils.is_wallaby():
if not os.path.exists(LIB_WALLABY): if not os.path.exists(LIB_WALLABY):
Logging.error("The Wallaby library should normally exist on " Logging.error("The Wallaby library should normally exist on "
@ -43,6 +50,7 @@ class SensorReadout:
Logging.warning("Sensor data can not be read on a dev-system. " Logging.warning("Sensor data can not be read on a dev-system. "
"Generating random values instead.") "Generating random values instead.")
self.generate_random_values = True self.generate_random_values = True
# Generate random values?
if not self.generate_random_values: if not self.generate_random_values:
self.wallaby_library = cdll.LoadLibrary(LIB_WALLABY) self.wallaby_library = cdll.LoadLibrary(LIB_WALLABY)
self.get_sensor_value = self.__get_sensor_value self.get_sensor_value = self.__get_sensor_value
@ -51,17 +59,26 @@ class SensorReadout:
start_new_thread(self._sensor_fetcher, ()) start_new_thread(self._sensor_fetcher, ())
def subscribe(self, port, peer, mode): def subscribe(self, port, mode, peer):
if port not in self.readout_required[mode]:
self.readout_required[mode].append(port)
if not peer in self.peers: if not peer in self.peers:
self.peers[peer] = {SensorReadout.ANALOG : [], SensorReadout.DIGITAL : []} self.peers[peer] = {SensorReadout.ANALOG : [],
else: SensorReadout.DIGITAL : []}
self.peers[peer][mode].append(port) self.peers[peer][mode].append(port)
def unsubscribe(self, port, peer, mode): def unsubscribe(self, port, mode, peer):
if peer in self.peers: if peer in self.peers:
if port in self.peers[peer][mode]: if port in self.peers[peer][mode]:
del self.peers[peer][mode][self.peers[peer][mode].index(port)] del self.peers[peer][mode][self.peers[peer][mode].index(port)]
readout_still_required = False
for peer in self.peers:
if port in self.peers[peer][mode]:
readout_required = True
break
if not readout_required:
del self.readout_required[mode][self.readout_required[mode].index(port)]
def __get_sensor_value(self, port, mode): def __get_sensor_value(self, port, mode):
@ -74,33 +91,34 @@ class SensorReadout:
def __get_random_value(self, port, mode): def __get_random_value(self, port, mode):
if mode == SensorReadout.ANALOG: if mode == SensorReadout.ANALOG:
return randint(0, 4095) return randint(0, 4095)
elif mode == DIGITAL: elif mode == SensorReadout.DIGITAL:
return randint(0, 1) return randint(0, 1)
def _sensor_fetcher(self, handler): def _sensor_fetcher(self):
while True: while True:
current_values = {"analog" : {}, "digital" : {}} current_values = {SensorReadout.ANALOG : {},
SensorReadout.DIGITAL : {}}
for mode in SensorReadout.MODES:
for port in self.readout_required[mode]:
current_values[mode][port] = self.get_sensor_value(port, mode)
for peer in self.peers: for peer in self.peers:
response = {"analog" : {}, "digital" : {}} response = {"analog" : {}, "digital" : {}}
for port in self.peers[peer][SensorReadout.ANALOG]: for mode in SensorReadout.NAMED_MODES:
if not port in current_values["analog"]: for port in self.peers[peer][mode]:
sensor_value = get_sensor_value(port, ANALOG) response[SensorReadout.NAMED_MODES[mode]][port] = current_values[mode][port]
response["analog"][port] = sensor_value
current_values["analog"][port] = sensor_value
else:
response["analog"][port] = current_values["analog"][port]
for port in self.peers[peer][SensorReadout.DIGITAL]:
if not port in current_values["digital"]:
sensor_value = get_sensor_value(port, DIGITAL)
response["digital"][port] = sensor_value
current_values["digital"][port] = sensor_value
else:
response["digital"][port] = current_values["digital"][port]
self.handler.pipe(response, "sensor", peer) self.handler.pipe(response, "sensor", peer)
time.sleep(self.poll_rate) time.sleep(self.poll_rate)
@staticmethod
def valid_port(port, mode):
if mode == SensorReadout.ANALOG:
return port >= 0 and port <= 5
elif mode == SensorReadout.DIGITAL:
return port >= 0 and port <= 9
return False
class Sensor(Pipe): class Sensor(Pipe):
@ -110,32 +128,26 @@ class Sensor(Pipe):
""" """
def run(self, data, peer, handler): def run(self, data, peer, handler):
if type(data) is dict: if type(data) is dict:
if "subscribe" in data: for event in ("subscribe", "unsubscribe"):
if "analog" in data["subscribe"]: if event in data:
for port in data["subscribe"]["analog"]: for mode in ("analog", "digital"):
if type(port) is int: if mode in data[event]:
if port >= 0 and port <= 10: for port in data[event][mode]:
sensor_readout.subscribe(port, handler, if type(port) is int:
SensorReadout.ANALOG) if mode == "analog":
if "digital" in data["subscribe"]: mode = SensorReadout.ANALOG
for port in data["subscribe"]["digital"]: elif mode == "digital":
if type(port) is int: mode = SensorReadout.DIGITAL
if port >= 0 and port <= 10: if SensorReadout.valid_port(port, mode):
sensor_readout.subscribe(port, handler, if event == "subscribe":
SensorReadout.DIGITAL) self.sensor_readout.subscribe(port, mode, peer)
if "unsubscribe" in data: elif event == "unsubscribe":
if "analog" in data["unsubscribe"]: self.sensor_readout.unsubscribe(port, mode, peer)
for port in data["unsubscribe"]["analog"]:
if type(port) is int: def start(self, handler):
if port >= 0 and port <= 10: self.sensor_readout = SensorReadout(handler)
sensor_readout.unsubscribe(port, handler,
SensorReadout.ANALOG)
if "digital" in data["unsubscribe"]:
for port in data["unsubscribe"]["digital"]:
if type(port) is int:
if port >= 0 and port <= 10:
sensor_readout.unsubscribe(port, handler,
SensorReadout.DIGITAL)
class WallabyControl(Route): class WallabyControl(Route):
def __init__(self, output_unbuffer): def __init__(self, output_unbuffer):
@ -194,7 +206,7 @@ class WallabyControl(Route):
class Subscribe(Route): class Subscribe(Route):
def start(self, handler): def start(self, handler):
handler.send({"name" : get_hostname(), "channel" : CHANNEL}, "subscribe") handler.send({"name" : Utils.get_hostname(), "channel" : CHANNEL}, "subscribe")
class Hostname(Pipe): class Hostname(Pipe):
@ -236,7 +248,7 @@ try:
ws = Handler(config.server_address) ws = Handler(config.server_address)
# setup has to be called before the connection is established # setup has to be called before the connection is established
ws.setup({"subscribe" : Subscribe(), "hostname" : Hostname(), ws.setup({"subscribe" : Subscribe(), "hostname" : Hostname(),
"processes" : Processes()}, "processes" : Processes(), "sensor" : Sensor()},
debug=config.debug) debug=config.debug)
ws.connect() ws.connect()
ws.run_forever() ws.run_forever()