Package: sdg-dev
Cодержит классыSdgDevMasterиSdgDevAsyncдля обмена командами, через
СКБ-шный интерфейс ввода/вывода.https://pypi.org/project/sdg-io/SdgDevMasterумеет только передавать команды, т.е. выполняет работуГлавного устройства.SdgDevAsyncпредназначен как для передачи так и для приема команд, т.е позволяет
организовать работу какГлавноготак иПодчиненного устройства.
Для работы SdgDevAsync создается поток, в котором выполняется переодическое
чтение данных из интерфейса ввода/вывода и их обработка на предмет получения команд.
Входящие команды должны быть заранее добавлены методомadd_incmd()с указанием кода команды,
форматом ожидаемых данных и callback функции, которой будет передано управление при
поступлении команды с нужным кодом и форматом данных.Вниманиеcallback функция вызывается из внутреннего потока SdgDevAsync и не должна его
блокировать! Для безопасного обмена данными должны быть приняты меры!SdgDevMasterиSdgDevAsyncмогут автоматически определять порт к которому подключено
подчиненное устройство. Для этого нужно:Переопределить функциюcheck_id(), которая будет запрашиватьуникальный идентификаторуподчиненногои при получении адекватного ответа, возвращать True.Использовать ф-юsearch_port()для поискаподчиненногопо всем доступным портам системы,
или search_port(portlist) для поиска по заранее подготовленному списоку портов.При необходимости подключить какой-то другой интерфейс ввода/вывода нужно
использовать классыDevMasterиDevAsync.
Интерфейс ввода/вывода должен иметь методыread/writeи вызывать
исключениеIOErrorпри ошибках чтения/записи.Формат обмена:АА СС D0 D1 .. DX- командаAA CA D0 D1 .. DX- ответАА: адрес устройства. Возможна работа без адреса (точка -точка).СС: код команды, любой в диапазоне 0x00 - 0x7F, кроме 0x70CA: код ответа = код команды с установленным старшим битом 0x80 - 0xFF, кроме 0xF0D0-DX: данные команды/ответа опционально.
На широковещательные команды с адресомАА=0х00ответ подчиненным(и) не выдается.
Возможен ответ подчиненного с кодом0xF0Недопустимая командаэто означает,
что он не смог выполнить данныую команду. Формат такого ответа:AA 0xF0 CC EE, гдеEE- код ошибки выполнения. (см. class DevBadCode)Пример использования (example.py):fromstructimportpackfromsdg_utilsimportlog_openfromsdg_devimportSdgDevMaster,DevException,SdgDevAsynclog=log_open()classMyMaster(SdgDevMaster):def__init__(self):super().__init__(port='',log=log.getChild('mastr'))defcheck_id(self):returnself.send(b'\x00',ackfrmt='H')==0xAAAAdefsend_val(self,val):returnself.send(b'\x31'+pack('I',val),ackfrmt='')defrequest_val(self):returnself.send(b'\x32',ackfrmt='I',timeout=.1,remix=0)classMySlave(SdgDevAsync):def__init__(self,port):super().__init__(port,log=log.getChild('slave'))self.val=0x04030201self.ID=0xAAAAself.add_incmd(b'\x00','',self._getid)self.add_incmd(b'\x31','I',self._setval)self.add_incmd(b'\x32','',self._getval)self.add_incmd(b'\x33','',lambda:pack('BBBB',5,6,7,8))def_setval(self,val):self.val=valreturnb''def_getval(self):returnpack('I',self.val)def_getid(self):returnpack('H',self.ID)if__name__=="__main__":print('Порт для master-a будет определен автопоиском по всем доступным портам системы.')PORT=input("Ведите название порта для slave-a или нажмите Enter(по умочанию 'COM26'):")ifnotPORT:PORT='COM26'slave=MySlave(PORT)master=MyMaster()master.search_port()try:val=master.request_val()log.info(f"request_val 0x{val:08x}")log.info(f"send new val 0x01020304")master.send_val(0x01020304)val=master.request_val()log.info(f"request_val 0x{val:08x}")a,b,c,d=master.send(b'\x33',ackfrmt='BBBB')log.info(f"{a},{b},{c},{d}")exceptDevExceptionase:log.error(e)master.close()slave.close()