Example #1
0
    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
Example #2
0
    def test_notification_decorator_filetime(self):
        # type: () -> None
        """Test passthrough of FILETIME value by notification decorator"""
        @self.plc.notification(timestamp_as_filetime=True)
        def callback(handle, name, timestamp, value):
            self.assertEqual(timestamp, 132223104000000000)

        notification = structs.SAdsNotificationHeader()
        notification.nTimeStamp = 132223104000000000
        notification.cbSampleSize = 1
        notification.data = 5
        callback(pointer(notification), "TestName")
Example #3
0
 def create_notification_struct(self, payload):
     # type: (bytes) -> structs.SAdsNotificationHeader
     buf = b"\x00" * 12  # hNotification, nTimeStamp
     buf += struct.pack("<i", len(payload))
     buf += payload
     notification = structs.SAdsNotificationHeader()
     resize(notification, len(buf))
     memmove(
         pointer(notification),
         (ctypes.c_ubyte * len(buf)).from_buffer_copy(buf),
         sizeof(notification),
     )
     return notification
Example #4
0
def create_notification_struct(payload: bytes) -> \
        structs.SAdsNotificationHeader:
    """Create notification callback structure"""
    buf = b"\x00" * 12  # hNotification, nTimeStamp
    buf += struct.pack("<i", len(payload))
    buf += payload
    notification = structs.SAdsNotificationHeader()
    resize(notification, len(buf))
    memmove(
        pointer(notification),
        (ctypes.c_ubyte * len(buf)).from_buffer_copy(buf),
        sizeof(notification),
    )
    return notification
Example #5
0
    def test_notification_decorator(self):
        # type: () -> None
        """Test decoding of header by notification decorator"""
        @self.plc.notification()
        def callback(handle, name, timestamp, value):
            self.assertEqual(handle, 1234)
            self.assertEqual(name, "TestName")
            self.assertEqual(timestamp, datetime.datetime(2020, 1, 1))
            self.assertEqual(value, bytearray((5, )))

        notification = structs.SAdsNotificationHeader()
        notification.hNotification = 1234
        notification.nTimeStamp = 132223104000000000
        notification.cbSampleSize = 1
        notification.data = 5
        callback(pointer(notification), "TestName")