You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.0 KiB
91 lines
3.0 KiB
7 years ago
|
from gex import Client, TF_Msg
|
||
7 years ago
|
from gex.Client import EventReport
|
||
7 years ago
|
|
||
7 years ago
|
|
||
|
class Unit:
|
||
7 years ago
|
def __init__(self, client:Client, name:str):
|
||
7 years ago
|
self.client = client
|
||
|
self.unit_name = name
|
||
7 years ago
|
self.unit_type = self._type()
|
||
|
self.callsign = client.get_callsign(name, self.unit_type)
|
||
|
|
||
7 years ago
|
# need intermediate function because the method also takes 'self'
|
||
|
def evt_hdl(evt:EventReport):
|
||
|
self._on_event(evt)
|
||
7 years ago
|
|
||
|
self.client.bind_report_listener(self.callsign, evt_hdl)
|
||
7 years ago
|
self._init()
|
||
|
|
||
|
def _init(self):
|
||
|
""" Do post-constructor init """
|
||
|
pass
|
||
7 years ago
|
|
||
7 years ago
|
def _type(self) -> str:
|
||
7 years ago
|
raise NotImplementedError("Missing _type() in Unit class \"%s\"" % self.__class__.__name__)
|
||
7 years ago
|
|
||
7 years ago
|
def _send(self, cmd:int, pld=None, id:int=None, confirm:bool=False):
|
||
|
"""
|
||
|
Send a command to the unit.
|
||
|
If 'confirm' is True, will ask for confirmation and throw an error if not received
|
||
7 years ago
|
|
||
|
Returns frame ID
|
||
7 years ago
|
"""
|
||
|
if confirm:
|
||
7 years ago
|
msg = self._query(cmd|0x80, pld, id)
|
||
|
return msg.id
|
||
7 years ago
|
else:
|
||
7 years ago
|
return self.client.send(cs=self.callsign, cmd=cmd, pld=pld, id=id)
|
||
7 years ago
|
|
||
7 years ago
|
def _query(self, cmd:int, pld=None, id:int=None, timeout=3) -> TF_Msg:
|
||
7 years ago
|
""" Query the unit. Returns TF_Msg """
|
||
7 years ago
|
return self.client.query(cs=self.callsign, cmd=cmd, pld=pld, id=id, timeout=timeout)
|
||
7 years ago
|
|
||
7 years ago
|
def _query_async(self, cmd:int, callback, pld=None, id:int=None):
|
||
|
"""
|
||
|
Query the unit without waiting for response.
|
||
|
The callback is fired for each frame; returns TF.CLOSE or TF.STAY
|
||
|
|
||
|
Returns frame ID
|
||
|
"""
|
||
|
return self.client.query_async(cs=self.callsign, cmd=cmd, pld=pld, id=id, callback=callback)
|
||
|
|
||
7 years ago
|
def _bulk_read(self, cmd:int, pld=None, id:int=None, chunk:int=1024) -> bytearray:
|
||
7 years ago
|
"""
|
||
|
Perform a bulk read.
|
||
|
cmd, id and pld are used to initiate the read.
|
||
|
"""
|
||
7 years ago
|
return self.client.bulk_read(cs=self.callsign, cmd=cmd, id=id, pld=pld, chunk=chunk)
|
||
7 years ago
|
|
||
7 years ago
|
def _bulk_write(self, cmd:int, bulk, id:int=None, pld=None):
|
||
7 years ago
|
"""
|
||
|
Perform a bulk write.
|
||
|
cmd, id and pld are used to initiate the read.
|
||
|
bulk is the data to write.
|
||
|
"""
|
||
|
self.client.bulk_write(cs=self.callsign, cmd=cmd, id=id, pld=pld, bulk=bulk)
|
||
7 years ago
|
|
||
7 years ago
|
def _on_event(self, evt:EventReport):
|
||
7 years ago
|
""" Stub for an event handler """
|
||
7 years ago
|
raise NotImplementedError("Missing _on_event() in Unit class \"%s\"" % self.__class__.__name__)
|
||
7 years ago
|
|
||
|
# --- utils ---
|
||
|
|
||
|
def pins2int(self, list_or_int):
|
||
|
if type(list_or_int) != int:
|
||
|
p = 0
|
||
|
for pin in list_or_int:
|
||
|
p |= 1 << pin
|
||
|
return p
|
||
|
else:
|
||
|
return list_or_int
|
||
|
|
||
|
def pins2list(self, list_or_int):
|
||
|
if type(list_or_int) == int:
|
||
|
L = []
|
||
|
for i in range(0,32): # this is up to 32 in order to allow using it also for adc channels
|
||
|
if list_or_int & (1 << i) != 0:
|
||
|
L.append(i)
|
||
|
return L
|
||
|
else:
|
||
|
return list_or_int
|