Sensor route initial working version, less ugly code
This commit is contained in:
parent
60b9b26d28
commit
5d1aba5e55
1 changed files with 65 additions and 53 deletions
|
@ -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()
|
||||||
|
|
Reference in a new issue