From f6379fe6873fffb84d299d948bafe438914ac619 Mon Sep 17 00:00:00 2001 From: Martin Bauer Date: Sat, 1 May 2021 11:54:54 +0000 Subject: [PATCH] Updated own integrations for new HA version --- config_creation/manual_config.yaml | 12 ++- custom_components/cover_half/manifest.json | 10 +++ custom_components/dimmer/manifest.json | 10 +++ custom_components/fhem/binary_sensor.py | 4 +- custom_components/fhem/cover.py | 4 +- custom_components/fhem/light.py | 4 +- custom_components/fhem/manifest.json | 3 +- custom_components/fhem/switch.py | 4 +- custom_components/httpsispmctl/manifest.json | 10 +++ custom_components/httpsispmctl/switch.py | 4 +- custom_components/lirc_network/__init__.py | 1 - custom_components/lirc_network/manifest.json | 3 +- custom_components/long_click/manifest.json | 10 +++ custom_components/ondilo/__init__.py | 78 +++++++++++++++++++ custom_components/ondilo/config_flow.py | 35 +++++++++ custom_components/ondilo/const.py | 4 + custom_components/ondilo/manifest.json | 10 +++ custom_components/ondilo/sensor.py | 52 +++++++++++++ custom_components/reconnecting_client.py | 4 +- .../squeezebox_telnet/manifest.json | 3 +- .../squeezebox_telnet/media_player.py | 9 ++- custom_components/squeezebox_telnet/radio.py | 46 +++++------ custom_components/sysdweb/binary_sensor.py | 4 +- custom_components/sysdweb/manifest.json | 10 +++ custom_components/watson_tts/manifest.json | 3 +- 25 files changed, 286 insertions(+), 51 deletions(-) create mode 100644 custom_components/cover_half/manifest.json create mode 100644 custom_components/dimmer/manifest.json create mode 100644 custom_components/httpsispmctl/manifest.json create mode 100644 custom_components/long_click/manifest.json create mode 100644 custom_components/ondilo/__init__.py create mode 100644 custom_components/ondilo/config_flow.py create mode 100644 custom_components/ondilo/const.py create mode 100644 custom_components/ondilo/manifest.json create mode 100644 custom_components/ondilo/sensor.py create mode 100644 custom_components/sysdweb/manifest.json diff --git a/config_creation/manual_config.yaml b/config_creation/manual_config.yaml index 46c9898..81cbb49 100644 --- a/config_creation/manual_config.yaml +++ b/config_creation/manual_config.yaml @@ -510,14 +510,12 @@ media_player: host: server.fritz.box - platform: squeezebox_telnet host: musikserverWohnzimmerOben.fritz.box - - platform: denonavr - host: avreceiver.fritz.box - -vacuum: - - platform: xiaomi_miio - host: vacuum.fritz.box - token: !secret vacuum_token +# set up via frontend :( +#vacuum: +# - platform: xiaomi_miio +# host: vacuum.fritz.box +# token: !secret vacuum_token sensor: diff --git a/custom_components/cover_half/manifest.json b/custom_components/cover_half/manifest.json new file mode 100644 index 0000000..f277eef --- /dev/null +++ b/custom_components/cover_half/manifest.json @@ -0,0 +1,10 @@ + +{ + "domain": "cover_half", + "name": "Cover Half", + "documentation": "", + "dependencies": [], + "codeowners": ["@mabau"], + "requirements": [], + "version": "0.1" +} \ No newline at end of file diff --git a/custom_components/dimmer/manifest.json b/custom_components/dimmer/manifest.json new file mode 100644 index 0000000..96beb16 --- /dev/null +++ b/custom_components/dimmer/manifest.json @@ -0,0 +1,10 @@ + +{ + "domain": "dimmer", + "name": "DimmerIntegration", + "documentation": "", + "dependencies": [], + "codeowners": ["@mabau"], + "requirements": [], + "version": "0.1" +} \ No newline at end of file diff --git a/custom_components/fhem/binary_sensor.py b/custom_components/fhem/binary_sensor.py index c9924f3..ddb6713 100644 --- a/custom_components/fhem/binary_sensor.py +++ b/custom_components/fhem/binary_sensor.py @@ -3,7 +3,7 @@ import voluptuous as vol import logging -from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorDevice, \ +from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorEntity, \ DEVICE_CLASS_MOTION, DEVICE_CLASS_OPENING, DEVICE_CLASS_BATTERY from homeassistant.const import CONF_NAME import homeassistant.helpers.config_validation as cv @@ -35,7 +35,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= async_add_entities([sensor]) -class FhemBinarySensor(BinarySensorDevice): +class FhemBinarySensor(BinarySensorEntity): def __init__(self, connection, name, ids, sensor_type): self._on = None diff --git a/custom_components/fhem/cover.py b/custom_components/fhem/cover.py index cb8a667..0423ec3 100644 --- a/custom_components/fhem/cover.py +++ b/custom_components/fhem/cover.py @@ -3,7 +3,7 @@ import voluptuous as vol import logging -from homeassistant.components.cover import PLATFORM_SCHEMA, CoverDevice, SUPPORT_OPEN, SUPPORT_CLOSE, \ +from homeassistant.components.cover import PLATFORM_SCHEMA, CoverEntity, SUPPORT_OPEN, SUPPORT_CLOSE, \ SUPPORT_SET_POSITION, SUPPORT_STOP, ATTR_POSITION from homeassistant.const import CONF_NAME import homeassistant.helpers.config_validation as cv @@ -27,7 +27,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= async_add_entities([cover]) -class FhemCover(CoverDevice): +class FhemCover(CoverEntity): def __init__(self, connection, name, ids): self._position = None diff --git a/custom_components/fhem/light.py b/custom_components/fhem/light.py index c3486c2..fac9d09 100644 --- a/custom_components/fhem/light.py +++ b/custom_components/fhem/light.py @@ -3,7 +3,7 @@ import voluptuous as vol import logging -from homeassistant.components.light import ATTR_BRIGHTNESS, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS, Light, ATTR_TRANSITION +from homeassistant.components.light import ATTR_BRIGHTNESS, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS, LightEntity, ATTR_TRANSITION from homeassistant.const import CONF_NAME import homeassistant.helpers.config_validation as cv from . import DATA_FHEM, device_error_reporting, CONF_FHEM_IDS @@ -29,7 +29,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= async_add_entities([light]) -class FhemLight(Light): +class FhemLight(LightEntity): def __init__(self, connection, name, ids, dimmer=False): self._brightness = None diff --git a/custom_components/fhem/manifest.json b/custom_components/fhem/manifest.json index 1d39a3a..e0922d2 100644 --- a/custom_components/fhem/manifest.json +++ b/custom_components/fhem/manifest.json @@ -5,5 +5,6 @@ "documentation": "", "dependencies": [], "codeowners": ["@mabau"], - "requirements": [] + "requirements": [], + "version": "0.1" } \ No newline at end of file diff --git a/custom_components/fhem/switch.py b/custom_components/fhem/switch.py index b7012cb..193c1d7 100644 --- a/custom_components/fhem/switch.py +++ b/custom_components/fhem/switch.py @@ -3,7 +3,7 @@ import voluptuous as vol import logging -from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA +from homeassistant.components.switch import SwitchEntity, PLATFORM_SCHEMA from homeassistant.const import CONF_NAME import homeassistant.helpers.config_validation as cv from . import DATA_FHEM, device_error_reporting, CONF_FHEM_IDS @@ -24,7 +24,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info= async_add_entities([switch]) -class FhemSwitch(SwitchDevice): +class FhemSwitch(SwitchEntity): def __init__(self, connection, name, ids): self._on = None diff --git a/custom_components/httpsispmctl/manifest.json b/custom_components/httpsispmctl/manifest.json new file mode 100644 index 0000000..50aa4d2 --- /dev/null +++ b/custom_components/httpsispmctl/manifest.json @@ -0,0 +1,10 @@ + +{ + "domain": "httpsispmctl", + "name": "sispmctl integration", + "documentation": "", + "dependencies": [], + "codeowners": ["@mabau"], + "requirements": [], + "version": "0.1" +} \ No newline at end of file diff --git a/custom_components/httpsispmctl/switch.py b/custom_components/httpsispmctl/switch.py index be45b73..e6253b8 100644 --- a/custom_components/httpsispmctl/switch.py +++ b/custom_components/httpsispmctl/switch.py @@ -4,7 +4,7 @@ from collections import defaultdict import homeassistant.helpers.config_validation as cv from homeassistant.helpers import aiohttp_client from homeassistant.const import CONF_HOST, CONF_PORT, CONF_NAME -from homeassistant.components.switch import SwitchDevice, PLATFORM_SCHEMA +from homeassistant.components.switch import SwitchEntity, PLATFORM_SCHEMA from aiohttp import ClientConnectionError @@ -75,7 +75,7 @@ class SispmctlHost: await switch.set_state(on=None, reachable=False) -class HttpSispmctlSwitch(SwitchDevice): +class HttpSispmctlSwitch(SwitchEntity): def __init__(self, basename, number): self._basename = basename self._number = number diff --git a/custom_components/lirc_network/__init__.py b/custom_components/lirc_network/__init__.py index 2ce15cd..db87ae0 100644 --- a/custom_components/lirc_network/__init__.py +++ b/custom_components/lirc_network/__init__.py @@ -34,7 +34,6 @@ async def async_setup(hass, config): connection = LircConnection(hass, config_element) hass.data[DATA_LIRC_NETWORK].append(connection) await connection.start() - _LOGGER.warning("About to return true in async_setup") return True diff --git a/custom_components/lirc_network/manifest.json b/custom_components/lirc_network/manifest.json index a2961a4..24ea04b 100644 --- a/custom_components/lirc_network/manifest.json +++ b/custom_components/lirc_network/manifest.json @@ -4,5 +4,6 @@ "documentation": "", "requirements": [], "dependencies": [], - "codeowners": ["@mabau"] + "codeowners": ["@mabau"], + "version": "0.1" } diff --git a/custom_components/long_click/manifest.json b/custom_components/long_click/manifest.json new file mode 100644 index 0000000..c54f939 --- /dev/null +++ b/custom_components/long_click/manifest.json @@ -0,0 +1,10 @@ + +{ + "domain": "long_click", + "name": "Long click", + "documentation": "", + "dependencies": [], + "codeowners": ["@mabau"], + "requirements": [], + "version": "0.1" +} \ No newline at end of file diff --git a/custom_components/ondilo/__init__.py b/custom_components/ondilo/__init__.py new file mode 100644 index 0000000..62b10a5 --- /dev/null +++ b/custom_components/ondilo/__init__.py @@ -0,0 +1,78 @@ +import asyncio +import logging + +import voluptuous as vol + +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_USERNAME, CONF_PASSWORD +from homeassistant.core import HomeAssistant +from homeassistant.helpers import config_entry_oauth2_flow, config_validation as cv + +from . import config_flow +from .const import DOMAIN, OAUTH2_AUTHORIZE, OAUTH2_TOKEN + +_LOGGER = logging.getLogger(__name__) + +CONFIG_SCHEMA = vol.Schema( + { + DOMAIN: vol.Schema( + { + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + } + ) + }, + extra=vol.ALLOW_EXTRA, +) + +PLATFORMS = ["sensor"] + + +async def async_setup(hass: HomeAssistant, config: dict): + """Set up the ondilo component.""" + hass.data[DOMAIN] = {} + print("Init1") + if DOMAIN not in config: + print("Init early out") + return True + + config_flow.OndiloFlowHandler.async_register_implementation( + hass, + config_entry_oauth2_flow.LocalOAuth2Implementation( + hass, + DOMAIN, + config[DOMAIN][CONF_USERNAME], + config[DOMAIN][CONF_PASSWORD], + OAUTH2_AUTHORIZE, + OAUTH2_TOKEN, + ), + ) + print("init finish") + return True + + +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): + """Set up ondilo from a config entry.""" + implementation = await config_entry_oauth2_flow.async_get_config_entry_implementation( + hass, entry + ) + session = config_entry_oauth2_flow.OAuth2Session(hass, entry, implementation) + hass.data[DOMAIN] = {"session": session} + hass.async_create_task(hass.config_entries.async_forward_entry_setup(entry, "sensor")) + return True + + +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): + """Unload a config entry.""" + unload_ok = all( + await asyncio.gather( + *[ + hass.config_entries.async_forward_entry_unload(entry, component) + for component in PLATFORMS + ] + ) + ) + if unload_ok: + hass.data[DOMAIN] = {} + + return unload_ok diff --git a/custom_components/ondilo/config_flow.py b/custom_components/ondilo/config_flow.py new file mode 100644 index 0000000..0c66be0 --- /dev/null +++ b/custom_components/ondilo/config_flow.py @@ -0,0 +1,35 @@ +"""Config flow for Ondilo.""" +import logging + +from homeassistant import config_entries +from homeassistant.helpers import config_entry_oauth2_flow + +from .const import DOMAIN + +_LOGGER = logging.getLogger(__name__) + + +class OndiloFlowHandler(config_entry_oauth2_flow.AbstractOAuth2FlowHandler, domain=DOMAIN): + """Config flow to handle Ondilo OAuth2 authentication.""" + + DOMAIN = DOMAIN + CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL + + @property + def logger(self) -> logging.Logger: + """Return logger.""" + return logging.getLogger(__name__) + + async def async_step_user(self, user_input=None): + """Handle a flow start.""" + print("async_step_user!!") + if self.hass.config_entries.async_entries(DOMAIN): + print("abort because already setup") + return self.async_abort(reason="already_setup") + print("works!") + return await super().async_step_user(user_input) + + async def async_step_homekit(self, homekit_info): + """Handle HomeKit discovery.""" + print("async_step_homekit!!") + return await self.async_step_user() diff --git a/custom_components/ondilo/const.py b/custom_components/ondilo/const.py new file mode 100644 index 0000000..42f03ae --- /dev/null +++ b/custom_components/ondilo/const.py @@ -0,0 +1,4 @@ +DOMAIN = "ondilo" +OAUTH2_AUTHORIZE = "https://interop.ondilo.com/oauth2/authorize" +OAUTH2_TOKEN = "https://interop.ondilo.com/oauth2/token" +URL_API_PREFIX = "https://interop.ondilo.com/api/customer/v1" diff --git a/custom_components/ondilo/manifest.json b/custom_components/ondilo/manifest.json new file mode 100644 index 0000000..98651de --- /dev/null +++ b/custom_components/ondilo/manifest.json @@ -0,0 +1,10 @@ +{ + "domain": "ondilo", + "name": "Ondilo Pool Monitor", + "documentation": "", + "requirements": [], + "dependencies": [], + "codeowners": ["@mabau"], + "config_flow": true, + "version": "0.1" +} diff --git a/custom_components/ondilo/sensor.py b/custom_components/ondilo/sensor.py new file mode 100644 index 0000000..faab9a9 --- /dev/null +++ b/custom_components/ondilo/sensor.py @@ -0,0 +1,52 @@ + +from .const import DOMAIN, URL_API_PREFIX +from datetime import timedelta +from homeassistant.helpers.entity import Entity +from homeassistant.util import Throttle +import logging + +MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=5) + +_LOGGER = logging.getLogger(__name__) + + +async def api_call(session, url, data={}): + return await session.async_request(method="GET", + url=f"{URL_API_PREFIX}/{url}", + json=data).json() + + +class OndiloData: + def __init__(self, session): + self._session = session + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + async def async_update(self): + pass + + +class PHSensor(Entity): + def __init__(self, data): + self._data = data + + async def async_update(self): + self._data.async_update() + + +class ORPSensor(Entity): + def __init__(self, data): + self._data = data + + async def async_update(self): + self._data.async_update() + + +async def async_setup_entry(hass, entry, async_add_entities): + session = hass.data[DOMAIN]['session'] + res = await api_call(session, "pools") + print(res) + _LOGGER.warn(res) + # data = OndiloData(session) + # get pools + # sensors = [PHSensor(data), ORPSensor(data)] + # async_add_entities(sensors) diff --git a/custom_components/reconnecting_client.py b/custom_components/reconnecting_client.py index c61de2b..889008c 100644 --- a/custom_components/reconnecting_client.py +++ b/custom_components/reconnecting_client.py @@ -1,11 +1,11 @@ import asyncio import logging from homeassistant.const import EVENT_HOMEASSISTANT_STOP -from homeassistant.components.binary_sensor import BinarySensorDevice +from homeassistant.components.binary_sensor import BinarySensorEntity import socket -class IsConnectedSensor(BinarySensorDevice): +class IsConnectedSensor(BinarySensorEntity): def __init__(self, name): self._on = True diff --git a/custom_components/squeezebox_telnet/manifest.json b/custom_components/squeezebox_telnet/manifest.json index 1d5d1c1..2a90807 100644 --- a/custom_components/squeezebox_telnet/manifest.json +++ b/custom_components/squeezebox_telnet/manifest.json @@ -4,5 +4,6 @@ "documentation": "", "requirements": [], "dependencies": [], - "codeowners": ["@mabau"] + "codeowners": ["@mabau"], + "version": "0.1" } diff --git a/custom_components/squeezebox_telnet/media_player.py b/custom_components/squeezebox_telnet/media_player.py index 11c35a7..957f32b 100644 --- a/custom_components/squeezebox_telnet/media_player.py +++ b/custom_components/squeezebox_telnet/media_player.py @@ -6,10 +6,10 @@ import sys from typing import List, Tuple import voluptuous as vol from ..reconnecting_client import ReconnectingClient -from .radio import find_local_radio_url_by_name +from .radio import find_local_radio_url_by_name, fill_station_cache_async from homeassistant.components.media_player import ( - MediaPlayerDevice, PLATFORM_SCHEMA) + MediaPlayerEntity, PLATFORM_SCHEMA) from homeassistant.components.media_player.const import ( ATTR_MEDIA_ENQUEUE, DOMAIN, MEDIA_TYPE_MUSIC, SUPPORT_CLEAR_PLAYLIST, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, @@ -22,6 +22,7 @@ from homeassistant.const import ( STATE_IDLE, STATE_OFF, STATE_PAUSED, STATE_PLAYING) import homeassistant.helpers.config_validation as cv from homeassistant.util.dt import utcnow +from homeassistant.helpers.aiohttp_client import async_get_clientsession _LOGGER = logging.getLogger(__name__) @@ -66,6 +67,8 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the squeezebox platform.""" import socket + + await fill_station_cache_async(async_get_clientsession(hass)) known_servers = hass.data.get(KNOWN_SERVERS) if known_servers is None: @@ -249,7 +252,7 @@ class LogitechMediaServer(ReconnectingClient): _LOGGER.warning("LMS Ignoring line " + line) -class SqueezeBoxDevice(MediaPlayerDevice): +class SqueezeBoxDevice(MediaPlayerEntity): """Representation of a SqueezeBox device.""" def __init__(self, lms, playerid, name, **attributes): diff --git a/custom_components/squeezebox_telnet/radio.py b/custom_components/squeezebox_telnet/radio.py index a8f1662..cd97328 100644 --- a/custom_components/squeezebox_telnet/radio.py +++ b/custom_components/squeezebox_telnet/radio.py @@ -1,7 +1,14 @@ import xml.etree.ElementTree as ET from urllib.request import urlopen +import aiohttp +import asyncio + ompl_radio_browse_url = 'http://opml.radiotime.com/Browse.ashx' +# goto ompl.radiotime with parameter ?c=local and look for your city there then paste id here +query_url = ompl_radio_browse_url + '?id=r100765' + +STATION_CACHE = {} def radio_name_cleanup(radio_name): @@ -17,15 +24,7 @@ def radio_name_cleanup(radio_name): return " ".join(res) -def get_sender_information(queryURL): - """ - Example Query: GET http://opml.radiotime.com/Browse.ashx?partnerId=&serial= - partnerid and serial does not seem to be necessary - so we do not use it here, - """ - xmlfile = urlopen(queryURL) - tree = ET.ElementTree(file=xmlfile) - rootnode = tree.getroot() - +def parse_sender_information(rootnode): result = dict() for node in rootnode.iter('outline'): if 'type' not in node.attrib or node.attrib['type'] != "audio": @@ -39,16 +38,15 @@ def get_sender_information(queryURL): return result -def get_related_radio_stations(stationID): - query_url = ompl_radio_browse_url + '?id=' + stationID - return get_sender_information(query_url) - - def get_local_radio_stations(): - # goto ompl.radiotime with parameter ?c=local and look for your city there then paste id here - query_url = ompl_radio_browse_url + '?id=r100765' - result = get_sender_information(query_url) - return result + """ + Example Query: GET http://opml.radiotime.com/Browse.ashx?partnerId=&serial= + partnerid and serial does not seem to be necessary - so we do not use it here, + """ + xmlfile = urlopen(query_url) + tree = ET.ElementTree(file=xmlfile) + return parse_sender_information(tree.getroot() +) def find_local_radio_url_by_name(search_name): @@ -58,20 +56,24 @@ def find_local_radio_url_by_name(search_name): return search_name # first try: find a station that starts with the search expression - for radio_id, radio in find_local_radio_url_by_name.stations.items(): + for radio_id, radio in STATION_CACHE.items(): if radio['name'].lower().startswith(search_name): return radio['url'] # second try: containment is enough - for radio_id, radio in find_local_radio_url_by_name.stations.items(): + for radio_id, radio in STATION_CACHE.items(): if search_name in radio['name'].lower(): return radio['url'] raise ValueError("Could not find radio station " + search_name) -find_local_radio_url_by_name.stations = get_local_radio_stations() - +async def fill_station_cache_async(client_session): + print("-------- Fill station cache async") + global STATION_CACHE + async with client_session.get(query_url) as resp: + STATION_CACHE = parse_sender_information(ET.fromstring(await resp.text())) + if __name__ == '__main__': print(find_local_radio_url_by_name("B 5 aktuell")) \ No newline at end of file diff --git a/custom_components/sysdweb/binary_sensor.py b/custom_components/sysdweb/binary_sensor.py index 5641aa8..4e815b3 100644 --- a/custom_components/sysdweb/binary_sensor.py +++ b/custom_components/sysdweb/binary_sensor.py @@ -1,12 +1,12 @@ from . import DATA_SYSDWEB import logging -from homeassistant.components.binary_sensor import BinarySensorDevice +from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.helpers import aiohttp_client _LOGGER = logging.getLogger(__name__) -class ServiceStateSensor(BinarySensorDevice): +class ServiceStateSensor(BinarySensorEntity): def __init__(self, name, url, auth): self._on = None diff --git a/custom_components/sysdweb/manifest.json b/custom_components/sysdweb/manifest.json new file mode 100644 index 0000000..c8d3879 --- /dev/null +++ b/custom_components/sysdweb/manifest.json @@ -0,0 +1,10 @@ + +{ + "domain": "sysdweb", + "name": "sysdweg", + "documentation": "", + "dependencies": [], + "codeowners": ["@mabau"], + "requirements": [], + "version": "0.1" +} \ No newline at end of file diff --git a/custom_components/watson_tts/manifest.json b/custom_components/watson_tts/manifest.json index b2a19ec..6e3c8b5 100644 --- a/custom_components/watson_tts/manifest.json +++ b/custom_components/watson_tts/manifest.json @@ -8,5 +8,6 @@ "dependencies": [], "codeowners": [ "@rutkai" - ] + ], + "version": "0.1" }