async def async_handle_push_notification(self, namespace: Namespace, data: dict) -> bool: locally_handled = False if namespace == Namespace.HUB_ONLINE: update_element = self.__prepare_push_notification_data(data=data) self._online = OnlineStatus(update_element.get('status', -1)) locally_handled = True elif namespace == Namespace.HUB_MTS100_ALL: self._schedule_b_mode = data.get('scheduleBMode') self._online = OnlineStatus(data.get('online', {}).get('status', -1)) self._last_active_time = data.get('online', {}).get('lastActiveTime') self.__togglex.update(data.get('togglex', {})) self.__timeSync = data.get('timeSync', {}) self.__mode.update(data.get('mode', {})) self.__temperature.update(data.get('temperature', {})) locally_handled = True elif namespace == Namespace.HUB_TOGGLEX: update_element = self.__prepare_push_notification_data(data=data) self.__togglex.update(update_element) locally_handled = True elif namespace == Namespace.HUB_MTS100_MODE: update_element = self.__prepare_push_notification_data(data=data) self.__mode.update(update_element) locally_handled = True elif namespace == Namespace.HUB_MTS100_TEMPERATURE: update_element = self.__prepare_push_notification_data(data=data) self.__temperature.update(update_element) locally_handled = True # Always call the parent handler when done with local specific logic. This gives the opportunity to all # ancestors to catch all events. parent_handled = await super().async_handle_push_notification(namespace=namespace, data=data) return locally_handled or parent_handled
async def _async_push_notification_received(self, namespace: Namespace, data: dict, device_internal_id: str): update_state = False full_update = False if namespace == Namespace.CONTROL_UNBIND: _LOGGER.warning( f"Received unbind event. Removing device {self.name} from HA") await self.platform.async_remove_entity(self.entity_id) elif namespace == Namespace.SYSTEM_ONLINE: _LOGGER.warning(f"Device {self.name} reported online event.") online = OnlineStatus(int(data.get('online').get('status'))) update_state = True full_update = online == OnlineStatus.ONLINE elif namespace == Namespace.HUB_ONLINE: _LOGGER.warning(f"Device {self.name} reported (HUB) online event.") online = OnlineStatus(int(data.get('status'))) update_state = True full_update = online == OnlineStatus.ONLINE else: update_state = True full_update = False # In all other cases, just tell HA to update the internal state representation if update_state: self.async_schedule_update_ha_state(force_refresh=full_update)
async def _async_push_notification_received(self, namespace: Namespace, data: dict, device_internal_id: str): update_state = False full_update = False if namespace == Namespace.CONTROL_UNBIND: self.logger.warning( f"Received unbind event. Removing device {self._device.name} from FHEM" ) await self.platform.async_remove_entity(self.entity_id) elif namespace == Namespace.SYSTEM_ONLINE: self.logger.warning( f"Device {self._device.name} reported online event.") online = OnlineStatus(int(data.get("online").get("status"))) update_state = True full_update = online == OnlineStatus.ONLINE elif namespace == Namespace.HUB_ONLINE: self.logger.warning( f"Device {self._device.name} reported (HUB) online event.") online = OnlineStatus(int(data.get("status"))) update_state = True full_update = online == OnlineStatus.ONLINE else: update_state = True full_update = False if full_update: await self._device.async_update() if update_state: await self.update_readings()
async def async_handle_push_notification(self, namespace: Namespace, data: dict) -> bool: locally_handled = False if namespace == Namespace.HUB_ONLINE: update_element = self._prepare_push_notification_data( data=data, filter_accessor='online') self._online = OnlineStatus(update_element.get('status', -1)) locally_handled = True elif namespace == Namespace.HUB_SENSOR_ALL: self._online = OnlineStatus( data.get('online', {}).get('status', -1)) self.__temperature.update(data.get('temperature', {})) self.__humidity.update(data.get('humidity', {})) locally_handled = True elif namespace == Namespace.HUB_SENSOR_TEMPHUM: latest_temperature = data.get('latestTemperature') latest_humidity = data.get('latestHumidity') synced_time = data.get('syncedTime') samples = data.get('sample') if synced_time is not None and ( self.last_sampled_time is None or synced_time > self.last_sampled_time.timestamp()): self.__temperature['latestSampleTime'] = synced_time self.__temperature['latest'] = latest_temperature self.__humidity['latestSampleTime'] = synced_time self.__humidity['latest'] = latest_humidity self.__samples.clear() for sample in samples: temp, hum, from_ts, to_ts, unknown = sample self.__samples.append({ 'from_ts': from_ts, 'to_ts': to_ts, 'temperature': float(temp) / 10, 'humidity': float(hum) / 10 }) else: _LOGGER.debug( "Skipping temperature update as synched time is None or old compared to the latest data" ) locally_handled = True elif namespace == Namespace.HUB_SENSOR_ALERT: locally_handled = False # TODO: not yet implemented # Always call the parent handler when done with local specific logic. This gives the opportunity to all # ancestors to catch all events. parent_handled = await super().async_handle_push_notification( namespace=namespace, data=data) return locally_handled or parent_handled
async def async_handle_push_notification(self, namespace: Namespace, data: dict) -> bool: locally_handled = False if namespace == Namespace.HUB_ONLINE: update_element = self._prepare_push_notification_data(data=data, filter_accessor='online') if update_element is not None: self._online = OnlineStatus(update_element.get('status', -1)) locally_handled = True return locally_handled
async def async_handle_update(self, namespace: Namespace, data: dict) -> bool: _LOGGER.debug(f"Handling {self.__class__.__name__} mixin data update.") locally_handled = False if namespace == Namespace.SYSTEM_ALL: online_data = data.get('all').get('system').get('online') status = OnlineStatus(int(online_data.get("status"))) self._online = status locally_handled = True super_handled = await super().async_handle_update(namespace=namespace, data=data) return super_handled or locally_handled
async def evt_coro(namespace: Namespace, data: dict, device_internal_id: str, *args, **kwargs): if namespace == Namespace.SYSTEM_ONLINE: status = OnlineStatus(int(data.get('online').get('status'))) if not disconnection_event.is_set( ) and status == OnlineStatus.UNKNOWN: _LOGGER.info("Disconnection event caught") disconnection_event.set() elif not connection_event.is_set( ) and status == OnlineStatus.ONLINE: _LOGGER.info("Connection event caught") connection_event.set()
async def async_handle_subdevice_notification(self, namespace: Namespace, data: dict) -> bool: locally_handled = False if namespace == Namespace.HUB_ONLINE: self._online = OnlineStatus(data.get('online', {}).get('status', -1)) self._last_active_time = data.get('online', {}).get('lastActiveTime') elif namespace == Namespace.HUB_MTS100_ALL: self._schedule_b_mode = data.get('scheduleBMode') self._online = OnlineStatus(data.get('online', {}).get('status', -1)) self._last_active_time = data.get('online', {}).get('lastActiveTime') self.__togglex.update(data.get('togglex', {})) self.__timeSync = data.get('timeSync', {}) self.__mode.update(data.get('mode', {})) self.__temperature.update(data.get('temperature', {})) self.__temperature['latestSampleTime'] = datetime.utcnow().timestamp() self.__adjust.update(data.get('temperature', {})) self.__adjust['latestSampleTime'] = datetime.utcnow().timestamp() locally_handled = True elif namespace == Namespace.HUB_TOGGLEX: update_element = self._prepare_push_notification_data(data=data) if update_element is not None: self.__togglex.update(update_element) locally_handled = True elif namespace == Namespace.HUB_MTS100_MODE: update_element = self._prepare_push_notification_data(data=data) if update_element is not None: self.__mode.update(update_element) locally_handled = True elif namespace == Namespace.HUB_MTS100_TEMPERATURE: update_element = self._prepare_push_notification_data(data=data) if update_element is not None: self.__temperature.update(update_element) self.__temperature['latestSampleTime'] = datetime.utcnow().timestamp() locally_handled = True else: _LOGGER.error(f"Could not handle event %s in subdevice %s handler", namespace, self.name) # Always call the parent handler when done with local specific logic. This gives the opportunity to all # ancestors to catch all events. parent_handled = await super().async_handle_push_notification(namespace=namespace, data=data) return locally_handled or parent_handled
def __init__( self, device_uuid: str, manager, # TODO: type hinting "manager" **kwargs): self._uuid = device_uuid self._manager = manager self._channels = self._parse_channels(kwargs.get('channels', [])) # Information about device self._name = kwargs.get('devName') self._type = kwargs.get('deviceType') self._fwversion = kwargs.get('fmwareVersion') self._hwversion = kwargs.get('hdwareVersion') self._online = OnlineStatus(kwargs.get('onlineStatus', -1)) # Domain and port domain = kwargs.get('domain') reserved_domain = kwargs.get('reservedDomain') # Prefer domain over reserved domain if domain is not None: self._mqtt_host = domain elif reserved_domain is not None: self._mqtt_host = reserved_domain else: _LOGGER.warning( "No MQTT DOMAIN specified in args, assuming default value %s", DEFAULT_MQTT_HOST) port = kwargs.get("port") second_port = kwargs.get("secondPort") if port is not None: self._mqtt_port = port elif second_port is not None: self._mqtt_port = second_port else: _LOGGER.info( "No MQTT PORT specified in args, assuming default value %d", DEFAULT_MQTT_PORT) self._mqtt_port = DEFAULT_MQTT_PORT if hasattr(self, "_abilities_spec"): self._abilities = self._abilities_spec else: self._abilities = {} self._push_coros = [] self._last_full_update_ts = None # Set default timeout value for command execution self._timeout = DEFAULT_COMMAND_TIMEOUT
def __init__(self, uuid: str, online_status: Union[int, OnlineStatus], dev_name: str, dev_icon_id: str, bind_time: Union[int, datetime], device_type: str, sub_type: str, channels: List[dict], region: str, fmware_version: str, hdware_version: str, user_dev_icon: str, icon_type: int, skill_number: str, domain: str, reserved_domain: str, *args, **kwargs): super().__init__(*args, **kwargs) self.uuid = uuid if isinstance(online_status, int): self.online_status = OnlineStatus(online_status) elif isinstance(online_status, OnlineStatus): self.online_status = online_status else: _LOGGER.warning(f"Provided online_status is not int neither OnlineStatus. It will be ignored.") self.online_status = None self.dev_name = dev_name self.dev_icon_id = dev_icon_id if isinstance(bind_time, int): self.bind_time = datetime.utcfromtimestamp(bind_time) elif isinstance(bind_time, datetime): self.bind_time = bind_time else: _LOGGER.warning(f"Provided bind_time is not int neither datetime. It will be ignored.") self.bind_time = None self.device_type = device_type self.sub_type = sub_type self.channels = channels self.region = region self.fmware_version = fmware_version self.hdware_version = hdware_version self.user_dev_icon = user_dev_icon self.icon_type = icon_type self.skill_number = skill_number self.domain = domain self.reserved_domain = reserved_domain
def __init__( self, device_uuid: str, manager, # TODO: type hinting "manager" **kwargs): self._uuid = device_uuid self._manager = manager self._channels = self._parse_channels(kwargs.get('channels', [])) # Information about device self._name = kwargs.get('devName') self._type = kwargs.get('deviceType') self._fwversion = kwargs.get('fmwareVersion') self._hwversion = kwargs.get('hdwareVersion') self._online = OnlineStatus(kwargs.get('onlineStatus', -1)) self._abilities = {} self._push_coros = []
async def async_handle_push_notification(self, namespace: Namespace, data: dict) -> bool: locally_handled = False if namespace == Namespace.SYSTEM_ONLINE: _LOGGER.debug(f"OnlineMixin handling push notification for namespace {namespace}") payload = data.get('online') if payload is None: _LOGGER.error(f"OnlineMixin could not find 'online' attribute in push notification data: " f"{data}") locally_handled = False else: status = OnlineStatus(int(payload.get("status"))) self._online = status locally_handled = True # Always call the parent handler when done with local specific logic. This gives the opportunity to all # ancestors to catch all events. parent_handled = await super().async_handle_push_notification(namespace=namespace, data=data) return locally_handled or parent_handled