def _mydevolo(conf: dict) -> Mydevolo: """Configure mydevolo.""" mydevolo = Mydevolo() mydevolo.user = conf[CONF_USERNAME] mydevolo.password = conf[CONF_PASSWORD] mydevolo.url = conf[CONF_MYDEVOLO] return mydevolo
def configure_mydevolo(conf: dict) -> Mydevolo: """Configure mydevolo.""" mydevolo = Mydevolo() mydevolo.user = conf[CONF_USERNAME] mydevolo.password = conf[CONF_PASSWORD] mydevolo.url = conf.get(CONF_MYDEVOLO, DEFAULT_MYDEVOLO) return mydevolo
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool: """Set up the devolo account from a config entry.""" conf = entry.data hass.data.setdefault(DOMAIN, {}) mydevolo = Mydevolo() mydevolo.user = conf[CONF_USERNAME] mydevolo.password = conf[CONF_PASSWORD] mydevolo.url = conf[CONF_MYDEVOLO] credentials_valid = await hass.async_add_executor_job( mydevolo.credentials_valid) if not credentials_valid: return False if await hass.async_add_executor_job(mydevolo.maintenance): raise ConfigEntryNotReady gateway_ids = await hass.async_add_executor_job(mydevolo.get_gateway_ids) try: zeroconf_instance = await zeroconf.async_get_instance(hass) hass.data[DOMAIN][entry.entry_id] = {"gateways": [], "listener": None} for gateway_id in gateway_ids: hass.data[DOMAIN][entry.entry_id]["gateways"].append( await hass.async_add_executor_job( partial( HomeControl, gateway_id=gateway_id, mydevolo_instance=mydevolo, zeroconf_instance=zeroconf_instance, ))) except (ConnectionError, GatewayOfflineError) as err: raise ConfigEntryNotReady from err for platform in PLATFORMS: hass.async_create_task( hass.config_entries.async_forward_entry_setup(entry, platform)) def shutdown(event): for gateway in hass.data[DOMAIN][entry.entry_id]["gateways"]: gateway.websocket_disconnect( f"websocket disconnect requested by {EVENT_HOMEASSISTANT_STOP}" ) # Listen when EVENT_HOMEASSISTANT_STOP is fired hass.data[DOMAIN][entry.entry_id]["listener"] = hass.bus.async_listen_once( EVENT_HOMEASSISTANT_STOP, shutdown) return True
def dummy_device(key: str) -> Zwave: """ Represent a dummy device in tests, where we do not care about the device type :param key: Key to look up in test_data.json :return: Dummy device """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data['devices'][key]) device.binary_switch_property = {} device.binary_switch_property[ f"devolo.BinarySwitch:{test_data['devices'][key]['uid']}"] = BinarySwitchProperty( element_uid= f"devolo.BinarySwitch:{test_data['devices'][key]['uid']}", setter=lambda uid, state: None, state=test_data['devices'][key]['state'], enabled=test_data['devices'][key]['guiEnabled']) device.settings_property = {} device.settings_property["general_device_settings"] = SettingsProperty( element_uid=f"gds.{test_data['devices'][key]['uid']}", setter=lambda uid, state: None, icon=test_data['devices'][key]['icon'], name=test_data['devices'][key]['itemName'], zone_id=test_data['devices'][key]['zoneId'], zones=test_data.get("gateway").get("zones")) return device
def humidity_sensor_device(device_uid: str) -> Zwave: """ Represent a humidity sensor :param device_uid: Device UID this mock shall have :return: Humidity sensor device """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data.get("devices").get("humidity")) gateway = MockGateway(test_data.get("gateway").get("id"), mydevolo=mydevolo) session = requests.Session() device.binary_sensor_property = {} device.humidity_bar_property = {} device.multi_level_sensor_property = {} device.settings_property = {} element_uid = f'devolo.DewpointSensor:{device_uid}' device.multi_level_sensor_property[element_uid] = \ MultiLevelSensorProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=element_uid, value=test_data.get("devices").get("humidity").get("dewpoint")) element_uid = f'devolo.MildewSensor:{device_uid}' device.binary_sensor_property[element_uid] = \ BinarySensorProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=element_uid, state=test_data.get("devices").get("humidity").get("mildew")) element_uid = f'devolo.HumidityBar:{device_uid}' device.humidity_bar_property[element_uid] = \ HumidityBarProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=element_uid, zone=test_data.get("devices").get("humidity").get("zone"), value=test_data.get("devices").get("humidity").get("value")) device.settings_property["general_device_settings"] = \ SettingsProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f'gds.{test_data.get("devices").get("humidity").get("uid")}', icon=test_data.get("devices").get("humidity").get("icon"), name=test_data.get("devices").get("humidity").get("itemName"), zone_id=test_data.get("devices").get("humidity").get("zoneId")) return device
def shutter(device_uid: str) -> Zwave: """ Represent a shutter in tests :param device_uid: Device UID this mock shall have :return: Metering Plug device """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data['devices']['blinds']) device.multi_level_switch_property = {} device.settings_property = {} device.multi_level_switch_property[f'devolo.Blinds:{device_uid}'] = MultiLevelSwitchProperty( element_uid=f"devolo.Blinds:{device_uid}", setter=lambda uid, state: None, value=test_data['devices']['blinds']['value'], max=test_data['devices']['blinds']['max'], min=test_data['devices']['blinds']['min']) device.settings_property['i2'] = SettingsProperty(element_uid=f"bas.{device_uid}", setter=lambda uid, state: None, value=test_data['devices']['blinds']['i2']) device.settings_property["general_device_settings"] = SettingsProperty(element_uid=f'gds.{device_uid}', setter=lambda uid, state: None, icon=test_data['devices']['blinds']['icon'], name=test_data['devices']['blinds']['itemName'], zone_id=test_data['devices']['blinds']['zoneId'], zones=test_data['gateway']['zones']) device.settings_property["automatic_calibration"] = SettingsProperty( element_uid=f'acs.{device_uid}', setter=lambda uid, state: None, calibration_status=test_data['devices']['blinds']['calibrationStatus'] == 2) device.settings_property["movement_direction"] = SettingsProperty( element_uid=f'bss.{device_uid}', setter=lambda uid, state: None, direction=not bool(test_data['devices']['blinds']['movement_direction'])) device.settings_property["shutter_duration"] = SettingsProperty( element_uid=f'mss.{device_uid}', setter=lambda uid, state: None, shutter_duration=test_data['devices']['blinds']['shutter_duration']) return device
def __init__(self): file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) self._mydevolo = Mydevolo() self._session = Session() self._zeroconf = None self.gateway = MockGateway(test_data['gateway']['id'], self._mydevolo) super().__init__()
async def async_step_user(self, user_input=None): """Handle a flow initiated by the user.""" if self.show_advanced_options: self.data_schema = { vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str, vol.Required(CONF_MYDEVOLO): str, vol.Required(CONF_HOMECONTROL): str, } if user_input is None: return self._show_form(user_input) user = user_input[CONF_USERNAME] password = user_input[CONF_PASSWORD] try: mydevolo = Mydevolo.get_instance() except SyntaxError: mydevolo = Mydevolo() mydevolo.user = user mydevolo.password = password if self.show_advanced_options: mydevolo.url = user_input[CONF_MYDEVOLO] mydevolo.mprm = user_input[CONF_HOMECONTROL] else: mydevolo.url = DEFAULT_MYDEVOLO mydevolo.mprm = DEFAULT_MPRM credentials_valid = await self.hass.async_add_executor_job( mydevolo.credentials_valid) if not credentials_valid: return self._show_form({"base": "invalid_credentials"}) _LOGGER.debug("Credentials valid") gateway_ids = await self.hass.async_add_executor_job( mydevolo.get_gateway_ids) await self.async_set_unique_id(gateway_ids[0]) self._abort_if_unique_id_configured() return self.async_create_entry( title="devolo Home Control", data={ CONF_PASSWORD: password, CONF_USERNAME: user, CONF_MYDEVOLO: mydevolo.url, CONF_HOMECONTROL: mydevolo.mprm, }, )
def siren(device_uid: str) -> Zwave: """ Represent a siren in tests :param device_uid: Device UID this mock shall have :return: Siren device """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data['devices']['siren']) gateway = MockGateway(test_data['gateway']['id'], mydevolo=mydevolo) session = requests.Session() device.multi_level_switch_property = {} device.multi_level_switch_property[f'devolo.SirenMultiLevelSwitch:{device_uid}'] = \ MultiLevelSwitchProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f"devolo.SirenMultiLevelSwitch:{device_uid}", state=test_data['devices']['siren']['state']) device.settings_property = {} device.settings_property['muted'] = \ SettingsProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f"bas.{device_uid}", value=test_data['devices']['siren']['muted']) device.settings_property["general_device_settings"] = \ SettingsProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f"gds.{device_uid}", icon=test_data['devices']['siren']['icon'], name=test_data['devices']['siren']['itemName'], zone_id=test_data['devices']['siren']['zoneId']) device.settings_property["tone"] = \ SettingsProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f"mss.{device_uid}", value=test_data['devices']['siren']['properties']['value']) return device
def multi_level_sensor_device(device_uid: str) -> Zwave: """ Represent a Multi Level Sensor :param device_uid: Device UID this mock shall have :return: Multi Level Sensor device """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data.get("devices").get("sensor")) device.binary_sensor_property = {} device.multi_level_sensor_property = {} device.settings_property = {} element_uid = f"devolo.BinarySensor:{device_uid}" device.binary_sensor_property[element_uid] = BinarySensorProperty( element_uid=element_uid, state=test_data.get("devices").get("sensor").get("state")) element_uid = f"devolo.MultiLevelSensor:{device_uid}#MultilevelSensor(1)" device.multi_level_sensor_property[element_uid] = MultiLevelSensorProperty( element_uid=element_uid, value=test_data.get("devices").get("sensor").get("value"), unit=test_data.get("devices").get("sensor").get("unit")) device.settings_property['temperature_report'] = SettingsProperty( element_uid=f"trs.{device_uid}", setter=lambda uid, state: True, temp_report=test_data.get("devices").get("sensor").get("temp_report")) device.settings_property['motion_sensitivity'] = SettingsProperty( element_uid=f"mss.{device_uid}", setter=lambda uid, state: True, motion_sensitivity=test_data.get("devices").get("sensor").get( "motion_sensitivity")) device.settings_property["general_device_settings"] = SettingsProperty( element_uid=f'gds.{device_uid}', setter=lambda uid, state: None, icon=test_data.get("devices").get("sensor").get("icon"), name=test_data.get("devices").get("sensor").get("itemName"), zone_id=test_data.get("devices").get("sensor").get("zoneId"), zones=test_data.get("gateway").get("zones")) return device
def remote_control(device_uid: str) -> Zwave: """ Represent a remote control in tests. :param device_uid: Device UID this mock shall have :return: Remote Control """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data['devices']['remote']) gateway = MockGateway(test_data['gateway']['id'], mydevolo=mydevolo) session = requests.Session() device.remote_control_property = {} device.settings_property = {} device.remote_control_property[f'devolo.RemoteControl:{device_uid}'] = \ RemoteControlProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f'devolo.RemoteControl:{device_uid}', key_count=test_data['devices']['remote']['key_count'], key_pressed=0) device.settings_property["general_device_settings"] = \ SettingsProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f'gds.{device_uid}', icon=test_data['devices']['remote']['icon'], name=test_data['devices']['remote']['itemName'], zone_id=test_data['devices']['remote']['zoneId']) device.settings_property["switch_type"] = \ SettingsProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f'sts.{device_uid}', value=test_data['devices']['remote']['key_count']) return device
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool: """Set up the devolo account from a config entry.""" conf = entry.data hass.data.setdefault(DOMAIN, {}) try: mydevolo = Mydevolo.get_instance() except SyntaxError: mydevolo = Mydevolo() mydevolo.user = conf[CONF_USERNAME] mydevolo.password = conf[CONF_PASSWORD] mydevolo.url = conf[CONF_MYDEVOLO] mydevolo.mprm = conf[CONF_HOMECONTROL] credentials_valid = await hass.async_add_executor_job(mydevolo.credentials_valid) if not credentials_valid: return False if await hass.async_add_executor_job(mydevolo.maintenance): raise ConfigEntryNotReady gateway_ids = await hass.async_add_executor_job(mydevolo.get_gateway_ids) gateway_id = gateway_ids[0] mprm_url = mydevolo.mprm try: hass.data[DOMAIN]["homecontrol"] = await hass.async_add_executor_job( partial(HomeControl, gateway_id=gateway_id, url=mprm_url) ) except ConnectionError as err: raise ConfigEntryNotReady from err for platform in PLATFORMS: hass.async_create_task( hass.config_entries.async_forward_entry_setup(entry, platform) ) def shutdown(event): hass.data[DOMAIN]["homecontrol"].websocket_disconnect( f"websocket disconnect requested by {EVENT_HOMEASSISTANT_STOP}" ) # Listen when EVENT_HOMEASSISTANT_STOP is fired hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, shutdown) return True
def multi_level_switch_device(device_uid: str) -> Zwave: """ Represent a multi level switch device in tests :param device_uid: Device UID this mock shall have :return: Multi level switch device """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data.get("devices").get("multi_level_switch")) gateway = MockGateway(test_data.get("gateway").get("id"), mydevolo=mydevolo) session = requests.Session() device.multi_level_switch_property = {} device.settings_property = {} device.multi_level_switch_property[f'devolo.MultiLevelSwitch:{device_uid}'] = \ MultiLevelSwitchProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f"devolo.MultiLevelSwitch:{device_uid}", value=test_data.get("devices").get("multi_level_switch").get("value"), max=test_data.get("devices").get("multi_level_switch").get("max"), min=test_data.get("devices").get("multi_level_switch").get("min")) device.settings_property["general_device_settings"] = \ SettingsProperty(gateway=gateway, session=session, mydevolo=mydevolo, element_uid=f'gds.{device_uid}', icon=test_data.get("devices").get("multi_level_switch").get("icon"), name=test_data.get("devices").get("multi_level_switch").get("itemName"), zone_id=test_data.get("devices").get("multi_level_switch").get("zoneId")) return device
def remote_control(device_uid: str) -> Zwave: """ Represent a remote control in tests. :param device_uid: Device UID this mock shall have :return: Remote Control """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data['devices']['remote']) device.remote_control_property = {} device.settings_property = {} device.remote_control_property[ f'devolo.RemoteControl:{device_uid}'] = RemoteControlProperty( element_uid=f"devolo.RemoteControl:{device_uid}", setter=lambda uid, state: True, key_count=test_data['devices']['remote']['key_count'], key_pressed=0) device.settings_property["general_device_settings"] = SettingsProperty( element_uid=f"gds.{device_uid}", setter=lambda uid, state: None, icon=test_data['devices']['remote']['icon'], name=test_data['devices']['remote']['itemName'], zone_id=test_data['devices']['remote']['zoneId'], zones=test_data['gateway']['zones']) device.settings_property["switch_type"] = SettingsProperty( element_uid=f"sts.{device_uid}", setter=lambda uid, state: None, value=test_data['devices']['remote']['key_count']) return device
def multi_level_switch_device(device_uid: str) -> Zwave: """ Represent a multi level switch device in tests :param device_uid: Device UID this mock shall have :return: Multi level switch device """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data.get("devices").get("multi_level_switch")) device.multi_level_switch_property = {} device.settings_property = {} device.multi_level_switch_property[ f'devolo.MultiLevelSwitch:{device_uid}'] = MultiLevelSwitchProperty( element_uid=f"devolo.MultiLevelSwitch:{device_uid}", setter=lambda uid, state: None, value=test_data.get("devices").get("multi_level_switch").get( "value"), max=test_data.get("devices").get("multi_level_switch").get("max"), min=test_data.get("devices").get("multi_level_switch").get("min")) device.settings_property['general_device_settings'] = SettingsProperty( element_uid=f"gds.{device_uid}", setter=lambda uid, state: None, icon=test_data.get("devices").get("multi_level_switch").get("icon"), name=test_data.get("devices").get("multi_level_switch").get( "itemName"), zone_id=test_data.get("devices").get("multi_level_switch").get( "zoneId"), zones=test_data.get("gateway").get("zones")) return device
async def async_step_user(self, user_input=None): """Handle a flow initiated by the user.""" if self.show_advanced_options: self.data_schema = { vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str, vol.Required(CONF_MYDEVOLO, default=DEFAULT_MYDEVOLO): str, } if user_input is None: return self._show_form(user_input) user = user_input[CONF_USERNAME] password = user_input[CONF_PASSWORD] mydevolo = Mydevolo() mydevolo.user = user mydevolo.password = password if self.show_advanced_options: mydevolo.url = user_input[CONF_MYDEVOLO] else: mydevolo.url = DEFAULT_MYDEVOLO credentials_valid = await self.hass.async_add_executor_job( mydevolo.credentials_valid ) if not credentials_valid: return self._show_form({"base": "invalid_auth"}) _LOGGER.debug("Credentials valid") uuid = await self.hass.async_add_executor_job(mydevolo.uuid) await self.async_set_unique_id(uuid) self._abort_if_unique_id_configured() return self.async_create_entry( title="devolo Home Control", data={ CONF_PASSWORD: password, CONF_USERNAME: user, CONF_MYDEVOLO: mydevolo.url, }, )
def mydevolo(request): """ Create real mydevolo object with static test data. """ mydevolo = Mydevolo() mydevolo._uuid = request.cls.user.get("uuid") yield mydevolo
from devolo_home_control_api.homecontrol import HomeControl from devolo_home_control_api.mydevolo import Mydevolo logging.basicConfig(level=logging.INFO, format="%(asctime)s %(name)s %(levelname)s: %(message)s") user = "******" password = "******" class Subscriber: def __init__(self, name): self.name = name def update(self, message): print(f'{self.name} got message "{message}"') mydevolo = Mydevolo() mydevolo.user = user mydevolo.password = password gateway_id = mydevolo.get_gateway_ids()[0] homecontrol = HomeControl(gateway_id=gateway_id, mydevolo_instance=mydevolo) for device in homecontrol.devices: homecontrol.devices[device].subscriber = Subscriber(device) homecontrol.publisher.register(device, homecontrol.devices[device].subscriber)
def test_call_WrongUrlError(self): mydevolo = Mydevolo() with pytest.raises(WrongUrlError): mydevolo._call("test")
def metering_plug(device_uid: str) -> Zwave: """ Represent a metering plug in tests :param device_uid: Device UID this mock shall have :return: Metering Plug device """ file = pathlib.Path(__file__).parent / ".." / "test_data.json" with file.open("r") as fh: test_data = json.load(fh) mydevolo = Mydevolo() device = Zwave(mydevolo_instance=mydevolo, **test_data['devices']['mains']['properties']) device.binary_switch_property = {} device.consumption_property = {} device.multi_level_sensor_property = {} device.settings_property = {} device.binary_switch_property[f'devolo.BinarySwitch:{device_uid}'] = BinarySwitchProperty( element_uid=f"devolo.BinarySwitch:{device_uid}", setter=lambda uid, state: None, state=test_data['devices']['mains']['properties']['state'], enabled=test_data['devices']['mains']['properties']['guiEnabled']) device.consumption_property[f'devolo.Meter:{device_uid}'] = ConsumptionProperty( element_uid=f"devolo.Meter:{device_uid}", setter=lambda uid, state: None, current=test_data['devices']['mains']['properties']['current_consumption'], total=test_data['devices']['mains']['properties']['total_consumption'], total_since=test_data['devices']['mains']['properties']['sinceTime']) device.multi_level_sensor_property[f'devolo.VoltageMultiLevelSensor:{device_uid}'] = \ MultiLevelSensorProperty(element_uid=f"devolo.VoltageMultiLevelSensor:{device_uid}", current=test_data['devices']['mains']['properties']['voltage']) device.settings_property["param_changed"] = SettingsProperty(element_uid=f"cps.{device_uid}", setter=lambda uid, state: None) device.settings_property['general_device_settings'] = SettingsProperty( element_uid=f"gds.{device_uid}", setter=lambda uid, state: True, events_enabled=test_data['devices']['mains']['properties']['eventsEnabled'], icon=test_data['devices']['mains']['properties']['icon'], name=test_data['devices']['mains']['properties']['itemName'], zone_id=test_data['devices']['mains']['properties']['zoneId'], zones=test_data.get("gateway").get("zones")) device.settings_property["led"] = SettingsProperty(element_uid=f"lis.{device_uid}", setter=lambda uid, state: True, led_setting=test_data['devices']['mains']['properties']['led_setting']) device.settings_property["protection"] = \ SettingsProperty(element_uid=f"ps.{device_uid}", setter=lambda uid, state: True, local_switching=test_data['devices']['mains']['properties']['local_switch'], remote_switching=test_data['devices']['mains']['properties']['remote_switch']) device.settings_property['flash_mode'] = SettingsProperty(element_uid=f"mas.{device_uid}", setter=lambda uid, state: None, valus=test_data['devices']['mains']['flashMode']) return device
def test_call_WrongCredentialsError(self): mydevolo = Mydevolo() with pytest.raises(WrongCredentialsError): mydevolo._call("test")