def write(self, value: bytes, request: AmsPacket = None): """Update the variable value, respecting notifications""" if self.value != value: if self.notifications: header = structs.SAdsNotificationHeader() header.hNotification = 0 header.nTimeStamp = dt_to_filetime(datetime.now()) header.cbSampleSize = len(value) # Perform byte-write into the header dst = ctypes.addressof( header) + structs.SAdsNotificationHeader.data.offset ctypes.memmove(dst, value, len(value)) for notification_handle in self.notifications: # It's hard to guess the exact AmsAddr from here, so instead # ignore the address and search for the note_handle for key, func in callback_store.items(): # callback_store is keyed by (AmsAddr, int) if key[1] != notification_handle: continue header.hNotification = notification_handle addr = key[0] # Call c-wrapper for user callback func(addr.amsAddrStruct(), header, 0) self.value = value
def test_ads_notification_stream(self): dt = datetime.datetime(2017, 9, 1, 10, 10, 10) filetime = dt_to_filetime(dt) stream = structs.AdsNotificationStream([ structs.AdsStampHeader( timestamp=filetime, samples=[ structs.AdsNotificationSample( handle=1, sample_size=ctypes.sizeof(pyads.PLCTYPE_INT), data=struct.pack("<H", 12), ) ], ) ]) self.assertEqual( b"\x16\x00\x00\x00" # length b"\x01\x00\x00\x00" # stamp count b"\x00\xadT~\n#\xd3\x01" # stamp timestamp b"\x01\x00\x00\x00" # stamp sample count b"\x01\x00\x00\x00" # sample handle b"\x02\x00\x00\x00" # sample sample_size b"\x0C\x00", # sample data stream.to_bytes(), ) self.assertEqual(stream.length, 30)
def test_ads_notification_stream(self): dt = datetime.datetime(2017, 9, 1, 10, 10, 10) filetime = dt_to_filetime(dt) stream = structs.AdsNotificationStream([ structs.AdsStampHeader( timestamp=filetime, samples=[structs.AdsNotificationSample( handle=1, sample_size=ctypes.sizeof(pyads.PLCTYPE_INT), data=struct.pack('<H', 12) )] ) ]) self.assertEqual( b'\x16\x00\x00\x00' # length b'\x01\x00\x00\x00' # stamp count b'\x00\xadT~\n#\xd3\x01' # stamp timestamp b'\x01\x00\x00\x00' # stamp sample count b'\x01\x00\x00\x00' # sample handle b'\x02\x00\x00\x00' # sample sample_size b'\x0C\x00', # sample data stream.to_bytes() ) self.assertEqual(stream.length, 30)
def test_filetime_dt_conversion(self): dt_now = datetime(2017, 10, 13, 10, 11, 12) ft = dt_to_filetime(dt_now) dt = filetime_to_dt(ft) # should be identical self.assertEqual(dt_now, dt)
def test_ads_stamp_header(self): dt = datetime.datetime(2017, 9, 1, 10, 10, 10) filetime = dt_to_filetime(dt) stamp_header = structs.AdsStampHeader( timestamp=filetime, samples=[ structs.AdsNotificationSample(handle=1, sample_size=ctypes.sizeof( pyads.PLCTYPE_INT), data=struct.pack('<H', 12)) ]) self.assertEqual( b'\x00\xadT~\n#\xd3\x01' # timestamp b'\x01\x00\x00\x00' # sample count b'\x01\x00\x00\x00' # sample handle b'\x02\x00\x00\x00' # sample sample_size b'\x0C\x00', # sample data stamp_header.to_bytes()) self.assertEqual(stamp_header.length, 22)