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/wiffi/* @mampfes
homeassistant/components/wilight/* @leofig-rj
homeassistant/components/wirelesstag/* @sergeymaysak
homeassistant/components/withings/* @vangorra
homeassistant/components/wled/* @frenck
homeassistant/components/wolflink/* @adamkrol93

View file

@ -3,9 +3,8 @@ import logging
from requests.exceptions import ConnectTimeout, HTTPError
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 (
ATTR_BATTERY_LEVEL,
ATTR_VOLTAGE,
@ -67,11 +66,6 @@ class WirelessTagPlatform:
self.tags = {}
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):
"""Load tags from remote server."""
self.tags = self.api.load_tags()
@ -91,97 +85,44 @@ class WirelessTagPlatform:
if disarm_func is not None:
disarm_func(switch.tag_id, switch.tag_manager_mac)
def make_notifications(self, binary_sensors, mac):
"""Create configurations for push notifications."""
_LOGGER.info("Creating configurations for push notifications")
configs = []
def start_monitoring(self):
"""Start monitoring push events."""
bi_url = self.binary_event_callback_url
for bi_sensor in binary_sensors:
configs.extend(bi_sensor.event.build_notifications(bi_url, mac))
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:
_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:
tag_id = event.data.get("id")
mac = event.data.get("mac")
dispatcher_send(self.hass, SIGNAL_TAG_UPDATE.format(tag_id, mac), event)
except Exception as ex: # pylint: disable=broad-except
_LOGGER.error(
"Unable to handle tag update event:\
%s error: %s",
str(event),
str(ex),
def push_callback(tags_spec, event_spec):
"""Handle push update."""
_LOGGER.debug(
"Push notification arrived: %s, events: %s", tags_spec, event_spec
)
for uuid, tag in tags_spec.items():
try:
tag_id = tag.tag_id
mac = tag.tag_manager_mac
_LOGGER.debug("Push notification for tag update arrived: %s", tag)
dispatcher_send(
self.hass, SIGNAL_TAG_UPDATE.format(tag_id, mac), tag
)
if uuid in event_spec:
events = event_spec[uuid]
for event in events:
_LOGGER.debug(
"Push notification for binary event arrived: %s", event
)
dispatcher_send(
self.hass,
SIGNAL_BINARY_EVENT_UPDATE.format(
tag_id, event.type, mac
),
tag,
)
except Exception as ex: # pylint: disable=broad-except
_LOGGER.error(
"Unable to handle tag update:\
%s error: %s",
str(tag),
str(ex),
)
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(
self.hass,
SIGNAL_BINARY_EVENT_UPDATE.format(tag_id, event_type, mac),
event,
)
except Exception as ex: # pylint: disable=broad-except
_LOGGER.error(
"Unable to handle tag binary event:\
%s error: %s",
str(event),
str(ex),
)
self.api.start_monitoring(push_callback)
def setup(hass, config):
@ -195,6 +136,7 @@ def setup(hass, config):
platform = WirelessTagPlatform(hass, wirelesstags)
platform.load_tags()
platform.start_monitoring()
hass.data[DOMAIN] = platform
except (ConnectTimeout, HTTPError, WirelessTagsException) as ex:
_LOGGER.error("Unable to connect to wirelesstag.net service: %s", str(ex))
@ -205,12 +147,6 @@ def setup(hass, config):
)
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

View file

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

View file

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

View file

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

View file

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