6 from .utils import Singleton
9 logger = logging.getLogger(__name__)
10 formatter = logging.Formatter('%(asctime)s - %(filename)s:%(lineno)s - %(levelname)s - %(message)s')
14 def __init__(self, ch, cmd, mode, id0, id1, id2, id3):
23 def __eq__(self, other):
25 self.mode == other.mode,
27 self.id0 == other.id0,
28 self.id1 == other.id1,
29 self.id2 == other.id2,
42 class NooLiteResponse(NooLiteMessage):
43 def __init__(self, st, mode, ctr, togl, ch, cmd, fmt, d0, d1, d2, d3, id0, id1, id2, id3, crc, sp):
44 super().__init__(ch, cmd, mode, id0, id1, id2, id3)
55 self.time = time.time()
58 return '{}'.format(self.to_list())
61 return '{}'.format(self.to_list())
89 class NooLiteCommand(NooLiteMessage):
90 def __init__(self, ch, cmd, mode=0, ctr=0, res=0, fmt=0, d0=0, d1=0, d2=0, d3=0, id0=0, id1=0, id2=0, id3=0):
91 super().__init__(ch, cmd, mode, id0, id1, id2, id3)
103 return '{}'.format(self.to_list())
106 return '{}'.format(self.to_list())
127 return crc if crc < 256 else divmod(crc, 256)[1]
171 def description(self):
173 'ST': {'value': self.st, 'description': 'Стартовый байт'},
174 'MODE': {'value': self.mode, 'description': 'Режим работы адаптера'},
175 'CTR': {'value': self.ctr, 'description': 'Управление адаптером'},
176 'RES': {'value': self.res, 'description': 'Зарезервирован, не используется'},
177 'CH': {'value': self.ch, 'description': 'Адрес канала, ячейки привязки'},
178 'CMD': {'value': self.cmd, 'description': 'Команда'},
179 'FMT': {'value': self.fmt, 'description': 'Формат'},
180 'DATA': {'value': [self.d0, self.d1, self.d2, self.d3], 'description': 'Данные'},
181 'ID': {'value': [self.id0, self.id1, self.id2, self.id3], 'description': 'Адрес блока'},
182 'CRC': {'value': self.crc, 'description': 'Контрольная сумма'},
183 'SP': {'value': self.sp, 'description': 'Стоповый байт'}
187 class NooliteSerial(metaclass=Singleton):
188 def __init__(self, loop, tty_name, input_command_callback_method):
189 self.tty = self._get_tty(tty_name)
191 self.input_command_callback_method = input_command_callback_method
194 # Если приходят данные на адаптер, то они обрабатываются в этом методе
195 self.loop.add_reader(self.tty.fd, self.inf_reading)
197 def inf_reading(self):
198 while self.tty.in_waiting >= 17:
199 in_bytes = self.tty.read(17)
200 resp = NooLiteResponse(*list(in_bytes))
201 logger.debug('Incoming command: {}'.format(resp))
202 self.loop.create_task(self.input_command_callback_method(resp))
204 async def send_command(self, ch, cmd, mode=0, ctr=0, res=0, fmt=0, d0=0, d1=0, d2=0, d3=0, id0=0, id1=0, id2=0, id3=0):
205 command = NooLiteCommand(ch, cmd, mode, ctr, res, fmt, d0, d1, d2, d3, id0, id1, id2, id3)
208 logger.info('> {}'.format(command))
210 self.tty.write(command.to_bytes())
211 logger.info('Time to write: {}'.format(time.time() - before))
214 def _get_tty(tty_name):
215 serial_port = serial.Serial(tty_name, timeout=2)
216 if not serial_port.is_open:
218 serial_port.flushInput()
219 serial_port.flushOutput()