def run(self): """Will be executed when the thread is started.""" @self.conn.notification(pyads.PLCTYPE_BOOL) def callback(handle: int, name: str, timestamp: str, value: bool): """ Called everytime when the PLC variable changes its state. :param int handle: An unique ID that the PLC associates to an address. :param str name: The name of the PLC variable, "MAIN.myVariable". :param datetime timestamp: YYYY-mm-dd HH:MM:SS.ssssss. :param bool value: The value of the PLC variable. """ data = {"name": name, "value": value} self.signal.emit(data) attr = pyads.NotificationAttrib(1) try: self.conn.add_device_notification(config.Outputs.QH0.value, attr, callback) self.conn.add_device_notification(config.Outputs.QM1LOWER.value, attr, callback) self.conn.add_device_notification(config.Outputs.QM1RAISE.value, attr, callback) self.conn.add_device_notification(config.Outputs.QM2LOWER.value, attr, callback) self.conn.add_device_notification(config.Outputs.QM2RAISE.value, attr, callback) except pyads.pyads_ex.ADSError as err: # e.g. wrong variable name print(err) self.signal.emit({"name": "error", "value": err})
def start(self): logger.info('Starting Bridge...') self.plc.open() logger.debug('Connecting to LCR device...') # Set up measuring instrument self.lcr.clear_instrument() self.lcr.set_format(True) # Set format to 'binary' self.worker.start() with self.plc: logger.debug('Entering plc context...') attr = pyads.NotificationAttrib(sizeof(pyads.PLCTYPE_BOOL)) self.plc.add_device_notification(self.config['PLC_MEASURE_FLAG'], attr, self.callback) logger.info('Callback registered with pyADS...') while True: sleep(10) try: self.plc.read_state() except pyads.ADSError: self.queue.put(False) self.worker.join() break self.worker.join() logger.info('Bridge terminated')
def test_methods_with_closed_port(self): # type: () -> None """Test pyads.Connection methods with no open port.""" with self.plc: adr = self.plc.get_local_address() self.assertIsNotNone(adr) plc = pyads.Connection("127.0.0.1.1.1", 851) self.assertIsNone(plc.get_local_address()) self.assertIsNone(plc.read_state()) self.assertIsNone(plc.read_device_info()) self.assertIsNone(plc.read_write(1, 2, pyads.PLCTYPE_INT, 1, pyads.PLCTYPE_INT)) self.assertIsNone(plc.read(1, 2, pyads.PLCTYPE_INT)) self.assertIsNone(plc.read_by_name("hello", pyads.PLCTYPE_INT)) self.assertIsNone(plc.get_handle("hello")) self.assertIsNone( plc.read_structure_by_name( "hello", (("", pyads.PLCTYPE_BOOL, 1), ("", pyads.PLCTYPE_BOOL, 1)) ) ) self.assertIsNone( plc.add_device_notification( "test", pyads.NotificationAttrib(4), lambda x: x ) )
def run(self): """ Executed automatically when the thread starts. """ # Create and open a connection. plc = pyads.Connection(AMS_NET_ID, AMS_NET_PORT) plc.open() @plc.notification(pyads.PLCTYPE_BOOL) def callback(handle, name, timestamp, value): """ Executed when the variable changes its state. """ data = {'name': name, 'value': value} self.notification_signal.emit(data) # send data # Create device notifications. attr = pyads.NotificationAttrib(1) plc.add_device_notification('MAIN.qCyl1toMinus', attr, callback) plc.add_device_notification('MAIN.qCyl1toPlus', attr, callback) plc.add_device_notification('MAIN.qCyl2toMinus', attr, callback) plc.add_device_notification('MAIN.qCyl2toPlus', attr, callback) plc.add_device_notification('MAIN.qCyl3toMinus', attr, callback) plc.add_device_notification('MAIN.qCyl3toPlus', attr, callback) plc.add_device_notification('MAIN.qCyl4toMinus', attr, callback) plc.add_device_notification('MAIN.qCyl4toPlus', attr, callback) plc.add_device_notification('MAIN.qMot1start', attr, callback) plc.add_device_notification('MAIN.qMot2start', attr, callback) plc.add_device_notification('MAIN.qMot3start', attr, callback) plc.add_device_notification('MAIN.qMot4start', attr, callback)
def init(): if self.poll_rate is None: self._update_data_type() attr = pyads.NotificationAttrib(ctypes.sizeof(self.data_type)) self.notification_handle = self.ads.add_device_notification( self.symbol, attr, self._notification_update) else: self._poll()
def test_decorated_device_notification(self): plc = pyads.Connection(TEST_SERVER_AMS_NET_ID, TEST_SERVER_AMS_PORT) @plc.notification(pyads.PLCTYPE_INT) def callback(handle, name, timestamp, value): print (handle, name, timestamp, value) with plc: plc.add_device_notification("a", pyads.NotificationAttrib(20), callback) plc.write_by_name("a", 1, pyads.PLCTYPE_INT)
def subscribe_by_name(self, name: str, plc_type, callbacks): if plc_type not in self.DATATYPE_MAP: return plc_type_mapped = self.DATATYPE_MAP[plc_type] attr = pyads.NotificationAttrib(ctypes.sizeof(plc_type_mapped)) try: handles = self.plc.add_device_notification( name, attr, self.callback(plc_type_mapped, callbacks), pyads.ADSTRANS_SERVERCYCLE, ) self.notification_handles.append(handles) except pyads.ADSError as e: print("Error while subscribing to: ", name, " ", e)
def add_device_notification(self, name, plc_datatype, callback): """Add a notification to the ADS devices.""" attr = pyads.NotificationAttrib(ctypes.sizeof(plc_datatype)) with self._lock: try: hnotify, huser = self._client.add_device_notification( name, attr, self._device_notification_callback) except pyads.ADSError as err: _LOGGER.error("Error subscribing to %s: %s", name, err) else: hnotify = int(hnotify) self._notification_items[hnotify] = NotificationItem( hnotify, huser, name, plc_datatype, callback) _LOGGER.debug("Added device notification %d for variable %s", hnotify, name)
def start(self): logger.info('Starting blocklenium...') self._plc.open() with self._plc: attr = pyads.NotificationAttrib(sizeof(pyads.PLCTYPE_BOOL)) self._t.start() if self.config['DESK_LOGIN_REQUIRED']: try: user = self._plc.read_by_name(self.config['PLC_DESK_USER'], pyads.PLCTYPE_STRING) pwd = self._plc.read_by_name(self.config['PLC_DESK_PW'], pyads.PLCTYPE_STRING) self._t.desk_username = user self._t.desk_password = pwd except pyads.ADSError as e: self.handle_error( '''{0} or {1} not defined on PLC with --login-required flag set.'''.format( self.config['PLC_DESK_USER'], self.config['PLC_DESK_PW']), e) return self._plc.add_device_notification(self.config['PLC_START_FLAG'], attr, self.callback) while not self.is_error: sleep(10) try: self._plc.read_state() except pyads.ADSError: logger.info('PLC not running. Terminating...') self.queue.put(False) break self._t.join() logger.debug('Blocklenium terminated.') exit(0)
def test_functions_with_closed_port(self): # type: () -> None """Test pyads functions with no open port.""" pyads.open_port() adr = pyads.get_local_address() pyads.close_port() self.assertIsNotNone(adr) self.assertIsNone(pyads.get_local_address()) self.assertIsNone(pyads.read_state(adr)) self.assertIsNone(pyads.read_device_info(adr)) self.assertIsNone( pyads.read_write(adr, 1, 2, pyads.PLCTYPE_INT, 1, pyads.PLCTYPE_INT)) self.assertIsNone(pyads.read(adr, 1, 2, pyads.PLCTYPE_INT)) self.assertIsNone(pyads.read_by_name(adr, "hello", pyads.PLCTYPE_INT)) self.assertIsNone( pyads.add_device_notification(adr, "test", pyads.NotificationAttrib(4), lambda x: x))
def test_device_notification(self): def callback(notification, data): pass handle_name = "test" attr = pyads.NotificationAttrib(8) requests = self.test_server.request_history with self.plc: notification, user = self.plc.add_device_notification( handle_name, attr, callback) # Assert that Read/Write command was used to get the handle by name self.assert_command_id(requests[0], constants.ADSCOMMAND_READWRITE) # Assert that ADDDEVICENOTIFICATION was used to add device notification self.assert_command_id(requests[1], constants.ADSCOMMAND_ADDDEVICENOTE) self.plc.del_device_notification(notification, user) # Assert that ADDDEVICENOTIFICATION was used to add device notification self.assert_command_id(requests[2], constants.ADSCOMMAND_DELDEVICENOTE)
def subscribe_by_name(self, name: str, plc_type): attr = pyads.NotificationAttrib(ctypes.sizeof(plc_type)) handles = self.plc.add_device_notification(name, attr, self.callback(plc_type), pyads.ADSTRANS_SERVERCYCLE) self.notification_handles.append(handles)