Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
ebb8a6b
Update plugwise async, config_flow and multi entity
CoMPaTech Apr 4, 2020
3dbeb36
Update battery percentage
CoMPaTech Apr 4, 2020
2504d0b
Fix yamllint on services
CoMPaTech Apr 5, 2020
90b796b
Fix yamllint on services
CoMPaTech Apr 5, 2020
d0e5950
Fix formatting for pyupgrade
CoMPaTech Apr 5, 2020
6c1e2c3
Update homeassistant/components/plugwise/__init__.py
CoMPaTech Apr 7, 2020
afd3c4d
Add try/except on setup
CoMPaTech Apr 7, 2020
54ced3a
Bump module version, battery version and valve position
CoMPaTech Apr 8, 2020
cebbbfe
Removing sensor, switch, water_heater for later (child) PRs
CoMPaTech Apr 8, 2020
e3b6d91
Catchup and version bump
CoMPaTech Apr 21, 2020
d882b14
Remove title from strings.json
CoMPaTech Apr 21, 2020
fd4648d
Readd already reviewd await try/except
CoMPaTech Apr 21, 2020
db60de7
Readd already reviewed config_flow
CoMPaTech Apr 21, 2020
d1c2c05
Fix pylint
CoMPaTech Apr 21, 2020
ec74d9d
Fix per 0.109 translations
CoMPaTech Apr 25, 2020
fe1d2d3
Remove unused import from merge
CoMPaTech Apr 25, 2020
132b17d
Translations and config_flow, module version bump with required changes
Apr 27, 2020
1276e97
Fix requirements
Apr 27, 2020
b716df4
Fix pylint
Apr 27, 2020
9d90fed
Update homeassistant/components/plugwise/__init__.py
CoMPaTech May 10, 2020
1dba1fe
Update homeassistant/components/plugwise/__init__.py
CoMPaTech May 10, 2020
d457c94
Update homeassistant/components/plugwise/__init__.py
CoMPaTech May 10, 2020
2ee78a5
Include configentrynotready on import
CoMPaTech May 10, 2020
e198002
Update __init__.py
CoMPaTech May 10, 2020
43eb7b8
Update plugwise async, config_flow and multi entity
CoMPaTech Apr 4, 2020
248ad61
Update battery percentage
CoMPaTech Apr 4, 2020
f615f23
Fix yamllint on services
CoMPaTech Apr 5, 2020
a5b1e0a
Fix yamllint on services
CoMPaTech Apr 5, 2020
862a73b
Bump module version
CoMPaTech Apr 8, 2020
166fb7b
Bump module version, battery version and valve position
CoMPaTech Apr 8, 2020
96eeedb
Removing sensor, switch, water_heater for later (child) PRs
CoMPaTech Apr 8, 2020
ee63fe8
Catchup and version bump
CoMPaTech Apr 21, 2020
8e9a761
Remove title from strings.json
CoMPaTech Apr 21, 2020
afa966d
Fix pylint
CoMPaTech Apr 21, 2020
cf85755
Fix per 0.109 translations
CoMPaTech Apr 25, 2020
2038be2
Translations and config_flow, module version bump with required changes
Apr 27, 2020
6c9513f
Fix requirements
Apr 27, 2020
7de418b
Fix pylint
Apr 27, 2020
8e1f840
DataUpdateCoordinator and comment non-PR-platforms
May 12, 2020
605ddc7
Fix reqs
May 12, 2020
dcac991
Rename devices variable in favor of entities
May 12, 2020
928f581
Rework updates with DataUpdateCoordinator
May 13, 2020
ffd487e
Peer review
May 13, 2020
1af2f38
Peer review second part
May 13, 2020
0c71710
Cleanup comments and redundant code
May 14, 2020
2ca0684
Added required config_flow test
May 14, 2020
0c40b9c
Peer review third part
May 14, 2020
6e95aed
Update service was replaced by DataUpdateCoordinator
May 17, 2020
a42dd55
Corrected testing, version bump for InvalidAuth, move uniq_id
May 20, 2020
585a8f6
Remove according to review
May 20, 2020
e231ce8
Await connect (py38)
May 20, 2020
4acdcb6
Remove unneccesary code
May 20, 2020
756486c
Show only when multiple
May 20, 2020
20de695
Improve config_flow, rename consts
May 26, 2020
44ba32b
Update homeassistant/components/plugwise/climate.py
CoMPaTech May 26, 2020
d4631e8
Update homeassistant/components/plugwise/climate.py
CoMPaTech May 26, 2020
e65b0af
Process review comments
May 26, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,8 @@ omit =
homeassistant/components/plaato/*
homeassistant/components/plex/media_player.py
homeassistant/components/plex/sensor.py
homeassistant/components/plugwise/*
homeassistant/components/plugwise/__init__.py
homeassistant/components/plugwise/climate.py
homeassistant/components/plum_lightpad/*
homeassistant/components/pocketcasts/sensor.py
homeassistant/components/point/*
Expand Down
2 changes: 1 addition & 1 deletion CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ homeassistant/components/pilight/* @trekky12
homeassistant/components/plaato/* @JohNan
homeassistant/components/plant/* @ChristianKuehnel
homeassistant/components/plex/* @jjlawren
homeassistant/components/plugwise/* @laetificat @CoMPaTech @bouwew
homeassistant/components/plugwise/* @CoMPaTech @bouwew
homeassistant/components/plum_lightpad/* @ColinHarrington
homeassistant/components/point/* @fredrike
homeassistant/components/powerwall/* @bdraco @jrester
Expand Down
162 changes: 161 additions & 1 deletion homeassistant/components/plugwise/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,161 @@
"""Plugwise Climate (current only Anna) component for Home Assistant."""
"""Plugwise platform for Home Assistant Core."""

import asyncio
from datetime import timedelta
import logging

from Plugwise_Smile.Smile import Smile
import async_timeout
import voluptuous as vol

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .const import DOMAIN

CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA)

_LOGGER = logging.getLogger(__name__)

ALL_PLATFORMS = ["climate"]


async def async_setup(hass: HomeAssistant, config: dict):
"""Set up the Plugwise platform."""
return True


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Plugwise Smiles from a config entry."""
websession = async_get_clientsession(hass, verify_ssl=False)
api = Smile(
host=entry.data["host"], password=entry.data["password"], websession=websession
)

try:
connected = await api.connect()

Comment thread
CoMPaTech marked this conversation as resolved.
if not connected:
_LOGGER.error("Unable to connect to Smile")
raise ConfigEntryNotReady

except Smile.InvalidAuthentication:
_LOGGER.error("Invalid Smile ID")
return False

except Smile.PlugwiseError:
_LOGGER.error("Error while communicating to device")
raise ConfigEntryNotReady

except asyncio.TimeoutError:
_LOGGER.error("Timeout while connecting to Smile")
raise ConfigEntryNotReady

if api.smile_type == "power":
update_interval = timedelta(seconds=10)
else:
update_interval = timedelta(seconds=60)

async def async_update_data():
"""Update data via API endpoint."""
try:
async with async_timeout.timeout(10):
await api.full_update_device()
return True
except Smile.XMLDataMissingError:
raise UpdateFailed("Smile update failed")

coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name="Smile",
update_method=async_update_data,
update_interval=update_interval,
)

await coordinator.async_refresh()

if not coordinator.last_update_success:
raise ConfigEntryNotReady

api.get_all_devices()
Comment thread
bdraco marked this conversation as resolved.

hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
"api": api,
"coordinator": coordinator,
}

device_registry = await dr.async_get_registry(hass)
device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
identifiers={(DOMAIN, api.gateway_id)},
manufacturer="Plugwise",
name=entry.title,
model=f"Smile {api.smile_name}",
sw_version=api.smile_version[0],
)

for component in ALL_PLATFORMS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, component)
)

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 ALL_PLATFORMS
]
)
)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)

return unload_ok


class SmileGateway(Entity):
"""Represent Smile Gateway."""

def __init__(self, api, coordinator):
"""Initialise the sensor."""
self._api = api
self._coordinator = coordinator
self._unique_id = None

@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id

@property
def should_poll(self):
"""Return False, updates are controlled via coordinator."""
return False

@property
def available(self):
"""Return True if entity is available."""
return self._coordinator.last_update_success

async def async_added_to_hass(self):
"""Subscribe to updates."""
self.async_on_remove(self._coordinator.async_add_listener(self._process_data))

def _process_data(self):
"""Interpret and process API data."""
raise NotImplementedError

async def async_update(self):
"""Update the entity."""
await self._coordinator.async_request_refresh()
Loading