Skip to content

Commit

Permalink
Increase to version 0.4.2.
Browse files Browse the repository at this point in the history
* Apply suggestions from code review.
* Apply comments from code review.
* Bumped to boschshcpy==0.2.17
  • Loading branch information
tschamm committed May 13, 2021
1 parent 1fd5f8c commit bbfe618
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 89 deletions.
37 changes: 9 additions & 28 deletions custom_components/bosch_shc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from boschshcpy import SHCSession, SHCUniversalSwitch
from boschshcpy.exceptions import SHCAuthenticationError, SHCConnectionError
from homeassistant.components.zeroconf import async_get_instance
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_DEVICE_ID,
ATTR_ID,
Expand Down Expand Up @@ -60,16 +60,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
False,
zeroconf,
)
except SHCAuthenticationError:
_LOGGER.warning("Unable to authenticate on Bosch Smart Home Controller API")
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH},
data=entry.data,
)
)
return False
except SHCAuthenticationError as err:
raise ConfigEntryAuthFailed from err
except SHCConnectionError as err:
raise ConfigEntryNotReady from err

Expand All @@ -86,18 +78,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
device_entry = device_registry.async_get_or_create(
config_entry_id=entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, dr.format_mac(shc_info.unique_id))},
identifiers={(DOMAIN, shc_info.name)},
identifiers={(DOMAIN, shc_info.unique_id)},
manufacturer="Bosch",
name=entry.title,
model="SmartHomeController",
sw_version=shc_info.version,
)
device_id = device_entry.id

for platform in PLATFORMS:
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, platform)
)
hass.config_entries.async_setup_platforms(entry, PLATFORMS)

async def stop_polling(event):
"""Stop polling service."""
Expand Down Expand Up @@ -137,19 +126,11 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
session: SHCSession = hass.data[DOMAIN][entry.entry_id][DATA_SESSION]
session.unsubscribe_scenario_callback()

if hass.data[DOMAIN][entry.entry_id][DATA_POLLING_HANDLER]:
hass.data[DOMAIN][entry.entry_id][DATA_POLLING_HANDLER]()
hass.data[DOMAIN][entry.entry_id].pop(DATA_POLLING_HANDLER)
await hass.async_add_executor_job(session.stop_polling)
hass.data[DOMAIN][entry.entry_id][DATA_POLLING_HANDLER]()
hass.data[DOMAIN][entry.entry_id].pop(DATA_POLLING_HANDLER)
await hass.async_add_executor_job(session.stop_polling)

