mirror of
https://github.com/home-assistant/core.git
synced 2025-12-25 21:47:08 +00:00
Remove IBM Watson IoT Platform integration (#153567)
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"domain": "ibm",
|
||||
"name": "IBM",
|
||||
"integrations": ["watson_iot", "watson_tts"]
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
"""Support for the IBM Watson IoT Platform."""
|
||||
|
||||
import logging
|
||||
import queue
|
||||
import threading
|
||||
import time
|
||||
|
||||
from ibmiotf import MissingMessageEncoderException
|
||||
from ibmiotf.gateway import Client
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
CONF_DOMAINS,
|
||||
CONF_ENTITIES,
|
||||
CONF_EXCLUDE,
|
||||
CONF_ID,
|
||||
CONF_INCLUDE,
|
||||
CONF_TOKEN,
|
||||
CONF_TYPE,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
EVENT_STATE_CHANGED,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import config_validation as cv, state as state_helper
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_ORG = "organization"
|
||||
|
||||
DOMAIN = "watson_iot"
|
||||
|
||||
MAX_TRIES = 3
|
||||
|
||||
RETRY_DELAY = 20
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
DOMAIN: vol.All(
|
||||
vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_ORG): cv.string,
|
||||
vol.Required(CONF_TYPE): cv.string,
|
||||
vol.Required(CONF_ID): cv.string,
|
||||
vol.Required(CONF_TOKEN): cv.string,
|
||||
vol.Optional(CONF_EXCLUDE, default={}): vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_ENTITIES, default=[]): cv.entity_ids,
|
||||
vol.Optional(CONF_DOMAINS, default=[]): vol.All(
|
||||
cv.ensure_list, [cv.string]
|
||||
),
|
||||
}
|
||||
),
|
||||
vol.Optional(CONF_INCLUDE, default={}): vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_ENTITIES, default=[]): cv.entity_ids,
|
||||
vol.Optional(CONF_DOMAINS, default=[]): vol.All(
|
||||
cv.ensure_list, [cv.string]
|
||||
),
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
},
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
|
||||
def setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up the Watson IoT Platform component."""
|
||||
|
||||
conf = config[DOMAIN]
|
||||
|
||||
include = conf[CONF_INCLUDE]
|
||||
exclude = conf[CONF_EXCLUDE]
|
||||
include_e = set(include[CONF_ENTITIES])
|
||||
include_d = set(include[CONF_DOMAINS])
|
||||
exclude_e = set(exclude[CONF_ENTITIES])
|
||||
exclude_d = set(exclude[CONF_DOMAINS])
|
||||
|
||||
client_args = {
|
||||
"org": conf[CONF_ORG],
|
||||
"type": conf[CONF_TYPE],
|
||||
"id": conf[CONF_ID],
|
||||
"auth-method": "token",
|
||||
"auth-token": conf[CONF_TOKEN],
|
||||
}
|
||||
watson_gateway = Client(client_args)
|
||||
|
||||
def event_to_json(event):
|
||||
"""Add an event to the outgoing list."""
|
||||
state = event.data.get("new_state")
|
||||
if (
|
||||
state is None
|
||||
or state.state in (STATE_UNKNOWN, "", STATE_UNAVAILABLE)
|
||||
or state.entity_id in exclude_e
|
||||
or state.domain in exclude_d
|
||||
):
|
||||
return None
|
||||
|
||||
if (include_e and state.entity_id not in include_e) or (
|
||||
include_d and state.domain not in include_d
|
||||
):
|
||||
return None
|
||||
|
||||
try:
|
||||
_state_as_value = float(state.state)
|
||||
except ValueError:
|
||||
_state_as_value = None
|
||||
|
||||
if _state_as_value is None:
|
||||
try:
|
||||
_state_as_value = float(state_helper.state_as_number(state))
|
||||
except ValueError:
|
||||
_state_as_value = None
|
||||
|
||||
out_event = {
|
||||
"tags": {"domain": state.domain, "entity_id": state.object_id},
|
||||
"time": event.time_fired.isoformat(),
|
||||
"fields": {"state": state.state},
|
||||
}
|
||||
if _state_as_value is not None:
|
||||
out_event["fields"]["state_value"] = _state_as_value
|
||||
|
||||
for key, value in state.attributes.items():
|
||||
if key != "unit_of_measurement":
|
||||
# If the key is already in fields
|
||||
if key in out_event["fields"]:
|
||||
key = f"{key}_"
|
||||
# For each value we try to cast it as float
|
||||
# But if we cannot do it we store the value
|
||||
# as string
|
||||
try:
|
||||
out_event["fields"][key] = float(value)
|
||||
except (ValueError, TypeError):
|
||||
out_event["fields"][key] = str(value)
|
||||
|
||||
return out_event
|
||||
|
||||
instance = hass.data[DOMAIN] = WatsonIOTThread(hass, watson_gateway, event_to_json)
|
||||
instance.start()
|
||||
|
||||
def shutdown(event):
|
||||
"""Shut down the thread."""
|
||||
instance.queue.put(None)
|
||||
instance.join()
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, shutdown)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class WatsonIOTThread(threading.Thread):
|
||||
"""A threaded event handler class."""
|
||||
|
||||
def __init__(self, hass, gateway, event_to_json):
|
||||
"""Initialize the listener."""
|
||||
threading.Thread.__init__(self, name="WatsonIOT")
|
||||
self.queue = queue.Queue()
|
||||
self.gateway = gateway
|
||||
self.gateway.connect()
|
||||
self.event_to_json = event_to_json
|
||||
self.write_errors = 0
|
||||
self.shutdown = False
|
||||
hass.bus.listen(EVENT_STATE_CHANGED, self._event_listener)
|
||||
|
||||
@callback
|
||||
def _event_listener(self, event):
|
||||
"""Listen for new messages on the bus and queue them for Watson IoT."""
|
||||
item = (time.monotonic(), event)
|
||||
self.queue.put(item)
|
||||
|
||||
def get_events_json(self):
|
||||
"""Return an event formatted for writing."""
|
||||
events = []
|
||||
|
||||
try:
|
||||
if (item := self.queue.get()) is None:
|
||||
self.shutdown = True
|
||||
else:
|
||||
event_json = self.event_to_json(item[1])
|
||||
if event_json:
|
||||
events.append(event_json)
|
||||
|
||||
except queue.Empty:
|
||||
pass
|
||||
|
||||
return events
|
||||
|
||||
def write_to_watson(self, events):
|
||||
"""Write preprocessed events to watson."""
|
||||
|
||||
for event in events:
|
||||
for retry in range(MAX_TRIES + 1):
|
||||
try:
|
||||
for field in event["fields"]:
|
||||
value = event["fields"][field]
|
||||
device_success = self.gateway.publishDeviceEvent(
|
||||
event["tags"]["domain"],
|
||||
event["tags"]["entity_id"],
|
||||
field,
|
||||
"json",
|
||||
value,
|
||||
)
|
||||
if not device_success:
|
||||
_LOGGER.error("Failed to publish message to Watson IoT")
|
||||
continue
|
||||
break
|
||||
except (MissingMessageEncoderException, OSError):
|
||||
if retry < MAX_TRIES:
|
||||
time.sleep(RETRY_DELAY)
|
||||
else:
|
||||
_LOGGER.exception("Failed to publish message to Watson IoT")
|
||||
|
||||
def run(self):
|
||||
"""Process incoming events."""
|
||||
while not self.shutdown:
|
||||
if event := self.get_events_json():
|
||||
self.write_to_watson(event)
|
||||
self.queue.task_done()
|
||||
|
||||
def block_till_done(self):
|
||||
"""Block till all events processed."""
|
||||
self.queue.join()
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"domain": "watson_iot",
|
||||
"name": "IBM Watson IoT Platform",
|
||||
"codeowners": [],
|
||||
"documentation": "https://www.home-assistant.io/integrations/watson_iot",
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["ibmiotf", "paho_mqtt"],
|
||||
"quality_scale": "legacy",
|
||||
"requirements": ["ibmiotf==0.3.4"]
|
||||
}
|
||||
@@ -2923,23 +2923,6 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"single_config_entry": true
|
||||
},
|
||||
"ibm": {
|
||||
"name": "IBM",
|
||||
"integrations": {
|
||||
"watson_iot": {
|
||||
"integration_type": "hub",
|
||||
"config_flow": false,
|
||||
"iot_class": "cloud_push",
|
||||
"name": "IBM Watson IoT Platform"
|
||||
},
|
||||
"watson_tts": {
|
||||
"integration_type": "hub",
|
||||
"config_flow": false,
|
||||
"iot_class": "cloud_push",
|
||||
"name": "IBM Watson TTS"
|
||||
}
|
||||
}
|
||||
},
|
||||
"idteck_prox": {
|
||||
"name": "IDTECK Proximity Reader",
|
||||
"integration_type": "hub",
|
||||
@@ -7447,6 +7430,12 @@
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push"
|
||||
},
|
||||
"watson_tts": {
|
||||
"name": "IBM Watson TTS",
|
||||
"integration_type": "hub",
|
||||
"config_flow": false,
|
||||
"iot_class": "cloud_push"
|
||||
},
|
||||
"watttime": {
|
||||
"name": "WattTime",
|
||||
"integration_type": "service",
|
||||
|
||||
3
requirements_all.txt
generated
3
requirements_all.txt
generated
@@ -1218,9 +1218,6 @@ iaqualink==0.6.0
|
||||
# homeassistant.components.ibeacon
|
||||
ibeacon-ble==1.2.0
|
||||
|
||||
# homeassistant.components.watson_iot
|
||||
ibmiotf==0.3.4
|
||||
|
||||
# homeassistant.components.google
|
||||
# homeassistant.components.local_calendar
|
||||
# homeassistant.components.local_todo
|
||||
|
||||
@@ -1067,7 +1067,6 @@ INTEGRATIONS_WITHOUT_QUALITY_SCALE_FILE = [
|
||||
"wallbox",
|
||||
"waqi",
|
||||
"waterfurnace",
|
||||
"watson_iot",
|
||||
"watson_tts",
|
||||
"watttime",
|
||||
"waze_travel_time",
|
||||
@@ -2116,7 +2115,6 @@ INTEGRATIONS_WITHOUT_SCALE = [
|
||||
"wallbox",
|
||||
"waqi",
|
||||
"waterfurnace",
|
||||
"watson_iot",
|
||||
"watson_tts",
|
||||
"watttime",
|
||||
"waze_travel_time",
|
||||
|
||||
Reference in New Issue
Block a user