Files
controller-wisetopdataserver/python/biopro/message/message.py
T
2021-12-20 14:52:55 +08:00

201 lines
5.0 KiB
Python

import struct
from typing import Optional, Union, List
class DataMessage:
"""It is typing used of the abstract interface of ReSampleEntry which is defined in c extension.
**Response Message Format**
::
| | 1 | 2 | 3 |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
-----------------------------------------------------------------
| header | data ........................................ |
header
message header
===== ==================
value description
===== ==================
0 system message
1 parameter error
2 general message
3 data message
===== ==================
1. system message (header=0)
::
| | 1 | 2 | 3 |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
-----------------------------------------------------------------
| header=0xFF | length | message ..................... |
#. data message
see :class:`DataMessageEncoderType` for more detail
**Command format**
1. command
1. greeting
echo greeting
response: ``greeting``
#. sync, sync:DEVICE, sync:DEVICE,...
return current Data server is sync or not.
response: ``start:DEVICE``, ``stop:DEVICE`` for each connected device
#. broadcast:MESSAGE
broadcast MESSAGE, send to controller
#. start, stop
start/stop routine data streaming.
2. response
1. scan, scan:update, scan:done
controller scanned, found device updated
#. connected, connected:DEVICE
device connected
#. disconnected, disconnected:DEVICE
device disconnected
#. start:DEVICE,..., stop:DEVICE,...
#. low_power:STATE (ups power using)
#. message::MESSAGE, message:DEVICE:MESSAGE
data notify message
#. broadcast:MESSAGE
broadcast MESSAGE, receive from controller
#. info:MESSAGE, warn:MESSAGE, error:MESSAGE
message for command response
"""
HEADER_SYSTEM = 0xFF
__slots__ = ()
GREETING = 'greeting'
SYNC = 'sync'
BROADCAST = 'broadcast'
START_DATA_STREAM = 'start'
STOP_DATA_STREAM = 'stop'
SCAN = 'scan'
SCAN_STATE = ('', 'update', 'done')
LOW_POWER = 'low_power'
LOW_POWER_STATE = ('UPS', 'EXT', 'OFF')
@classmethod
def response(cls, message: str) -> bytes:
message = message.encode()
return struct.pack('<2B%ds' % len(message), cls.HEADER_SYSTEM, len(message), message)
@classmethod
def greeting(cls) -> str:
return cls.GREETING
@classmethod
def scan(cls, state: Optional[str] = None) -> str:
if state is None:
return cls.SCAN + ':done'
elif state == '':
return cls.SCAN
elif state in cls.SCAN_STATE:
return cls.SCAN + ':' + state
else:
raise ValueError()
@classmethod
def sync(cls, sync: bool) -> str:
return 'start' if sync else 'stop'
@classmethod
def low_power(cls, ups_state: str):
if ups_state in cls.LOW_POWER_STATE:
return cls.LOW_POWER + ':' + ups_state
else:
raise ValueError()
@classmethod
def start(cls, device: Union[None, int, List[int]] = None) -> str:
if device is None:
return 'start'
elif isinstance(device, int):
return 'start:' + str(device)
else:
return 'start:' + ','.join(map(str, device))
@classmethod
def stop(cls, device: Union[None, int, List[int]] = None) -> str:
if device is None:
return 'stop'
elif isinstance(device, int):
return 'stop:' + str(device)
else:
return 'stop:' + ','.join(map(str, device))
@classmethod
def message(cls, message: str, device: Optional[int] = None) -> str:
if device is None:
return 'message::' + message
else:
return 'message:' + str(device) + ':' + message
@classmethod
def broadcast(cls, message: str) -> str:
return 'broadcast:' + message
@classmethod
def connected(cls, device: Optional[int] = None) -> str:
if device is None:
return 'connected'
else:
return 'connected:' + str(device)
@classmethod
def disconnected(cls, device: Optional[int] = None) -> str:
if device is None:
return 'disconnected'
else:
return 'disconnected:' + str(device)
@classmethod
def info(cls, message: str) -> str:
return 'info:' + message
@classmethod
def warn(cls, message: str) -> str:
return 'warn:' + message
@classmethod
def error(cls, message: str) -> str:
return 'error:' + message