major improvements and rework
- add stream / instrument availability data - events contain event kind for dispatching db methods
This commit is contained in:
42
secop.py
42
secop.py
@ -16,6 +16,14 @@ class EnumConvert(dict):
|
||||
return float(self[value])
|
||||
|
||||
|
||||
class TagsDict(dict):
|
||||
def __init__(self, default_value):
|
||||
self.default_value = default_value
|
||||
|
||||
def __missing__(self, key):
|
||||
return self.default_value
|
||||
|
||||
|
||||
class SecopStream(Stream):
|
||||
ping_time = 0
|
||||
|
||||
@ -47,12 +55,12 @@ class SecopStream(Stream):
|
||||
self.tags['device'] = self.device
|
||||
self.modules = self.descr['modules']
|
||||
self.convert = {}
|
||||
self.original_id = {}
|
||||
self.tags_dict = TagsDict(self.tags)
|
||||
for mod, moddesc in self.modules.items():
|
||||
for key in ('_original_id', 'original_id'):
|
||||
value = moddesc.get(key)
|
||||
if value:
|
||||
self.original_id[mod] = value
|
||||
self.tags_dict[mod] = dict(self.tags, device=value)
|
||||
break
|
||||
for param, desc in moddesc['accessibles'].items():
|
||||
dt = desc['datainfo']
|
||||
@ -64,11 +72,10 @@ class SecopStream(Stream):
|
||||
self.send('ping')
|
||||
|
||||
def get_tags(self, key):
|
||||
return dict(self.tags, device=self.original_id.get(key[0], self.device))
|
||||
return self.tags_dict[key[0]]
|
||||
|
||||
def event_generator(self):
|
||||
try:
|
||||
cnt = 0
|
||||
for msg in self.get_lines():
|
||||
match = UPDATE.match(msg)
|
||||
if match:
|
||||
@ -78,23 +85,23 @@ class SecopStream(Stream):
|
||||
cvt = self.convert.get(key)
|
||||
if cvt:
|
||||
data = json.loads(data)
|
||||
tags = self.tags_dict[key[0]]
|
||||
if cmd == 'error_update':
|
||||
error = ': '.join(data[0:2])
|
||||
print(msg, repr(error))
|
||||
ts = data[2].get('t', time.time())
|
||||
value = None
|
||||
timestamp = data[2].get('t', time.time())
|
||||
yield 'error', error, key, tags, timestamp
|
||||
else:
|
||||
error = None
|
||||
ts = data[1].get('t', time.time())
|
||||
value = cvt(data[0])
|
||||
cnt += 1
|
||||
yield key, value, error, ts, self.get_tags(key)
|
||||
timestamp = data[1].get('t', time.time())
|
||||
yield 'value', value, key, tags, timestamp
|
||||
elif msg == 'active':
|
||||
# from now on, no more waiting
|
||||
self.notimeout()
|
||||
|
||||
except Exception as e:
|
||||
print(self.uri, repr(e))
|
||||
raise
|
||||
|
||||
|
||||
SECOP_UDP_PORT = 10767
|
||||
@ -115,6 +122,8 @@ class UdpStream(Base):
|
||||
continue
|
||||
if kind == 'for_other_node':
|
||||
uri = msg.pop('uri')
|
||||
if 'device' not in msg:
|
||||
msg['device'] = uri.split('://', 1)[-1].split(':')[0]
|
||||
kwargs = msg
|
||||
elif kind == 'node':
|
||||
uri = f"{addr[0]}:{msg['port']}"
|
||||
@ -152,14 +161,17 @@ class ScanStream(UdpStream):
|
||||
self.select_dict[sock.fileno()] = self
|
||||
|
||||
|
||||
def send_fake_udp(uri, device='fake'):
|
||||
def send_fake_udp(uri, device=None, instrument=None):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||
msg = json.dumps({
|
||||
msg = {
|
||||
'SECoP': 'for_other_node',
|
||||
'uri': uri,
|
||||
'device': device,
|
||||
}, ensure_ascii=False, separators=(',', ':')).encode('utf-8')
|
||||
sock.sendto(msg, ('255.255.255.255', SECOP_UDP_PORT))
|
||||
}
|
||||
if device:
|
||||
msg['device'] = device
|
||||
msg['instrument'] = instrument or '0'
|
||||
sock.sendto(json.dumps(msg, ensure_ascii=False, separators=(',', ':')).encode('utf-8'),
|
||||
('255.255.255.255', SECOP_UDP_PORT))
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user