Skip to content

Commit

Permalink
add threading async reader. Not recommended for use probably...
Browse files Browse the repository at this point in the history
  • Loading branch information
nznobody committed Sep 2, 2021
1 parent 24a040b commit 5dd6da3
Showing 1 changed file with 48 additions and 3 deletions.
51 changes: 48 additions & 3 deletions src/lib/terkin/driver/vedirect_sensor.py
Expand Up @@ -2,6 +2,8 @@
# (c) 2020 Jan Hoffmann <jan.hoffmann@bergamsee.de>
# (c) 2020 Andreas Motl <andreas.motl@terkin.org>
# License: GNU General Public License, Version 3
import time
import _thread
from terkin import logging
from terkin.sensor import SensorManager, AbstractSensor
from terkin.util import get_platform_info
Expand Down Expand Up @@ -55,6 +57,31 @@ def __init__(self, settings=None):
self.device = settings["device"]
self.timeout = 5
self.driver = None
self.threading = bool(settings["async"])
self._raw_data= None
self._read_time = 0
self._shutdown = False

def __del__(self):
self.shutdown()

def shutdown(self):
self._shutdown = True

def _async_read(self):
"""Read until shutdown"""
log.info("Starting async VEDirect thread")
while not self._shutdown:
try:
data = self.driver.read_data_single(timeout=5000)
if not data:
continue
log.info("Received ASYNC data, storing it")
self._raw_data = data
self._read_time = time.time()
except KeyboardInterrupt:
break
log.info("Shutting down async VEDirect thread")

def start(self):
log.info('Initializing sensor "Victron Energy VE.Direct"')
Expand Down Expand Up @@ -92,6 +119,11 @@ def start(self):
"VEDirect driver not implemented on this platform"
)

if self.threading:
# Todo: probably need to use a queue to pass data between threads?
_thread.start_new_thread(self._async_read, ())
time.sleep(1) # Allow thread to start up
self.timeout = 60 # Since this is async, we can accept a longer timeout
return True

except Exception as ex:
Expand All @@ -103,11 +135,24 @@ def read(self):
return
log.info('Reading sensor "Victron Energy VE.Direct"')

data_raw = self.driver.read_data_single()

if self.threading:
data_raw = self._raw_data
if data_raw:
if time.time() - self._read_time > self.timeout:
raise TimeoutError("VEDirect Asynchronous reading stale data, not sending")
self._raw_data = None
else:
data_raw = self.driver.read_data_single()
if not data_raw:
raise ValueError("No data received from VEDirect")
data = {}
product_id = ""
if "PID" in data_raw:
product_id = str(data_raw["PID"])
else:
product_id = "unkown-pid"
for key, value in data_raw.items():
key = "vedirect:{}".format(key)
key = "vedirect-{}:{}".format(product_id, key)
data[key] = value

return data

0 comments on commit 5dd6da3

Please sign in to comment.