diff --git a/homeassistant/components/ads/__init__.py b/homeassistant/components/ads/__init__.py index f5742718b12..32d89b5b597 100644 --- a/homeassistant/components/ads/__init__.py +++ b/homeassistant/components/ads/__init__.py @@ -29,18 +29,40 @@ DATA_ADS = "data_ads" # Supported Types ADSTYPE_BOOL = "bool" ADSTYPE_BYTE = "byte" -ADSTYPE_DINT = "dint" ADSTYPE_INT = "int" -ADSTYPE_UDINT = "udint" ADSTYPE_UINT = "uint" +ADSTYPE_SINT = "sint" +ADSTYPE_USINT = "usint" +ADSTYPE_DINT = "dint" +ADSTYPE_UDINT = "udint" +ADSTYPE_WORD = "word" +ADSTYPE_DWORD = "dword" +ADSTYPE_LREAL = "lreal" +ADSTYPE_REAL = "real" +ADSTYPE_STRING = "string" +ADSTYPE_TIME = "time" +ADSTYPE_DATE = "date" +ADSTYPE_DATE_AND_TIME = "dt" +ADSTYPE_TOD = "tod" ADS_TYPEMAP = { ADSTYPE_BOOL: pyads.PLCTYPE_BOOL, ADSTYPE_BYTE: pyads.PLCTYPE_BYTE, - ADSTYPE_DINT: pyads.PLCTYPE_DINT, ADSTYPE_INT: pyads.PLCTYPE_INT, - ADSTYPE_UDINT: pyads.PLCTYPE_UDINT, ADSTYPE_UINT: pyads.PLCTYPE_UINT, + ADSTYPE_SINT: pyads.PLCTYPE_SINT, + ADSTYPE_USINT: pyads.PLCTYPE_USINT, + ADSTYPE_DINT: pyads.PLCTYPE_DINT, + ADSTYPE_UDINT: pyads.PLCTYPE_UDINT, + ADSTYPE_WORD: pyads.PLCTYPE_WORD, + ADSTYPE_DWORD: pyads.PLCTYPE_DWORD, + ADSTYPE_REAL: pyads.PLCTYPE_REAL, + ADSTYPE_LREAL: pyads.PLCTYPE_LREAL, + ADSTYPE_STRING: pyads.PLCTYPE_STRING, + ADSTYPE_TIME: pyads.PLCTYPE_TIME, + ADSTYPE_DATE: pyads.PLCTYPE_DATE, + ADSTYPE_DATE_AND_TIME: pyads.PLCTYPE_DT, + ADSTYPE_TOD: pyads.PLCTYPE_TOD, } CONF_ADS_FACTOR = "factor" @@ -75,12 +97,23 @@ SCHEMA_SERVICE_WRITE_DATA_BY_NAME = vol.Schema( { vol.Required(CONF_ADS_TYPE): vol.In( [ + ADSTYPE_BOOL, + ADSTYPE_BYTE, ADSTYPE_INT, ADSTYPE_UINT, - ADSTYPE_BYTE, - ADSTYPE_BOOL, + ADSTYPE_SINT, + ADSTYPE_USINT, ADSTYPE_DINT, ADSTYPE_UDINT, + ADSTYPE_WORD, + ADSTYPE_DWORD, + ADSTYPE_REAL, + ADSTYPE_LREAL, + ADSTYPE_STRING, + ADSTYPE_TIME, + ADSTYPE_DATE, + ADSTYPE_DATE_AND_TIME, + ADSTYPE_TOD, ] ), vol.Required(CONF_ADS_VALUE): vol.Coerce(int), @@ -222,37 +255,53 @@ class AdsHub: def _device_notification_callback(self, notification, name): """Handle device notifications.""" contents = notification.contents - hnotify = int(contents.hNotification) _LOGGER.debug("Received notification %d", hnotify) - # get dynamically sized data array + # Get dynamically sized data array data_size = contents.cbSampleSize - data = (ctypes.c_ubyte * data_size).from_address( + data_address = ( ctypes.addressof(contents) + pyads.structs.SAdsNotificationHeader.data.offset ) + data = (ctypes.c_ubyte * data_size).from_address(data_address) - try: - with self._lock: - notification_item = self._notification_items[hnotify] - except KeyError: + # Acquire notification item + with self._lock: + notification_item = self._notification_items.get(hnotify) + + if not notification_item: _LOGGER.error("Unknown device notification handle: %d", hnotify) return - # Parse data to desired datatype - if notification_item.plc_datatype == pyads.PLCTYPE_BOOL: + # Data parsing based on PLC data type + plc_datatype = notification_item.plc_datatype + unpack_formats = { + pyads.PLCTYPE_BYTE: "