unload_ok = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(entry, platform)
for platform in PLATFORMS
]
)
)
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/bosch_shc/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
intrusion_system = session.intrusion_system
alarm_control_panel = IntrusionSystemAlarmControlPanel(
device=intrusion_system,
parent_id=session.information.name,
parent_id=session.information.unique_id,
entry_id=config_entry.entry_id,
)
devices.append(alarm_control_panel)
Expand Down
10 changes: 5 additions & 5 deletions custom_components/bosch_shc/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(
ShutterContactSensor(
device=binarysensor,
parent_id=session.information.name,
parent_id=session.information.unique_id,
entry_id=config_entry.entry_id,
)
)
Expand All @@ -64,7 +64,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
MotionDetectionSensor(
hass=hass,
device=binarysensor,
parent_id=session.information.name,
parent_id=session.information.unique_id,
entry_id=config_entry.entry_id,
)
)
Expand All @@ -73,7 +73,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(
SmokeDetectorSensor(
device=binarysensor,
parent_id=session.information.name,
parent_id=session.information.unique_id,
hass=hass,
entry_id=config_entry.entry_id,
)
Expand All @@ -83,7 +83,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(
SmokeDetectionSystemSensor(
device=binarysensor,
parent_id=session.information.name,
parent_id=session.information.unique_id,
hass=hass,
entry_id=config_entry.entry_id,
)
Expand All @@ -93,7 +93,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(
WaterLeakageDetectorSensor(
device=binarysensor,
parent_id=session.information.name,
parent_id=session.information.unique_id,
hass=hass,
entry_id=config_entry.entry_id,
)
Expand Down
2 changes: 1 addition & 1 deletion custom_components/bosch_shc/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(
ClimateControl(
device=climate,
parent_id=session.information.name,
parent_id=session.information.unique_id,
entry_id=config_entry.entry_id,
name=f"Room Climate {session.room(room_id).name}",
)
Expand Down
34 changes: 17 additions & 17 deletions custom_components/bosch_shc/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
import logging
from os import makedirs

import voluptuous as vol
from boschshcpy import SHCRegisterClient, SHCSession
from boschshcpy.exceptions import (
SHCAuthenticationError,
SHCConnectionError,
SHCRegistrationError,
SHCSessionError,
)
import voluptuous as vol

from homeassistant import config_entries, core
from homeassistant.components.zeroconf import async_get_instance
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_TOKEN
Expand Down Expand Up @@ -77,7 +78,6 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Bosch SHC."""

VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL
info = None
host = None
hostname = None
Expand Down Expand Up @@ -123,38 +123,36 @@ async def async_step_credentials(self, user_input=None):
"""Handle the credentials step."""
errors = {}
if user_input is not None:
zeroconf = await async_get_instance(self.hass)
try:
zeroconf = await async_get_instance(self.hass)
result = await self.hass.async_add_executor_job(
create_credentials_and_validate,
self.hass,
self.host,
user_input,
zeroconf,
)
entry_data = {
CONF_SSL_CERTIFICATE: self.hass.config.path(DOMAIN, CONF_SHC_CERT),
CONF_SSL_KEY: self.hass.config.path(DOMAIN, CONF_SHC_KEY),
CONF_HOST: self.host,
CONF_TOKEN: result["token"],
CONF_HOSTNAME: result["token"].split(":", 1)[1],
}
except SHCAuthenticationError:
errors["base"] = "invalid_auth"
except SHCConnectionError:
errors["base"] = "cannot_connect"
except SHCSessionError:
_LOGGER.warning("API call returned non-OK result. Wrong password?")
except SHCSessionError as err:
_LOGGER.warning("Session error: %s", err.message)
errors["base"] = "unknown"
except SHCRegistrationError:
_LOGGER.warning(
"SHC not in pairing mode! Please press the Bosch Smart Home Controller button until LED starts blinking"
)
except SHCRegistrationError as err:
_LOGGER.warning("Registration error: %s", err.message)
errors["base"] = "pairing_failed"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
entry_data = {
CONF_SSL_CERTIFICATE: self.hass.config.path(DOMAIN, CONF_SHC_CERT),
CONF_SSL_KEY: self.hass.config.path(DOMAIN, CONF_SHC_KEY),
CONF_HOST: self.host,
CONF_TOKEN: result["token"],
CONF_HOSTNAME: result["token"].split(":", 1)[1],
}
existing_entry = await self.async_set_unique_id(self.info["unique_id"])
if existing_entry:
self.hass.config_entries.async_update_entry(
Expand All @@ -173,7 +171,9 @@ async def async_step_credentials(self, user_input=None):

schema = vol.Schema(
{
vol.Required(CONF_PASSWORD, default=user_input.get(CONF_PASSWORD)): str,
vol.Required(
CONF_PASSWORD, default=user_input.get(CONF_PASSWORD, "")
): str,
}
)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/bosch_shc/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(
ShutterControlCover(
device=cover,
parent_id=session.information.name,
parent_id=session.information.unique_id,
entry_id=config_entry.entry_id,
)
)
Expand Down
2 changes: 1 addition & 1 deletion custom_components/bosch_shc/device_trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async def get_device_from_id(hass, device_id) -> Tuple[SHCDevice, str]:
return ids, "IDS"

device = dev_registry.async_get_device(
identifiers={(DOMAIN, session.information.name)}, connections=set()
identifiers={(DOMAIN, session.information.unique_id)}, connections=set()
)
if device.id == device_id:
return session, "SHC"
Expand Down
20 changes: 7 additions & 13 deletions custom_components/bosch_shc/entity.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Bosch Smart Home Controller base entity."""
from boschshcpy.device import SHCDevice

from homeassistant.helpers.device_registry import async_get as get_dev_reg
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_registry import async_get as get_ent_reg

from .const import DOMAIN

Expand All @@ -13,21 +13,16 @@ async def async_get_device_id(hass, device_id):
device = dev_registry.async_get_device(
identifiers={(DOMAIN, device_id)}, connections=set()
)
if device is None:
return None
return device.id

return device.id if device is not None else None

async def async_remove_devices(hass, entity, entry_id):
"""Get item that is removed from session."""
ent_registry = get_ent_reg(hass)
if entity.entity_id in ent_registry.entities:
ent_registry.async_remove(entity.entity_id)

dev_registry = get_dev_reg(hass)
device_id = async_get_device_id(hass, entity.device_id)
if device_id is not None:
dev_registry.async_update_device(device_id, remove_config_entry_id=entry_id)
device = dev_registry.async_get_device(
identifiers={(DOMAIN, entity.device_id)}, connections=set()
)
if device is not None:
dev_registry.async_update_device(device.id, remove_config_entry_id=entry_id)


class SHCEntity(Entity):
Expand All @@ -49,7 +44,6 @@ def on_state_changed():
def update_entity_information():
if self._device.deleted:
self.hass.add_job(async_remove_devices(self.hass, self, self._entry_id))

else:
self.schedule_update_ha_state()

Expand Down
2 changes: 1 addition & 1 deletion custom_components/bosch_shc/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
entities.append(
LightSwitch(
device=light,
parent_id=session.information.name,
parent_id=session.information.unique_id,
entry_id=config_entry.entry_id,
)
)
Expand Down
4 changes: 2 additions & 2 deletions custom_components/bosch_shc/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"name": "Bosch SHC",
"config_flow": true,
"documentation": "https://github.com/tschamm/boschshc-hass/blob/master/README.md",
"requirements": ["boschshcpy==0.2.16.dev1"],
"version": "0.4.2.dev0",
"requirements": ["boschshcpy==0.2.17"],
"version": "0.4.2",
"zeroconf": [
{"type": "_http._tcp.local.", "name": "bosch shc*"}
],
Expand Down
Loading

0 comments on commit bbfe618

Please sign in to comment.