Switch wirelesstag to use cloud push (#50984)

This commit is contained in:
Sergiy Maysak 2021-07-22 14:40:39 +03:00 committed by GitHub
parent ff781583fc
commit f009b1442f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 113 deletions

View File

@ -565,6 +565,7 @@ homeassistant/components/websocket_api/* @home-assistant/core
homeassistant/components/wemo/* @esev homeassistant/components/wemo/* @esev
homeassistant/components/wiffi/* @mampfes homeassistant/components/wiffi/* @mampfes
homeassistant/components/wilight/* @leofig-rj homeassistant/components/wilight/* @leofig-rj
homeassistant/components/wirelesstag/* @sergeymaysak
homeassistant/components/withings/* @vangorra homeassistant/components/withings/* @vangorra
homeassistant/components/wled/* @frenck homeassistant/components/wled/* @frenck
homeassistant/components/wolflink/* @adamkrol93 homeassistant/components/wolflink/* @adamkrol93

View File

@ -3,9 +3,8 @@ import logging
from requests.exceptions import ConnectTimeout, HTTPError from requests.exceptions import ConnectTimeout, HTTPError
import voluptuous as vol import voluptuous as vol
from wirelesstagpy import NotificationConfig as NC, WirelessTags, WirelessTagsException from wirelesstagpy import WirelessTags, WirelessTagsException
from homeassistant import util
from homeassistant.const import ( from homeassistant.const import (
ATTR_BATTERY_LEVEL, ATTR_BATTERY_LEVEL,
ATTR_VOLTAGE, ATTR_VOLTAGE,
@ -67,11 +66,6 @@ class WirelessTagPlatform:
self.tags = {} self.tags = {}
self._local_base_url = None self._local_base_url = None
@property
def tag_manager_macs(self):
"""Return list of tag managers mac addresses in user account."""
return self.api.mac_addresses
def load_tags(self): def load_tags(self):
"""Load tags from remote server.""" """Load tags from remote server."""
self.tags = self.api.load_tags() self.tags = self.api.load_tags()
@ -91,98 +85,45 @@ class WirelessTagPlatform:
if disarm_func is not None: if disarm_func is not None:
disarm_func(switch.tag_id, switch.tag_manager_mac) disarm_func(switch.tag_id, switch.tag_manager_mac)
def make_notifications(self, binary_sensors, mac): def start_monitoring(self):
"""Create configurations for push notifications.""" """Start monitoring push events."""
_LOGGER.info("Creating configurations for push notifications")
configs = []
bi_url = self.binary_event_callback_url def push_callback(tags_spec, event_spec):
for bi_sensor in binary_sensors: """Handle push update."""
configs.extend(bi_sensor.event.build_notifications(bi_url, mac)) _LOGGER.debug(
"Push notification arrived: %s, events: %s", tags_spec, event_spec
update_url = self.update_callback_url
update_config = NC.make_config_for_update_event(update_url, mac)
configs.append(update_config)
return configs
def install_push_notifications(self, binary_sensors):
"""Register local push notification from tag manager."""
_LOGGER.info("Registering local push notifications")
for mac in self.tag_manager_macs:
configs = self.make_notifications(binary_sensors, mac)
# install notifications for all tags in tag manager
# specified by mac
result = self.api.install_push_notification(0, configs, True, mac)
if not result:
self.hass.components.persistent_notification.create(
"Error: failed to install local push notifications <br />",
title="Wireless Sensor Tag Setup Local Push Notifications",
notification_id="wirelesstag_failed_push_notification",
) )
else: for uuid, tag in tags_spec.items():
_LOGGER.info(
"Installed push notifications for all tags in %s",
mac,
)
@property
def local_base_url(self):
"""Define base url of hass in local network."""
if self._local_base_url is None:
self._local_base_url = f"http://{util.get_local_ip()}"
port = self.hass.config.api.port
if port is not None:
self._local_base_url += f":{port}"
return self._local_base_url
@property
def update_callback_url(self):
"""Return url for local push notifications(update event)."""
return f"{self.local_base_url}/api/events/wirelesstag_update_tags"
@property
def binary_event_callback_url(self):
"""Return url for local push notifications(binary event)."""
return f"{self.local_base_url}/api/events/wirelesstag_binary_event"
def handle_update_tags_event(self, event):
"""Handle push event from wireless tag manager."""
_LOGGER.info("Push notification for update arrived: %s", event)
try: try:
tag_id = event.data.get("id") tag_id = tag.tag_id
mac = event.data.get("mac") mac = tag.tag_manager_mac
dispatcher_send(self.hass, SIGNAL_TAG_UPDATE.format(tag_id, mac), event) _LOGGER.debug("Push notification for tag update arrived: %s", tag)
except Exception as ex: # pylint: disable=broad-except dispatcher_send(
_LOGGER.error( self.hass, SIGNAL_TAG_UPDATE.format(tag_id, mac), tag
"Unable to handle tag update event:\ )
%s error: %s", if uuid in event_spec:
str(event), events = event_spec[uuid]
str(ex), for event in events:
_LOGGER.debug(
"Push notification for binary event arrived: %s", event
) )
def handle_binary_event(self, event):
"""Handle push notifications for binary (on/off) events."""
_LOGGER.info("Push notification for binary event arrived: %s", event)
try:
tag_id = event.data.get("id")
event_type = event.data.get("type")
mac = event.data.get("mac")
dispatcher_send( dispatcher_send(
self.hass, self.hass,
SIGNAL_BINARY_EVENT_UPDATE.format(tag_id, event_type, mac), SIGNAL_BINARY_EVENT_UPDATE.format(
event, tag_id, event.type, mac
),
tag,
) )
except Exception as ex: # pylint: disable=broad-except except Exception as ex: # pylint: disable=broad-except
_LOGGER.error( _LOGGER.error(
"Unable to handle tag binary event:\ "Unable to handle tag update:\
%s error: %s", %s error: %s",
str(event), str(tag),
str(ex), str(ex),
) )
self.api.start_monitoring(push_callback)
def setup(hass, config): def setup(hass, config):
"""Set up the Wireless Sensor Tag component.""" """Set up the Wireless Sensor Tag component."""
@ -195,6 +136,7 @@ def setup(hass, config):
platform = WirelessTagPlatform(hass, wirelesstags) platform = WirelessTagPlatform(hass, wirelesstags)
platform.load_tags() platform.load_tags()
platform.start_monitoring()
hass.data[DOMAIN] = platform hass.data[DOMAIN] = platform
except (ConnectTimeout, HTTPError, WirelessTagsException) as ex: except (ConnectTimeout, HTTPError, WirelessTagsException) as ex:
_LOGGER.error("Unable to connect to wirelesstag.net service: %s", str(ex)) _LOGGER.error("Unable to connect to wirelesstag.net service: %s", str(ex))
@ -205,12 +147,6 @@ def setup(hass, config):
) )
return False return False
# listen to custom events
hass.bus.listen(
"wirelesstag_update_tags", hass.data[DOMAIN].handle_update_tags_event
)
hass.bus.listen("wirelesstag_binary_event", hass.data[DOMAIN].handle_binary_event)
return True return True

View File

@ -81,7 +81,6 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
sensors.append(WirelessTagBinarySensor(platform, tag, sensor_type)) sensors.append(WirelessTagBinarySensor(platform, tag, sensor_type))
add_entities(sensors, True) add_entities(sensors, True)
hass.add_job(platform.install_push_notifications, sensors)
class WirelessTagBinarySensor(WirelessTagBaseSensor, BinarySensorEntity): class WirelessTagBinarySensor(WirelessTagBaseSensor, BinarySensorEntity):
@ -134,8 +133,8 @@ class WirelessTagBinarySensor(WirelessTagBaseSensor, BinarySensorEntity):
return self.principal_value return self.principal_value
@callback @callback
def _on_binary_event_callback(self, event): def _on_binary_event_callback(self, new_tag):
"""Update state from arrived push notification.""" """Update state from arrived push notification."""
# state should be 'on' or 'off' self._tag = new_tag
self._state = event.data.get("state") self._state = self.updated_state_value()
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -2,7 +2,7 @@
"domain": "wirelesstag", "domain": "wirelesstag",
"name": "Wireless Sensor Tags", "name": "Wireless Sensor Tags",
"documentation": "https://www.home-assistant.io/integrations/wirelesstag", "documentation": "https://www.home-assistant.io/integrations/wirelesstag",
"requirements": ["wirelesstagpy==0.4.1"], "requirements": ["wirelesstagpy==0.5.0"],
"codeowners": [], "codeowners": ["@sergeymaysak"],
"iot_class": "local_push" "iot_class": "cloud_push"
} }

View File

@ -108,9 +108,9 @@ class WirelessTagSensor(WirelessTagBaseSensor, SensorEntity):
return self._tag.sensor[self._sensor_type] return self._tag.sensor[self._sensor_type]
@callback @callback
def _update_tag_info_callback(self, event): def _update_tag_info_callback(self, new_tag):
"""Handle push notification sent by tag manager.""" """Handle push notification sent by tag manager."""
_LOGGER.debug("Entity to update state: %s event data: %s", self, event.data) _LOGGER.debug("Entity to update state: %s with new tag: %s", self, new_tag)
new_value = self._sensor.value_from_update_event(event.data) self._tag = new_tag
self._state = self.decorate_value(new_value) self._state = self.updated_state_value()
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -2372,7 +2372,7 @@ webexteamssdk==1.1.1
wiffi==1.0.1 wiffi==1.0.1
# homeassistant.components.wirelesstag # homeassistant.components.wirelesstag
wirelesstagpy==0.4.1 wirelesstagpy==0.5.0
# homeassistant.components.withings # homeassistant.components.withings
withings-api==2.3.2 withings-api==2.3.2