def setup(hass, config): """Establish connection with Daikin.""" def discovery_dispatch(service, discovery_info): """Dispatcher for Daikin discovery events.""" host = discovery_info.get('ip') if daikin_api_setup(hass, host) is None: return for component in COMPONENT_TYPES: load_platform(hass, component, DOMAIN, discovery_info, config) discovery.listen(hass, SERVICE_DAIKIN, discovery_dispatch) for host in config.get(DOMAIN, {}).get(CONF_HOSTS, []): if daikin_api_setup(hass, host) is None: continue discovery_info = { 'ip': host, CONF_MONITORED_CONDITIONS: config[DOMAIN][CONF_MONITORED_CONDITIONS] } load_platform(hass, 'sensor', DOMAIN, discovery_info, config) return True
def setup(hass, base_config): """Set up the Lutron component.""" from pylutron import Lutron hass.data[LUTRON_CONTROLLER] = None hass.data[LUTRON_DEVICES] = {'light': []} config = base_config.get(DOMAIN) hass.data[LUTRON_CONTROLLER] = Lutron( config['lutron_host'], config['lutron_user'], config['lutron_password'] ) hass.data[LUTRON_CONTROLLER].load_xml_db() hass.data[LUTRON_CONTROLLER].connect() _LOGGER.info("Connected to Main Repeater at %s", config['lutron_host']) # Sort our devices into types for area in hass.data[LUTRON_CONTROLLER].areas: for output in area.outputs: hass.data[LUTRON_DEVICES]['light'].append((area.name, output)) for component in ('light',): discovery.load_platform(hass, component, DOMAIN, None, base_config) return True
def setup(hass, config): """Set up the Meteo-France component.""" hass.data[DATA_METEO_FRANCE] = {} for location in config[DOMAIN]: city = location[CONF_CITY] from meteofrance.client import meteofranceClient, meteofranceError try: client = meteofranceClient(city) except meteofranceError as exp: _LOGGER.error(exp) return client.need_rain_forecast = bool( CONF_MONITORED_CONDITIONS in location and 'next_rain' in location[CONF_MONITORED_CONDITIONS]) hass.data[DATA_METEO_FRANCE][city] = MeteoFranceUpdater(client) hass.data[DATA_METEO_FRANCE][city].update() if CONF_MONITORED_CONDITIONS in location: monitored_conditions = location[CONF_MONITORED_CONDITIONS] load_platform( hass, 'sensor', DOMAIN, { CONF_CITY: city, CONF_MONITORED_CONDITIONS: monitored_conditions}, config) load_platform(hass, 'weather', DOMAIN, {CONF_CITY: city}, config) return True
def setup(hass, config): """Establish connection to MAX! Cube.""" from maxcube.connection import MaxCubeConnection from maxcube.cube import MaxCube if DATA_KEY not in hass.data: hass.data[DATA_KEY] = {} connection_failed = 0 gateways = config[DOMAIN][CONF_GATEWAYS] for gateway in gateways: host = gateway[CONF_HOST] port = gateway[CONF_PORT] scan_interval = gateway[CONF_SCAN_INTERVAL].total_seconds() try: cube = MaxCube(MaxCubeConnection(host, port)) hass.data[DATA_KEY][host] = MaxCubeHandle(cube, scan_interval) except timeout as ex: _LOGGER.error("Unable to connect to Max!Cube gateway: %s", str(ex)) hass.components.persistent_notification.create( 'Error: {}<br />' 'You will need to restart Home Assistant after fixing.' ''.format(ex), title=NOTIFICATION_TITLE, notification_id=NOTIFICATION_ID) connection_failed += 1 if connection_failed >= len(gateways): return False load_platform(hass, 'climate', DOMAIN, {}, config) load_platform(hass, 'binary_sensor', DOMAIN, {}, config) return True
def accessory_setup(self): """Handle setup of a HomeKit accessory.""" # pylint: disable=import-error from homekit.model.services import ServicesTypes from homekit.exceptions import AccessoryDisconnectedError self.pairing.pairing_data['AccessoryIP'] = self.host self.pairing.pairing_data['AccessoryPort'] = self.port try: data = self.pairing.list_accessories_and_characteristics() except AccessoryDisconnectedError: call_later( self.hass, RETRY_INTERVAL, lambda _: self.accessory_setup()) return for accessory in data: aid = accessory['aid'] for service in accessory['services']: iid = service['iid'] if (aid, iid) in self.entities: # Don't add the same entity again continue devtype = ServicesTypes.get_short(service['type']) _LOGGER.debug("Found %s", devtype) service_info = {'serial': self.hkid, 'aid': aid, 'iid': service['iid'], 'model': self.model, 'device-type': devtype} component = HOMEKIT_ACCESSORY_DISPATCH.get(devtype, None) if component is not None: discovery.load_platform(self.hass, component, DOMAIN, service_info, self.config)
def setup(hass, config): """Set up Abode component.""" from abodepy.exceptions import AbodeException conf = config[DOMAIN] username = conf.get(CONF_USERNAME) password = conf.get(CONF_PASSWORD) name = conf.get(CONF_NAME) polling = conf.get(CONF_POLLING) exclude = conf.get(CONF_EXCLUDE) lights = conf.get(CONF_LIGHTS) try: cache = hass.config.path(DEFAULT_CACHEDB) hass.data[DOMAIN] = AbodeSystem( username, password, cache, name, polling, exclude, lights) except (AbodeException, ConnectTimeout, HTTPError) as ex: _LOGGER.error("Unable to connect to Abode: %s", str(ex)) hass.components.persistent_notification.create( 'Error: {}<br />' 'You will need to restart hass after fixing.' ''.format(ex), title=NOTIFICATION_TITLE, notification_id=NOTIFICATION_ID) return False setup_hass_services(hass) setup_hass_events(hass) setup_abode_events(hass) for platform in ABODE_PLATFORMS: discovery.load_platform(hass, platform, DOMAIN, {}, config) return True
def setup(hass, config): """Setup SleepIQ. Will automatically load sensor components to support devices discovered on the account. """ # pylint: disable=global-statement global DATA from sleepyq import Sleepyq username = config[DOMAIN][CONF_USERNAME] password = config[DOMAIN][CONF_PASSWORD] client = Sleepyq(username, password) try: DATA = SleepIQData(client) DATA.update() except HTTPError: message = """ SleepIQ failed to login, double check your username and password" """ _LOGGER.error(message) return False discovery.load_platform(hass, "sensor", DOMAIN, {}, config) discovery.load_platform(hass, "binary_sensor", DOMAIN, {}, config) return True
def value_added(node, value): """Called when a value is added to a node on the network.""" for (component, generic_device_class, specific_device_class, command_class, value_type, value_genre) in DISCOVERY_COMPONENTS: _LOGGER.debug("Component=%s Node_id=%s query start", component, node.node_id) if node.generic not in generic_device_class and \ None not in generic_device_class: _LOGGER.debug("node.generic %s not None and in \ generic_device_class %s", node.generic, generic_device_class) continue if node.specific not in specific_device_class and \ None not in specific_device_class: _LOGGER.debug("node.specific %s is not None and in \ specific_device_class %s", node.specific, specific_device_class) continue if value.command_class not in command_class and \ None not in command_class: _LOGGER.debug("value.command_class %s is not None \ and in command_class %s", value.command_class, command_class) continue if value_type != value.type and value_type is not None: _LOGGER.debug("value.type %s != value_type %s", value.type, value_type) continue if value_genre != value.genre and value_genre is not None: _LOGGER.debug("value.genre %s != value_genre %s", value.genre, value_genre) continue # Configure node _LOGGER.debug("Adding Node_id=%s Generic_command_class=%s, \ Specific_command_class=%s, \ Command_class=%s, Value type=%s, \ Genre=%s", node.node_id, node.generic, node.specific, value.command_class, value.type, value.genre) name = "{}.{}".format(component, _object_id(value)) node_config = customize.get(name, {}) polling_intensity = convert( node_config.get(CONF_POLLING_INTENSITY), int) if polling_intensity: value.enable_poll(polling_intensity) else: value.disable_poll() discovery.load_platform(hass, component, DOMAIN, { ATTR_NODE_ID: node.node_id, ATTR_VALUE_ID: value.value_id, }, config)
def setup(hass, config): """Set up the eBusd component.""" conf = config[DOMAIN] name = conf[CONF_NAME] circuit = conf[CONF_CIRCUIT] monitored_conditions = conf.get(CONF_MONITORED_CONDITIONS) server_address = ( conf.get(CONF_HOST), conf.get(CONF_PORT)) try: _LOGGER.debug("Ebusd component setup started") import ebusdpy ebusdpy.init(server_address) hass.data[DOMAIN] = EbusdData(server_address, circuit) sensor_config = { CONF_MONITORED_CONDITIONS: monitored_conditions, 'client_name': name, 'sensor_types': SENSOR_TYPES[circuit] } load_platform(hass, 'sensor', DOMAIN, sensor_config, config) hass.services.register( DOMAIN, SERVICE_EBUSD_WRITE, hass.data[DOMAIN].write) _LOGGER.debug("Ebusd component setup completed") return True except (socket.timeout, socket.error): return False
def save_data(self): """Save the device configuration to `hass.data`.""" sensors = {} for entity in self.config.get(CONF_BINARY_SENSORS) or []: if CONF_ZONE in entity: pin = ZONE_TO_PIN[entity[CONF_ZONE]] else: pin = entity[CONF_PIN] sensors[pin] = { CONF_TYPE: entity[CONF_TYPE], CONF_NAME: entity.get(CONF_NAME, 'Konnected {} Zone {}'.format( self.device_id[6:], PIN_TO_ZONE[pin])), CONF_INVERSE: entity.get(CONF_INVERSE), ATTR_STATE: None } _LOGGER.debug('Set up sensor %s (initial state: %s)', sensors[pin].get('name'), sensors[pin].get(ATTR_STATE)) actuators = [] for entity in self.config.get(CONF_SWITCHES) or []: if 'zone' in entity: pin = ZONE_TO_PIN[entity['zone']] else: pin = entity['pin'] act = { CONF_PIN: pin, CONF_NAME: entity.get( CONF_NAME, 'Konnected {} Actuator {}'.format( self.device_id[6:], PIN_TO_ZONE[pin])), ATTR_STATE: None, CONF_ACTIVATION: entity[CONF_ACTIVATION], CONF_MOMENTARY: entity.get(CONF_MOMENTARY), CONF_PAUSE: entity.get(CONF_PAUSE), CONF_REPEAT: entity.get(CONF_REPEAT)} actuators.append(act) _LOGGER.debug('Set up actuator %s', act) device_data = { CONF_BINARY_SENSORS: sensors, CONF_SWITCHES: actuators, CONF_BLINK: self.config.get(CONF_BLINK), CONF_DISCOVERY: self.config.get(CONF_DISCOVERY) } if CONF_DEVICES not in self.hass.data[DOMAIN]: self.hass.data[DOMAIN][CONF_DEVICES] = {} _LOGGER.debug('Storing data in hass.data[%s][%s][%s]: %s', DOMAIN, CONF_DEVICES, self.device_id, device_data) self.hass.data[DOMAIN][CONF_DEVICES][self.device_id] = device_data discovery.load_platform( self.hass, 'binary_sensor', DOMAIN, {'device_id': self.device_id}, self.hass_config) discovery.load_platform( self.hass, 'switch', DOMAIN, {'device_id': self.device_id}, self.hass_config)
def setup(hass, base_config): """Set up the Lutron component.""" from pylutron import Lutron hass.data[LUTRON_CONTROLLER] = None hass.data[LUTRON_DEVICES] = {'light': [], 'cover': []} config = base_config.get(DOMAIN) hass.data[LUTRON_CONTROLLER] = Lutron( config[CONF_HOST], config[CONF_USERNAME], config[CONF_PASSWORD]) hass.data[LUTRON_CONTROLLER].load_xml_db() hass.data[LUTRON_CONTROLLER].connect() _LOGGER.info("Connected to main repeater at %s", config[CONF_HOST]) # Sort our devices into types for area in hass.data[LUTRON_CONTROLLER].areas: for output in area.outputs: if output.type == 'SYSTEM_SHADE': hass.data[LUTRON_DEVICES]['cover'].append((area.name, output)) else: hass.data[LUTRON_DEVICES]['light'].append((area.name, output)) for component in ('light', 'cover'): discovery.load_platform(hass, component, DOMAIN, None, base_config) return True
def test_platform(self, mock_setup_component): """Test discover platform method.""" calls = [] @callback def platform_callback(platform, info): """Platform callback method.""" calls.append((platform, info)) discovery.listen_platform(self.hass, 'test_component', platform_callback) discovery.load_platform(self.hass, 'test_component', 'test_platform', 'discovery info') self.hass.block_till_done() assert mock_setup_component.called assert mock_setup_component.call_args[0] == \ (self.hass, 'test_component', None) self.hass.block_till_done() discovery.load_platform(self.hass, 'test_component_2', 'test_platform', 'discovery info') self.hass.block_till_done() assert len(calls) == 1 assert calls[0] == ('test_platform', 'discovery info') self.hass.bus.fire(discovery.EVENT_PLATFORM_DISCOVERED, { discovery.ATTR_SERVICE: discovery.EVENT_LOAD_PLATFORM.format('test_component') }) self.hass.block_till_done() assert len(calls) == 1
def setup(hass, config): """Set up the Dyson parent component.""" _LOGGER.info("Creating new Dyson component") if DYSON_DEVICES not in hass.data: hass.data[DYSON_DEVICES] = [] from libpurecoollink.dyson import DysonAccount dyson_account = DysonAccount(config[DOMAIN].get(CONF_USERNAME), config[DOMAIN].get(CONF_PASSWORD), config[DOMAIN].get(CONF_LANGUAGE)) logged = dyson_account.login() timeout = config[DOMAIN].get(CONF_TIMEOUT) retry = config[DOMAIN].get(CONF_RETRY) if not logged: _LOGGER.error("Not connected to Dyson account. Unable to add devices") return False _LOGGER.info("Connected to Dyson account") dyson_devices = dyson_account.devices() if CONF_DEVICES in config[DOMAIN] and config[DOMAIN].get(CONF_DEVICES): configured_devices = config[DOMAIN].get(CONF_DEVICES) for device in configured_devices: dyson_device = next((d for d in dyson_devices if d.serial == device["device_id"]), None) if dyson_device: connected = dyson_device.connect(None, device["device_ip"], timeout, retry) if connected: _LOGGER.info("Connected to device %s", dyson_device) hass.data[DYSON_DEVICES].append(dyson_device) else: _LOGGER.warning("Unable to connect to device %s", dyson_device) else: _LOGGER.warning( "Unable to find device %s in Dyson account", device["device_id"]) else: # Not yet reliable for device in dyson_devices: _LOGGER.info("Trying to connect to device %s with timeout=%i " "and retry=%i", device, timeout, retry) connected = device.connect(None, None, timeout, retry) if connected: _LOGGER.info("Connected to device %s", device) hass.data[DYSON_DEVICES].append(device) else: _LOGGER.warning("Unable to connect to device %s", device) # Start fan/sensors components if hass.data[DYSON_DEVICES]: _LOGGER.debug("Starting sensor/fan components") discovery.load_platform(hass, "sensor", DOMAIN, {}, config) discovery.load_platform(hass, "fan", DOMAIN, {}, config) return True
def setup(hass, config): """Set up the Verisure component.""" import verisure global HUB HUB = VerisureHub(config[DOMAIN], verisure) if not HUB.login(): return False hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, lambda event: HUB.logout()) HUB.update_overview() for component in ('sensor', 'switch', 'alarm_control_panel', 'lock', 'camera', 'binary_sensor'): discovery.load_platform(hass, component, DOMAIN, {}, config) descriptions = conf_util.load_yaml_config_file( os.path.join(os.path.dirname(__file__), 'services.yaml')) def capture_smartcam(service): """Capture a new picture from a smartcam.""" device_id = service.data.get(ATTR_DEVICE_SERIAL) HUB.smartcam_capture(device_id) _LOGGER.debug("Capturing new image from %s", ATTR_DEVICE_SERIAL) hass.services.register(DOMAIN, SERVICE_CAPTURE_SMARTCAM, capture_smartcam, descriptions[DOMAIN][SERVICE_CAPTURE_SMARTCAM], schema=CAPTURE_IMAGE_SCHEMA) return True
def imp_discover(json): """Discover new devices.""" dev_per_domain = {} for key, val in json.items(): if key in all_devices: continue prop_name, _, agent_id = key.partition('@') imp_domain, _, display_name = prop_name.partition('_') if imp_domain not in defs: continue cls, hass_domain = defs[imp_domain] url = IMPURL.format(agent_id) all_devices[key] = cls(url, display_name, prop_name, val) # Store in dev per domain... used to add_devices if hass_domain not in dev_per_domain: dev_per_domain[hass_domain] = [] dev_per_domain[hass_domain].append(all_devices[key]) for dom, val in dev_per_domain.items(): key = '{}.{}'.format(DOMAIN, dom) hass.data[key] = val load_platform(hass, dom, 'generic', {'add_devices': key})
def setup(hass, config): """Setup the Wink component.""" logger = logging.getLogger(__name__) if not validate_config(config, {DOMAIN: [CONF_ACCESS_TOKEN]}, logger): return False import pywink from pubnub import Pubnub pywink.set_bearer_token(config[DOMAIN][CONF_ACCESS_TOKEN]) global SUBSCRIPTION_HANDLER SUBSCRIPTION_HANDLER = Pubnub("N/A", pywink.get_subscription_key(), ssl_on=True) SUBSCRIPTION_HANDLER.set_heartbeat(120) # Load components for the devices in the Wink that we support for component_name, func_exists in ( ('light', pywink.get_bulbs), ('switch', lambda: pywink.get_switches or pywink.get_sirens or pywink.get_powerstrip_outlets), ('binary_sensor', pywink.get_sensors), ('sensor', lambda: pywink.get_sensors or pywink.get_eggtrays), ('lock', pywink.get_locks), ('rollershutter', pywink.get_shades), ('garage_door', pywink.get_garage_doors)): if func_exists(): discovery.load_platform(hass, component_name, DOMAIN, {}, config) return True
def setup(hass, config): """Setup the Wink component.""" import pywink user_agent = config[DOMAIN][CONF_USER_AGENT] if user_agent: pywink.set_user_agent(user_agent) from pubnub import Pubnub access_token = config[DOMAIN].get(CONF_ACCESS_TOKEN) if access_token: pywink.set_bearer_token(access_token) else: email = config[DOMAIN][CONF_EMAIL] password = config[DOMAIN][CONF_PASSWORD] client_id = config[DOMAIN]['client_id'] client_secret = config[DOMAIN]['client_secret'] pywink.set_wink_credentials(email, password, client_id, client_secret) global SUBSCRIPTION_HANDLER SUBSCRIPTION_HANDLER = Pubnub( 'N/A', pywink.get_subscription_key(), ssl_on=True) SUBSCRIPTION_HANDLER.set_heartbeat(120) # Load components for the devices in Wink that we support for component in WINK_COMPONENTS: discovery.load_platform(hass, component, DOMAIN, {}, config) return True
def setup(hass, config): """Set up Eufy devices.""" import lakeside if CONF_USERNAME in config[DOMAIN] and CONF_PASSWORD in config[DOMAIN]: data = lakeside.get_devices(config[DOMAIN][CONF_USERNAME], config[DOMAIN][CONF_PASSWORD]) for device in data: kind = device['type'] if kind not in EUFY_DISPATCH: continue discovery.load_platform(hass, EUFY_DISPATCH[kind], DOMAIN, device, config) for device_info in config[DOMAIN][CONF_DEVICES]: kind = device_info['type'] if kind not in EUFY_DISPATCH: continue device = {} device['address'] = device_info['address'] device['code'] = device_info['access_token'] device['type'] = device_info['type'] device['name'] = device_info['name'] discovery.load_platform(hass, EUFY_DISPATCH[kind], DOMAIN, device, config) return True
def setup(hass, config): """Setup the iOS component.""" # pylint: disable=global-statement, import-error global CONFIG_FILE global CONFIG_FILE_PATH CONFIG_FILE_PATH = hass.config.path(CONFIGURATION_FILE) CONFIG_FILE = _load_config(CONFIG_FILE_PATH) if CONFIG_FILE == {}: CONFIG_FILE[ATTR_DEVICES] = {} # Notify needs to have discovery # notify_config = {"notify": {CONF_PLATFORM: "ios"}} # bootstrap.setup_component(hass, "notify", notify_config) discovery.load_platform(hass, "sensor", DOMAIN, {}, config) hass.http.register_view(iOSIdentifyDeviceView) app_config = config.get(DOMAIN, {}) hass.http.register_view(iOSPushConfigView(app_config.get(CONF_PUSH, {}))) return True
def setup(hass, config): """Setup Insteon Hub component. This will automatically import associated lights. """ _LOGGER.warning('Component disabled at request from Insteon. ' 'For more information: https://goo.gl/zLJaic') return False # pylint: disable=unreachable import insteon username = config[DOMAIN][CONF_USERNAME] password = config[DOMAIN][CONF_PASSWORD] api_key = config[DOMAIN][CONF_API_KEY] global INSTEON INSTEON = insteon.Insteon(username, password, api_key) if INSTEON is None: _LOGGER.error("Could not connect to Insteon service") return False discovery.load_platform(hass, 'light', DOMAIN, {}, config) return True
def autosetup_ihc_products(hass: HomeAssistantType, config, ihc_controller): """Auto setup of IHC products from the ihc project file.""" project_xml = ihc_controller.get_project() if not project_xml: _LOGGER.error("Unable to read project from ihc controller.") return False project = xml.etree.ElementTree.fromstring(project_xml) # if an auto setup file exist in the configuration it will override yaml_path = hass.config.path(AUTO_SETUP_YAML) if not os.path.isfile(yaml_path): yaml_path = os.path.join(os.path.dirname(__file__), AUTO_SETUP_YAML) yaml = load_yaml_config_file(yaml_path) try: auto_setup_conf = AUTO_SETUP_SCHEMA(yaml) except vol.Invalid as exception: _LOGGER.error("Invalid IHC auto setup data: %s", exception) return False groups = project.findall('.//group') for component in IHC_PLATFORMS: component_setup = auto_setup_conf[component] discovery_info = get_discovery_info(component_setup, groups) if discovery_info: discovery.load_platform(hass, component, DOMAIN, discovery_info, config) return True
def setup(hass, hass_config): """Set up global ECoalController instance same for sensors and switches.""" from ecoaliface.simple import ECoalController conf = hass_config[DOMAIN] host = conf[CONF_HOST] username = conf[CONF_USERNAME] passwd = conf[CONF_PASSWORD] # Creating ECoalController instance makes HTTP request to controller. ecoal_contr = ECoalController(host, username, passwd) if ecoal_contr.version is None: # Wrong credentials nor network config _LOGGER.error("Unable to read controller status from %s@%s" " (wrong host/credentials)", username, host, ) return False _LOGGER.debug("Detected controller version: %r @%s", ecoal_contr.version, host, ) hass.data[DATA_ECOAL_BOILER] = ecoal_contr # Setup switches switches = conf[CONF_SWITCHES][CONF_MONITORED_CONDITIONS] load_platform(hass, 'switch', DOMAIN, switches, hass_config) # Setup temp sensors sensors = conf[CONF_SENSORS][CONF_MONITORED_CONDITIONS] load_platform(hass, 'sensor', DOMAIN, sensors, hass_config) return True
def setup(hass, config): """Use config values to set up a function enabling status retrieval.""" conf = config[DOMAIN] username = conf.get(CONF_USERNAME) password = conf.get(CONF_PASSWORD) name = conf.get(CONF_NAME) driver = conf.get(CONF_DRIVER) import myusps try: cookie = hass.config.path(COOKIE) cache = hass.config.path(CACHE) session = myusps.get_session(username, password, cookie_path=cookie, cache_path=cache, driver=driver) except myusps.USPSError: _LOGGER.exception('Could not connect to My USPS') return False hass.data[DATA_USPS] = USPSData(session, name) for component in USPS_TYPE: discovery.load_platform(hass, component, DOMAIN, {}, config) return True
def _system_callback_handler(hass, config, src, *args): """Callback handler.""" if src == 'newDevices': _LOGGER.debug("newDevices with: %s", args) # pylint: disable=unused-variable (interface_id, dev_descriptions) = args proxy = interface_id.split('-')[-1] # device support active? if not hass.data[DATA_DEVINIT][proxy]: return ## # Get list of all keys of the devices (ignoring channels) key_dict = {} for dev in dev_descriptions: key_dict[dev['ADDRESS'].split(':')[0]] = True ## # remove device they allready init by HA tmp_devs = key_dict.copy() for dev in tmp_devs: if dev in hass.data[DATA_STORE]: del key_dict[dev] else: hass.data[DATA_STORE].append(dev) # Register EVENTS # Search all device with a EVENTNODE that include data bound_event_callback = partial(_hm_event_handler, hass, proxy) for dev in key_dict: hmdevice = hass.data[DATA_HOMEMATIC].devices[proxy].get(dev) # have events? if len(hmdevice.EVENTNODE) > 0: _LOGGER.debug("Register Events from %s", dev) hmdevice.setEventCallback(callback=bound_event_callback, bequeath=True) # If configuration allows autodetection of devices, # all devices not configured are added. if key_dict: for component_name, discovery_type in ( ('switch', DISCOVER_SWITCHES), ('light', DISCOVER_LIGHTS), ('cover', DISCOVER_COVER), ('binary_sensor', DISCOVER_BINARY_SENSORS), ('sensor', DISCOVER_SENSORS), ('climate', DISCOVER_CLIMATE)): # Get all devices of a specific type found_devices = _get_devices( hass, discovery_type, key_dict, proxy) # When devices of this type are found # they are setup in HA and an event is fired if found_devices: # Fire discovery event discovery.load_platform(hass, component_name, DOMAIN, { ATTR_DISCOVER_DEVICES: found_devices }, config)
def setup(hass, config): """Set up the Hive Component.""" from pyhiveapi import Pyhiveapi session = HiveSession() session.core = Pyhiveapi() username = config[DOMAIN][CONF_USERNAME] password = config[DOMAIN][CONF_PASSWORD] update_interval = config[DOMAIN][CONF_SCAN_INTERVAL] devicelist = session.core.initialise_api( username, password, update_interval) if devicelist is None: _LOGGER.error("Hive API initialization failed") return False session.sensor = Pyhiveapi.Sensor() session.heating = Pyhiveapi.Heating() session.hotwater = Pyhiveapi.Hotwater() session.light = Pyhiveapi.Light() session.switch = Pyhiveapi.Switch() session.weather = Pyhiveapi.Weather() session.attributes = Pyhiveapi.Attributes() hass.data[DATA_HIVE] = session for ha_type, hive_type in DEVICETYPES.items(): for key, devices in devicelist.items(): if key == hive_type: for hivedevice in devices: load_platform(hass, ha_type, DOMAIN, hivedevice, config) return True
def get_manual_configuration( hass, config, conf, ihc_controller, controller_id): """Get manual configuration for IHC devices.""" for component in IHC_PLATFORMS: discovery_info = {} if component in conf: component_setup = conf.get(component) for sensor_cfg in component_setup: name = sensor_cfg[CONF_NAME] device = { 'ihc_id': sensor_cfg[CONF_ID], 'ctrl_id': controller_id, 'product': { 'name': name, 'note': sensor_cfg.get(CONF_NOTE) or '', 'position': sensor_cfg.get(CONF_POSITION) or ''}, 'product_cfg': { 'type': sensor_cfg.get(CONF_TYPE), 'inverting': sensor_cfg.get(CONF_INVERTING), 'off_id': sensor_cfg.get(CONF_OFF_ID), 'on_id': sensor_cfg.get(CONF_ON_ID), 'dimmable': sensor_cfg.get(CONF_DIMMABLE), 'unit_of_measurement': sensor_cfg.get( CONF_UNIT_OF_MEASUREMENT) } } discovery_info[name] = device if discovery_info: discovery.load_platform( hass, component, DOMAIN, discovery_info, config)
def discover(device_id, component): """Discover the component.""" discovery.load_platform(self._hass, component, DOMAIN, [device_id], self._config)
def setup(hass, base_config): """Start Homeworks controller.""" from pyhomeworks.pyhomeworks import Homeworks def hw_callback(msg_type, values): """Dispatch state changes.""" _LOGGER.debug('callback: %s, %s', msg_type, values) addr = values[0] signal = ENTITY_SIGNAL.format(addr) dispatcher_send(hass, signal, msg_type, values) config = base_config.get(DOMAIN) controller = Homeworks(config[CONF_HOST], config[CONF_PORT], hw_callback) hass.data[HOMEWORKS_CONTROLLER] = controller def cleanup(event): controller.close() hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, cleanup) dimmers = config[CONF_DIMMERS] load_platform(hass, 'light', DOMAIN, {CONF_DIMMERS: dimmers}, base_config) for key_config in config[CONF_KEYPADS]: addr = key_config[CONF_ADDR] name = key_config[CONF_NAME] HomeworksKeypadEvent(hass, addr, name) return True
def setup(hass, config): """Set up the Coinbase component. Will automatically setup sensors to support wallets discovered on the network. """ api_key = config[DOMAIN].get(CONF_API_KEY) api_secret = config[DOMAIN].get(CONF_API_SECRET) exchange_currencies = config[DOMAIN].get(CONF_EXCHANGE_CURRENCIES) hass.data[DATA_COINBASE] = coinbase_data = CoinbaseData( api_key, api_secret) if not hasattr(coinbase_data, 'accounts'): return False for account in coinbase_data.accounts.data: load_platform(hass, 'sensor', DOMAIN, {'account': account}, config) for currency in exchange_currencies: if currency not in coinbase_data.exchange_rates.rates: _LOGGER.warning("Currency %s not found", currency) continue native = coinbase_data.exchange_rates.currency load_platform(hass, 'sensor', DOMAIN, {'native_currency': native, 'exchange_currency': currency}, config) return True
def accessory_setup(self): """Handle setup of a HomeKit accessory.""" # pylint: disable=import-error import homekit self.controllerkey, self.accessorykey = \ homekit.get_session_keys(self.conn, self.pairing_data) self.securecon = homekit.SecureHttp(self.conn.sock, self.accessorykey, self.controllerkey) response = self.securecon.get('/accessories') data = json.loads(response.read().decode()) for accessory in data['accessories']: serial = get_serial(accessory) if serial in self.hass.data[KNOWN_ACCESSORIES]: continue self.hass.data[KNOWN_ACCESSORIES][serial] = self aid = accessory['aid'] for service in accessory['services']: service_info = {'serial': serial, 'aid': aid, 'iid': service['iid']} devtype = homekit.ServicesTypes.get_short(service['type']) _LOGGER.debug("Found %s", devtype) component = HOMEKIT_ACCESSORY_DISPATCH.get(devtype, None) if component is not None: discovery.load_platform(self.hass, component, DOMAIN, service_info, self.config)
def setup(hass, config): """Set up the Dyson parent component.""" _LOGGER.info("Creating new Dyson component") if DYSON_DEVICES not in hass.data: hass.data[DYSON_DEVICES] = [] from libpurecoollink.dyson import DysonAccount dyson_account = DysonAccount(config[DOMAIN].get(CONF_USERNAME), config[DOMAIN].get(CONF_PASSWORD), config[DOMAIN].get(CONF_LANGUAGE)) logged = dyson_account.login() timeout = config[DOMAIN].get(CONF_TIMEOUT) retry = config[DOMAIN].get(CONF_RETRY) if not logged: _LOGGER.error("Not connected to Dyson account. Unable to add devices") return False _LOGGER.info("Connected to Dyson account") dyson_devices = dyson_account.devices() if CONF_DEVICES in config[DOMAIN] and config[DOMAIN].get(CONF_DEVICES): configured_devices = config[DOMAIN].get(CONF_DEVICES) for device in configured_devices: dyson_device = next( (d for d in dyson_devices if d.serial == device["device_id"]), None) if dyson_device: connected = dyson_device.connect(None, device["device_ip"], timeout, retry) if connected: _LOGGER.info("Connected to device %s", dyson_device) hass.data[DYSON_DEVICES].append(dyson_device) else: _LOGGER.warning("Unable to connect to device %s", dyson_device) else: _LOGGER.warning("Unable to find device %s in Dyson account", device["device_id"]) else: # Not yet reliable for device in dyson_devices: _LOGGER.info( "Trying to connect to device %s with timeout=%i " "and retry=%i", device, timeout, retry) connected = device.connect(None, None, timeout, retry) if connected: _LOGGER.info("Connected to device %s", device) hass.data[DYSON_DEVICES].append(device) else: _LOGGER.warning("Unable to connect to device %s", device) # Start fan/sensors components if hass.data[DYSON_DEVICES]: _LOGGER.debug("Starting sensor/fan components") discovery.load_platform(hass, "sensor", DOMAIN, {}, config) discovery.load_platform(hass, "fan", DOMAIN, {}, config) return True
def setup(hass, config): """Set up the Ariston Aqua component.""" if DOMAIN not in config: return True hass.data.setdefault(DATA_ARISTONAQUA, {DEVICES: {}, WATER_HEATERS: []}) api_list = [] for device in config[DOMAIN]: name = device[CONF_NAME] username = device[CONF_USERNAME] password = device[CONF_PASSWORD] store_file = device[CONF_STORE_CONFIG_FILES] binary_sensors = device.get(CONF_BINARY_SENSORS) sensors = device.get(CONF_SENSORS) switches = device.get(CONF_SWITCHES) selects = device.get(CONF_SELECTOR) boiler_type = device.get(CONF_TYPE) polling = device.get(CONF_POLLING) logging = device.get(CONF_LOG) path = device.get(CONF_PATH) api = AristonAquaChecker( hass=hass, device=device, name=name, username=username, password=password, store_file=store_file, sensors=sensors, binary_sensors=binary_sensors, switches=switches, selects=selects, boiler_type=boiler_type, polling=polling, logging=logging, path=path ) api_list.append(api) # start api execution api.ariston_api.start() # load all devices hass.data[DATA_ARISTONAQUA][DEVICES][name] = AristonAquaDevice(api, device) discovery.load_platform(hass, WATER_HEATER, DOMAIN, {CONF_NAME: name}, config) if switches: discovery.load_platform( hass, SWITCH, DOMAIN, {CONF_NAME: name, CONF_SWITCHES: switches}, config, ) if selects: discovery.load_platform( hass, SELECT, DOMAIN, {CONF_NAME: name, CONF_SELECTOR: selects}, config, ) if binary_sensors: discovery.load_platform( hass, BINARY_SENSOR, DOMAIN, {CONF_NAME: name, CONF_BINARY_SENSORS: binary_sensors}, config, ) if sensors: discovery.load_platform( hass, SENSOR, DOMAIN, {CONF_NAME: name, CONF_SENSORS: sensors}, config ) def set_ariston_aqua_data(call): """Handle the service call to set the data.""" # Start with mandatory parameter entity_id = call.data.get(ATTR_ENTITY_ID, "") try: domain = entity_id.split(".")[0] except: _LOGGER.warning("Invalid entity_id domain for Ariston Aqua") raise Exception("Invalid entity_id domain for Ariston Aqua") if domain.lower() != "water_heater": _LOGGER.warning("Invalid entity_id domain for Ariston Aqua") raise Exception("Invalid entity_id domain for Ariston Aqua") try: device_id = entity_id.split(".")[1] except: _LOGGER.warning("Invalid entity_id device for Ariston Aqua") raise Exception("Invalid entity_id device for Ariston Aqua") for api in api_list: if api.name.replace(' ', '_').lower() == device_id.lower(): # water_heater entity is found parameter_list = {} data = call.data.get(PARAM_MODE, "") if data != "": parameter_list[PARAM_MODE] = str(data).lower() data = call.data.get(PARAM_ON, "") if data != "": parameter_list[PARAM_ON] = str(data).lower() data = call.data.get(PARAM_REQUIRED_TEMPERATURE, "") if data != "": parameter_list[PARAM_REQUIRED_TEMPERATURE] = str(data).lower() data = call.data.get(PARAM_CLEANSE_TEMPERATURE, "") if data != "": parameter_list[PARAM_CLEANSE_TEMPERATURE] = str(data).lower() data = call.data.get(PARAM_ECO, "") if data != "": parameter_list[PARAM_ECO] = str(data).lower() data = call.data.get(PARAM_REQUIRED_SHOWERS, "") if data != "": parameter_list[PARAM_REQUIRED_SHOWERS] = str(data).lower() _LOGGER.debug("Ariston Aqua device found, data to check and send") api.ariston_api.set_http_data(**parameter_list) return raise Exception("Corresponding entity_id for Ariston Aqua not found") return hass.services.register(DOMAIN, SERVICE_SET_DATA, set_ariston_aqua_data) if not hass.data[DATA_ARISTONAQUA][DEVICES]: return False # Return boolean to indicate that initialization was successful. return True
def event_initialized(event): """Register event initialized on metadatastream here.""" hass = event.device_config('hass') discovery.load_platform(hass, convert(event.topic, 'topic', 'platform'), DOMAIN, {'axis_event': event})
def setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the ISY 994 platform.""" hass.data[ISY994_NODES] = {} for domain in SUPPORTED_DOMAINS: hass.data[ISY994_NODES][domain] = [] hass.data[ISY994_WEATHER] = [] hass.data[ISY994_PROGRAMS] = {} for domain in SUPPORTED_DOMAINS: hass.data[ISY994_PROGRAMS][domain] = [] isy_config = config.get(DOMAIN) user = isy_config.get(CONF_USERNAME) password = isy_config.get(CONF_PASSWORD) tls_version = isy_config.get(CONF_TLS_VER) host = urlparse(isy_config.get(CONF_HOST)) ignore_identifier = isy_config.get(CONF_IGNORE_STRING) sensor_identifier = isy_config.get(CONF_SENSOR_STRING) enable_climate = isy_config.get(CONF_ENABLE_CLIMATE) if host.scheme == 'http': https = False port = host.port or 80 elif host.scheme == 'https': https = True port = host.port or 443 else: _LOGGER.error("isy994 host value in configuration is invalid") return False import PyISY # Connect to ISY controller. isy = PyISY.ISY(host.hostname, port, username=user, password=password, use_https=https, tls_ver=tls_version, log=_LOGGER) if not isy.connected: return False _categorize_nodes(hass, isy.nodes, ignore_identifier, sensor_identifier) _categorize_programs(hass, isy.programs) if enable_climate and isy.configuration.get('Weather Information'): _categorize_weather(hass, isy.climate) def stop(event: object) -> None: """Stop ISY auto updates.""" isy.auto_update = False # Listen for HA stop to disconnect. hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop) # Load platforms for the devices in the ISY controller that we support. for component in SUPPORTED_DOMAINS: discovery.load_platform(hass, component, DOMAIN, {}, config) isy.auto_update = True return True
def setup(hass, config): """Set up the Xiaomi component.""" gateways = [] interface = 'any' discovery_retry = 3 if DOMAIN in config: gateways = config[DOMAIN][CONF_GATEWAYS] interface = config[DOMAIN][CONF_INTERFACE] discovery_retry = config[DOMAIN][CONF_DISCOVERY_RETRY] async def xiaomi_gw_discovered(service, discovery_info): """Perform action when Xiaomi Gateway device(s) has been found.""" # We don't need to do anything here, the purpose of Home Assistant's # discovery service is to just trigger loading of this # component, and then its own discovery process kicks in. discovery.listen(hass, SERVICE_XIAOMI_GW, xiaomi_gw_discovered) from xiaomi_gateway import XiaomiGatewayDiscovery xiaomi = hass.data[PY_XIAOMI_GATEWAY] = XiaomiGatewayDiscovery( hass.add_job, gateways, interface) _LOGGER.debug("Expecting %s gateways", len(gateways)) for k in range(discovery_retry): _LOGGER.info("Discovering Xiaomi Gateways (Try %s)", k + 1) xiaomi.discover_gateways() if len(xiaomi.gateways) >= len(gateways): break if not xiaomi.gateways: _LOGGER.error("No gateway discovered") return False xiaomi.listen() _LOGGER.debug("Gateways discovered. Listening for broadcasts") for component in [ 'binary_sensor', 'sensor', 'switch', 'light', 'cover', 'lock' ]: discovery.load_platform(hass, component, DOMAIN, {}, config) def stop_xiaomi(event): """Stop Xiaomi Socket.""" _LOGGER.info("Shutting down Xiaomi Hub") xiaomi.stop_listen() hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_xiaomi) def play_ringtone_service(call): """Service to play ringtone through Gateway.""" ring_id = call.data.get(ATTR_RINGTONE_ID) gateway = call.data.get(ATTR_GW_MAC) kwargs = {'mid': ring_id} ring_vol = call.data.get(ATTR_RINGTONE_VOL) if ring_vol is not None: kwargs['vol'] = ring_vol gateway.write_to_hub(gateway.sid, **kwargs) def stop_ringtone_service(call): """Service to stop playing ringtone on Gateway.""" gateway = call.data.get(ATTR_GW_MAC) gateway.write_to_hub(gateway.sid, mid=10000) def add_device_service(call): """Service to add a new sub-device within the next 30 seconds.""" gateway = call.data.get(ATTR_GW_MAC) gateway.write_to_hub(gateway.sid, join_permission='yes') hass.components.persistent_notification.async_create( 'Join permission enabled for 30 seconds! ' 'Please press the pairing button of the new device once.', title='Xiaomi Aqara Gateway') def remove_device_service(call): """Service to remove a sub-device from the gateway.""" device_id = call.data.get(ATTR_DEVICE_ID) gateway = call.data.get(ATTR_GW_MAC) gateway.write_to_hub(gateway.sid, remove_device=device_id) gateway_only_schema = _add_gateway_to_schema(xiaomi, vol.Schema({})) hass.services.register(DOMAIN, SERVICE_PLAY_RINGTONE, play_ringtone_service, schema=_add_gateway_to_schema( xiaomi, SERVICE_SCHEMA_PLAY_RINGTONE)) hass.services.register(DOMAIN, SERVICE_STOP_RINGTONE, stop_ringtone_service, schema=gateway_only_schema) hass.services.register(DOMAIN, SERVICE_ADD_DEVICE, add_device_service, schema=gateway_only_schema) hass.services.register(DOMAIN, SERVICE_REMOVE_DEVICE, remove_device_service, schema=_add_gateway_to_schema( xiaomi, SERVICE_SCHEMA_REMOVE_DEVICE)) return True
def setup(hass, config): """Set up the Amcrest IP Camera component.""" hass.data.setdefault(DATA_AMCREST, {DEVICES: {}, CAMERAS: []}) for device in config[DOMAIN]: name = device[CONF_NAME] username = device[CONF_USERNAME] password = device[CONF_PASSWORD] api = AmcrestChecker( hass, name, device[CONF_HOST], device[CONF_PORT], username, password ) ffmpeg_arguments = device[CONF_FFMPEG_ARGUMENTS] resolution = RESOLUTION_LIST[device[CONF_RESOLUTION]] binary_sensors = device.get(CONF_BINARY_SENSORS) sensors = device.get(CONF_SENSORS) stream_source = device[CONF_STREAM_SOURCE] control_light = device.get(CONF_CONTROL_LIGHT) # currently aiohttp only works with basic authentication # only valid for mjpeg streaming if device[CONF_AUTHENTICATION] == HTTP_BASIC_AUTHENTICATION: authentication = aiohttp.BasicAuth(username, password) else: authentication = None hass.data[DATA_AMCREST][DEVICES][name] = AmcrestDevice( api, authentication, ffmpeg_arguments, stream_source, resolution, control_light, ) discovery.load_platform(hass, CAMERA, DOMAIN, {CONF_NAME: name}, config) event_codes = [] if binary_sensors: discovery.load_platform( hass, BINARY_SENSOR, DOMAIN, {CONF_NAME: name, CONF_BINARY_SENSORS: binary_sensors}, config, ) event_codes = [ BINARY_SENSORS[sensor_type][SENSOR_EVENT_CODE] for sensor_type in binary_sensors if sensor_type not in BINARY_POLLED_SENSORS ] _start_event_monitor(hass, name, api, event_codes) if sensors: discovery.load_platform( hass, SENSOR, DOMAIN, {CONF_NAME: name, CONF_SENSORS: sensors}, config ) if not hass.data[DATA_AMCREST][DEVICES]: return False def have_permission(user, entity_id): return not user or user.permissions.check_entity(entity_id, POLICY_CONTROL) async def async_extract_from_service(call): if call.context.user_id: user = await hass.auth.async_get_user(call.context.user_id) if user is None: raise UnknownUser(context=call.context) else: user = None if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_ALL: # Return all entity_ids user has permission to control. return [ entity_id for entity_id in hass.data[DATA_AMCREST][CAMERAS] if have_permission(user, entity_id) ] if call.data.get(ATTR_ENTITY_ID) == ENTITY_MATCH_NONE: return [] call_ids = await async_extract_entity_ids(hass, call) entity_ids = [] for entity_id in hass.data[DATA_AMCREST][CAMERAS]: if entity_id not in call_ids: continue if not have_permission(user, entity_id): raise Unauthorized( context=call.context, entity_id=entity_id, permission=POLICY_CONTROL ) entity_ids.append(entity_id) return entity_ids async def async_service_handler(call): args = [] for arg in CAMERA_SERVICES[call.service][2]: args.append(call.data[arg]) for entity_id in await async_extract_from_service(call): async_dispatcher_send(hass, service_signal(call.service, entity_id), *args) for service, params in CAMERA_SERVICES.items(): hass.services.register(DOMAIN, service, async_service_handler, params[0]) return True
async def async_setup(hass, config): """Qwiskswitch component setup.""" # Add cmd's to in /&listen packets will fire events # By default only buttons of type [TOGGLE,SCENE EXE,LEVEL] cmd_buttons = set(CMD_BUTTONS) for btn in config[DOMAIN][CONF_BUTTON_EVENTS]: cmd_buttons.add(btn) url = config[DOMAIN][CONF_URL] dimmer_adjust = config[DOMAIN][CONF_DIMMER_ADJUST] sensors = config[DOMAIN][CONF_SENSORS] switches = config[DOMAIN][CONF_SWITCHES] def callback_value_changed(_qsd, qsid, _val): """Update entity values based on device change.""" _LOGGER.debug("Dispatch %s (update from devices)", qsid) hass.helpers.dispatcher.async_dispatcher_send(qsid, None) session = async_get_clientsession(hass) qsusb = QSUsb( url=url, dim_adj=dimmer_adjust, session=session, callback_value_changed=callback_value_changed, ) # Discover all devices in QSUSB if not await qsusb.update_from_devices(): return False hass.data[DOMAIN] = qsusb comps = {"switch": [], "light": [], "sensor": [], "binary_sensor": []} try: sensor_ids = [] for sens in sensors: _, _type = SENSORS[sens["type"]] sensor_ids.append(sens["id"]) if _type is bool: comps["binary_sensor"].append(sens) continue comps["sensor"].append(sens) for _key in ("invert", "class"): if _key in sens: _LOGGER.warning( "%s should only be used for binary_sensors: %s", _key, sens) except KeyError: _LOGGER.warning("Sensor validation failed") for qsid, dev in qsusb.devices.items(): if qsid in switches: if dev.qstype != QSType.relay: _LOGGER.warning( "You specified a switch that is not a relay %s", qsid) continue comps["switch"].append(qsid) elif dev.qstype in (QSType.relay, QSType.dimmer): comps["light"].append(qsid) else: _LOGGER.warning("Ignored unknown QSUSB device: %s", dev) continue # Load platforms for comp_name, comp_conf in comps.items(): if comp_conf: load_platform(hass, comp_name, DOMAIN, {DOMAIN: comp_conf}, config) def callback_qs_listen(qspacket): """Typically a button press or update signal.""" # If button pressed, fire a hass event if QS_ID in qspacket: if qspacket.get(QS_CMD, "") in cmd_buttons: hass.bus.async_fire( "qwikswitch.button.{}".format(qspacket[QS_ID]), qspacket) return if qspacket[QS_ID] in sensor_ids: _LOGGER.debug("Dispatch %s ((%s))", qspacket[QS_ID], qspacket) hass.helpers.dispatcher.async_dispatcher_send( qspacket[QS_ID], qspacket) # Update all ha_objects hass.async_add_job(qsusb.update_from_devices) @callback def async_start(_): """Start listening.""" hass.async_add_job(qsusb.listen, callback_qs_listen) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, async_start) @callback def async_stop(_): """Stop the listener.""" hass.data[DOMAIN].stop() hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, async_stop) return True
def sync_devices(call): stick.sync_devices() _LOGGER.warning(call) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config)
def pull_new_devices(call): """Pull new devices added to users Wink account since startup.""" _LOGGER.info("Getting new devices from Wink API") for _component in WINK_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config)
def refresh(call): _LOGGER.warning(call) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config)
def setup(hass, config): """Set up the Amcrest IP Camera component.""" from amcrest import AmcrestCamera if DATA_AMCREST not in hass.data: hass.data[DATA_AMCREST] = {} if DATA_AMCREST_LOCK not in hass.data: hass.data[DATA_AMCREST_LOCK] = {} amcrest_cams = config[DOMAIN] for device in amcrest_cams: try: camera = AmcrestCamera(device.get(CONF_HOST), device.get(CONF_PORT), device.get(CONF_USERNAME), device.get(CONF_PASSWORD), retries_connection=1, timeout_protocol=5).camera # pylint: disable=pointless-statement camera.current_time except RequestException as ex: _LOGGER.error("Unable to connect to Amcrest camera: %s", str(ex)) hass.components.persistent_notification.create( 'Error: {}<br />' 'You will need to restart hass after fixing.' ''.format(ex), title=NOTIFICATION_TITLE, notification_id=NOTIFICATION_ID) continue ffmpeg_arguments = device.get(CONF_FFMPEG_ARGUMENTS) name = device.get(CONF_NAME) resolution = RESOLUTION_LIST[device.get(CONF_RESOLUTION)] binary_sensors = device.get(CONF_BINARY_SENSORS) sensors = device.get(CONF_SENSORS) switches = device.get(CONF_SWITCHES) stream_source = STREAM_SOURCE_LIST[device.get(CONF_STREAM_SOURCE)] username = device.get(CONF_USERNAME) password = device.get(CONF_PASSWORD) # currently aiohttp only works with basic authentication # only valid for mjpeg streaming if username is not None and password is not None: if device.get(CONF_AUTHENTICATION) == HTTP_BASIC_AUTHENTICATION: authentication = aiohttp.BasicAuth(username, password) else: authentication = None hass.data[DATA_AMCREST][name] = AmcrestDevice( camera, name, authentication, ffmpeg_arguments, stream_source, resolution) hass.data[DATA_AMCREST_LOCK][name] = threading.Lock() discovery.load_platform( hass, 'camera', DOMAIN, { CONF_NAME: name, }, config) if binary_sensors: discovery.load_platform( hass, 'binary_sensor', DOMAIN, { CONF_NAME: name, CONF_BINARY_SENSORS: binary_sensors }, config) if sensors: discovery.load_platform( hass, 'sensor', DOMAIN, { CONF_NAME: name, CONF_SENSORS: sensors, }, config) if switches: discovery.load_platform( hass, 'switch', DOMAIN, { CONF_NAME: name, CONF_SWITCHES: switches }, config) return len(hass.data[DATA_AMCREST]) >= 1
def setup(hass, config): """Setup the Awesome Light platform.""" # Assign configuration variables. The configuration check takes care they are # present. from pyduofern.duofern_stick import DuofernStickThreaded if config.get(DOMAIN) is not None: serial_port = config[DOMAIN].get(CONF_SERIAL_PORT) if serial_port is None: serial_port = "/dev/serial/by-id/usb-Rademacher_DuoFern_USB-Stick_WR04ZFP4-if00-port0" code = config[DOMAIN].get(CONF_CODE, None) if code is None: code = "affe" configfile = config[DOMAIN].get('config_file') hass.data[DOMAIN] = { 'stick': DuofernStickThreaded(serial_port=serial_port, system_code=code, config_file_json=configfile, ephemeral=False), 'devices': {} } hass.data[DOMAIN]['stick'].start() # Setup connection with devices/cloud stick = hass.data["duofern"]['stick'] def start_pairing(call): _LOGGER.warning("start pairing") hass.data[DOMAIN]['stick'].pair(call.data.get('timeout', 60)) def start_unpairing(call): _LOGGER.warning("start pairing") hass.data[DOMAIN]['stick'].unpair(call.data.get('timeout', 60)) hass.services.register(DOMAIN, 'start_pairing', start_pairing, PAIRING_SCHEMA) hass.services.register(DOMAIN, 'start_unpairing', start_unpairing, PAIRING_SCHEMA) def sync_devices(call): stick.sync_devices() _LOGGER.warning(call) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) def clean_config(call): stick.clean_config() stick.sync_devices() hass.services.register(DOMAIN, 'sync_devices', sync_devices) hass.services.register(DOMAIN, 'clean_config', clean_config) def refresh(call): _LOGGER.warning(call) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) return True
def setup(hass, config): """Set up the Wink component.""" import pywink from pubnubsubhandler import PubNubSubscriptionHandler if hass.data.get(DOMAIN) is None: hass.data[DOMAIN] = { 'unique_ids': [], 'entities': {}, 'oauth': {}, 'configuring': {}, 'pubnub': None, 'configurator': False } if config.get(DOMAIN) is not None: client_id = config[DOMAIN].get(ATTR_CLIENT_ID) client_secret = config[DOMAIN].get(ATTR_CLIENT_SECRET) email = config[DOMAIN].get(CONF_EMAIL) password = config[DOMAIN].get(CONF_PASSWORD) local_control = config[DOMAIN].get(CONF_LOCAL_CONTROL) else: client_id = None client_secret = None email = None password = None local_control = None hass.data[DOMAIN]['configurator'] = True if None not in [client_id, client_secret]: _LOGGER.info("Using legacy OAuth authentication") if not local_control: pywink.disable_local_control() hass.data[DOMAIN]["oauth"]["client_id"] = client_id hass.data[DOMAIN]["oauth"]["client_secret"] = client_secret hass.data[DOMAIN]["oauth"]["email"] = email hass.data[DOMAIN]["oauth"]["password"] = password pywink.legacy_set_wink_credentials(email, password, client_id, client_secret) else: _LOGGER.info("Using OAuth authentication") if not local_control: pywink.disable_local_control() config_path = hass.config.path(WINK_CONFIG_FILE) if os.path.isfile(config_path): config_file = load_json(config_path) if config_file == DEFAULT_CONFIG: _request_app_setup(hass, config) return True # else move on because the user modified the file else: save_json(config_path, DEFAULT_CONFIG) _request_app_setup(hass, config) return True if DOMAIN in hass.data[DOMAIN]['configuring']: _configurator = hass.data[DOMAIN]['configuring'] hass.components.configurator.request_done( _configurator.pop(DOMAIN)) # Using oauth access_token = config_file.get(ATTR_ACCESS_TOKEN) refresh_token = config_file.get(ATTR_REFRESH_TOKEN) # This will be called after authorizing Home-Assistant if None not in (access_token, refresh_token): pywink.set_wink_credentials(config_file.get(ATTR_CLIENT_ID), config_file.get(ATTR_CLIENT_SECRET), access_token=access_token, refresh_token=refresh_token) # This is called to create the redirect so the user can Authorize # Home . else: redirect_uri = '{}{}'.format(hass.config.api.base_url, WINK_AUTH_CALLBACK_PATH) wink_auth_start_url = pywink.get_authorization_url( config_file.get(ATTR_CLIENT_ID), redirect_uri) hass.http.register_redirect(WINK_AUTH_START, wink_auth_start_url) hass.http.register_view( WinkAuthCallbackView(config, config_file, pywink.request_token)) _request_oauth_completion(hass, config) return True pywink.set_user_agent(USER_AGENT) hass.data[DOMAIN]['pubnub'] = PubNubSubscriptionHandler( pywink.get_subscription_key()) def _subscribe(): hass.data[DOMAIN]['pubnub'].subscribe() # Call subscribe after the user sets up wink via the configurator # All other methods will complete setup before # EVENT_HOMEASSISTANT_START is called meaning they # will call subscribe via the method below. (start_subscription) if hass.data[DOMAIN]['configurator']: _subscribe() def keep_alive_call(event_time): """Call the Wink API endpoints to keep PubNub working.""" _LOGGER.info("Polling the Wink API to keep PubNub updates flowing") pywink.set_user_agent(str(int(time.time()))) _temp_response = pywink.get_user() _LOGGER.debug(str(json.dumps(_temp_response))) time.sleep(1) pywink.set_user_agent(USER_AGENT) _temp_response = pywink.wink_api_fetch() _LOGGER.debug(str(json.dumps(_temp_response))) # Call the Wink API every hour to keep PubNub updates flowing track_time_interval(hass, keep_alive_call, timedelta(minutes=60)) def start_subscription(event): """Start the PubNub subscription.""" _subscribe() hass.bus.listen(EVENT_HOMEASSISTANT_START, start_subscription) def stop_subscription(event): """Stop the PubNub subscription.""" hass.data[DOMAIN]['pubnub'].unsubscribe() hass.data[DOMAIN]['pubnub'] = None hass.bus.listen(EVENT_HOMEASSISTANT_STOP, stop_subscription) def save_credentials(event): """Save currently set OAuth credentials.""" if hass.data[DOMAIN]["oauth"].get("email") is None: config_path = hass.config.path(WINK_CONFIG_FILE) _config = pywink.get_current_oauth_credentials() save_json(config_path, _config) hass.bus.listen(EVENT_HOMEASSISTANT_STOP, save_credentials) # Save the users potentially updated oauth credentials at a regular # interval to prevent them from being expired after a HA reboot. track_time_interval(hass, save_credentials, timedelta(minutes=60)) def force_update(call): """Force all devices to poll the Wink API.""" _LOGGER.info("Refreshing Wink states from API") for entity_list in hass.data[DOMAIN]['entities'].values(): # Throttle the calls to Wink API for entity in entity_list: time.sleep(1) entity.schedule_update_ha_state(True) hass.services.register(DOMAIN, SERVICE_REFRESH_STATES, force_update) def pull_new_devices(call): """Pull new devices added to users Wink account since startup.""" _LOGGER.info("Getting new devices from Wink API") for _component in WINK_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) hass.services.register(DOMAIN, SERVICE_ADD_NEW_DEVICES, pull_new_devices) def set_pairing_mode(call): """Put the hub in provided pairing mode.""" hub_name = call.data.get('hub_name') pairing_mode = call.data.get('pairing_mode') kidde_code = call.data.get('kidde_radio_code') for hub in WINK_HUBS: if hub.name() == hub_name: hub.pair_new_device(pairing_mode, kidde_radio_code=kidde_code) def rename_device(call): """Set specified device's name.""" # This should only be called on one device at a time. found_device = None entity_id = call.data.get('entity_id')[0] all_devices = [] for list_of_devices in hass.data[DOMAIN]['entities'].values(): all_devices += list_of_devices for device in all_devices: if device.entity_id == entity_id: found_device = device if found_device is not None: name = call.data.get('name') found_device.wink.set_name(name) hass.services.register(DOMAIN, SERVICE_RENAME_DEVICE, rename_device, schema=RENAME_DEVICE_SCHEMA) def delete_device(call): """Delete specified device.""" # This should only be called on one device at a time. found_device = None entity_id = call.data.get('entity_id')[0] all_devices = [] for list_of_devices in hass.data[DOMAIN]['entities'].values(): all_devices += list_of_devices for device in all_devices: if device.entity_id == entity_id: found_device = device if found_device is not None: found_device.wink.remove_device() hass.services.register(DOMAIN, SERVICE_DELETE_DEVICE, delete_device, schema=DELETE_DEVICE_SCHEMA) hubs = pywink.get_hubs() for hub in hubs: if hub.device_manufacturer() == 'wink': WINK_HUBS.append(hub) if WINK_HUBS: hass.services.register(DOMAIN, SERVICE_SET_PAIRING_MODE, set_pairing_mode, schema=SET_PAIRING_MODE_SCHEMA) def service_handle(service): """Handle services.""" entity_ids = service.data.get('entity_id') all_sirens = [] for switch in hass.data[DOMAIN]['entities']['switch']: if isinstance(switch, WinkSirenDevice): all_sirens.append(switch) sirens_to_set = [] if entity_ids is None: sirens_to_set = all_sirens else: for siren in all_sirens: if siren.entity_id in entity_ids: sirens_to_set.append(siren) for siren in sirens_to_set: _man = siren.wink.device_manufacturer() if (service.service != SERVICE_SET_AUTO_SHUTOFF and service.service != SERVICE_ENABLE_SIREN and (_man != 'dome' and _man != 'wink')): _LOGGER.error("Service only valid for Dome or Wink sirens") return if service.service == SERVICE_ENABLE_SIREN: siren.wink.set_state(service.data.get(ATTR_ENABLED)) elif service.service == SERVICE_SET_AUTO_SHUTOFF: siren.wink.set_auto_shutoff( service.data.get(ATTR_AUTO_SHUTOFF)) elif service.service == SERVICE_SET_CHIME_VOLUME: siren.wink.set_chime_volume(service.data.get(ATTR_VOLUME)) elif service.service == SERVICE_SET_SIREN_VOLUME: siren.wink.set_siren_volume(service.data.get(ATTR_VOLUME)) elif service.service == SERVICE_SET_SIREN_TONE: siren.wink.set_siren_sound(service.data.get(ATTR_TONE)) elif service.service == SERVICE_ENABLE_CHIME: siren.wink.set_chime(service.data.get(ATTR_TONE)) elif service.service == SERVICE_SIREN_STROBE_ENABLED: siren.wink.set_siren_strobe_enabled( service.data.get(ATTR_ENABLED)) elif service.service == SERVICE_CHIME_STROBE_ENABLED: siren.wink.set_chime_strobe_enabled( service.data.get(ATTR_ENABLED)) # Load components for the devices in Wink that we support for wink_component in WINK_COMPONENTS: hass.data[DOMAIN]['entities'][wink_component] = [] discovery.load_platform(hass, wink_component, DOMAIN, {}, config) component = EntityComponent(_LOGGER, DOMAIN, hass) sirens = [] has_dome_or_wink_siren = False for siren in pywink.get_sirens(): _man = siren.device_manufacturer() if _man == "dome" or _man == "wink": has_dome_or_wink_siren = True _id = siren.object_id() + siren.name() if _id not in hass.data[DOMAIN]['unique_ids']: sirens.append(WinkSirenDevice(siren, hass)) if sirens: hass.services.register(DOMAIN, SERVICE_SET_AUTO_SHUTOFF, service_handle, schema=SET_AUTO_SHUTOFF_SCHEMA) hass.services.register(DOMAIN, SERVICE_ENABLE_SIREN, service_handle, schema=ENABLED_SIREN_SCHEMA) if has_dome_or_wink_siren: hass.services.register(DOMAIN, SERVICE_SET_SIREN_TONE, service_handle, schema=SET_SIREN_TONE_SCHEMA) hass.services.register(DOMAIN, SERVICE_ENABLE_CHIME, service_handle, schema=SET_CHIME_MODE_SCHEMA) hass.services.register(DOMAIN, SERVICE_SET_SIREN_VOLUME, service_handle, schema=SET_VOLUME_SCHEMA) hass.services.register(DOMAIN, SERVICE_SET_CHIME_VOLUME, service_handle, schema=SET_VOLUME_SCHEMA) hass.services.register(DOMAIN, SERVICE_SIREN_STROBE_ENABLED, service_handle, schema=SET_STROBE_ENABLED_SCHEMA) hass.services.register(DOMAIN, SERVICE_CHIME_STROBE_ENABLED, service_handle, schema=SET_STROBE_ENABLED_SCHEMA) component.add_entities(sirens) return True
def setup(hass, config): """Setup the QSUSB component.""" from pyqwikswitch import (QSUsb, CMD_BUTTONS, QS_NAME, QS_ID, QS_CMD, PQS_VALUE, PQS_TYPE, QSType) # Override which cmd's in /&listen packets will fire events # By default only buttons of type [TOGGLE,SCENE EXE,LEVEL] cmd_buttons = config[DOMAIN].get('button_events', ','.join(CMD_BUTTONS)) cmd_buttons = cmd_buttons.split(',') url = config[DOMAIN]['url'] dimmer_adjust = config[DOMAIN]['dimmer_adjust'] qsusb = QSUsb(url, _LOGGER, dimmer_adjust) def _stop(event): """Stop the listener queue and clean up.""" nonlocal qsusb qsusb.stop() qsusb = None global QSUSB QSUSB = {} _LOGGER.info("Waiting for long poll to QSUSB to time out") hass.bus.listen(EVENT_HOMEASSISTANT_STOP, _stop) # Discover all devices in QSUSB devices = qsusb.devices() QSUSB['switch'] = [] QSUSB['light'] = [] for item in devices: if item[PQS_TYPE] == QSType.relay and ( item[QS_NAME].lower().endswith(' switch')): item[QS_NAME] = item[QS_NAME][:-7] # Remove ' switch' postfix QSUSB['switch'].append(QSSwitch(item, qsusb)) elif item[PQS_TYPE] in [QSType.relay, QSType.dimmer]: QSUSB['light'].append(QSLight(item, qsusb)) else: _LOGGER.warning("Ignored unknown QSUSB device: %s", item) # Load platforms for comp_name in ('switch', 'light'): if len(QSUSB[comp_name]) > 0: load_platform(hass, comp_name, 'qwikswitch', {}, config) def qs_callback(item): """Typically a button press or update signal.""" if qsusb is None: # Shutting down _LOGGER.info("Done") return # If button pressed, fire a hass event if item.get(QS_CMD, '') in cmd_buttons: hass.bus.fire('qwikswitch.button.' + item.get(QS_ID, '@no_id')) return # Update all ha_objects qsreply = qsusb.devices() if qsreply is False: return for item in qsreply: if item[QS_ID] in QSUSB: QSUSB[item[QS_ID]].update_value( round(min(item[PQS_VALUE], 100) * 2.55)) def _start(event): """Start listening.""" qsusb.listen(callback=qs_callback, timeout=30) hass.bus.listen_once(EVENT_HOMEASSISTANT_START, _start) return True
def setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the notify_events component.""" hass.data[DOMAIN] = config[DOMAIN] discovery.load_platform(hass, "notify", DOMAIN, {}, config) return True
def setup(hass, config): """Set up the Ecovacs component.""" _LOGGER.debug("Creating new Ecovacs component") hass.data[ECOVACS_DEVICES] = [] hass.data[ECOVACS_CONFIG] = [] from ozmo import EcoVacsAPI, VacBot ecovacs_api = EcoVacsAPI( ECOVACS_API_DEVICEID, config[DOMAIN].get(CONF_USERNAME), EcoVacsAPI.md5(config[DOMAIN].get(CONF_PASSWORD)), config[DOMAIN].get(CONF_COUNTRY), config[DOMAIN].get(CONF_CONTINENT), ) devices = ecovacs_api.devices() _LOGGER.debug("Ecobot devices: %s", devices) for device in devices: # This is broken!! # _LOGGER.info( # "Discovered Ecovacs device on account: %s with nickname %s", # device["did"], # device["nick"], # ) vacbot = VacBot( ecovacs_api.uid, ecovacs_api.REALM, ecovacs_api.resource, ecovacs_api.user_access_token, device, config[DOMAIN].get(CONF_CONTINENT).lower(), monitor=True, ) hass.data[ECOVACS_DEVICES].append(vacbot) def stop(event: object) -> None: """Shut down open connections to Ecovacs XMPP server.""" for device in hass.data[ECOVACS_DEVICES]: _LOGGER.info("Shutting down connection to Ecovacs device %s", device.vacuum["did"]) device.disconnect() # Listen for HA stop to disconnect. hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop) if hass.data[ECOVACS_DEVICES]: _LOGGER.debug("Starting vacuum components") dconfig = config[DOMAIN] if len(dconfig.get(CONF_SUPPORTED_FEATURES)) == 0: dconfig[CONF_SUPPORTED_FEATURES] = STRING_TO_SERVICE.keys() if CONF_UNSUPPORTED_FEATURES in dconfig: filtered_features = [] for supported_feature in dconfig.get(CONF_SUPPORTED_FEATURES): if supported_feature not in dconfig.get( CONF_UNSUPPORTED_FEATURES): filtered_features.append(supported_feature) dconfig[CONF_SUPPORTED_FEATURES] = filtered_features _LOGGER.debug("SUPPORTED FEATURES") _LOGGER.debug(dconfig.get(CONF_SUPPORTED_FEATURES)) deebot_config = { CONF_SUPPORTED_FEATURES: strings_to_services(dconfig.get(CONF_SUPPORTED_FEATURES), STRING_TO_SERVICE) } hass.data[ECOVACS_CONFIG].append(deebot_config) _LOGGER.debug(hass.data[ECOVACS_CONFIG]) discovery.load_platform(hass, "vacuum", DOMAIN, {}, config) return True
def setup(hass, config): """Set up the Haiku SenseME platform.""" from senseme import discover from senseme import SenseMe # discover Haiku with SenseME fans devices = discover(config[DOMAIN][CONF_MAX_NUMBER_FANS], 8) hubs = [] include_list = config[DOMAIN].get(CONF_INCLUDE) exclude_list = config[DOMAIN].get(CONF_EXCLUDE) if len(include_list) > 0: # add only included fans for device in devices: # _LOGGER.warning("Discovered fan: '%s'." % (device.name)) for include in include_list: if include["name"] == device.name: # _LOGGER.warning("Match include fan: '%s'.", device.name) newDevice = SenseMe( ip=device.ip, name=device.name, monitor_frequency=SENSEME_UPDATE_DELAY, monitor=True, ) hubs.append( SenseMeHub( newDevice, include.get("friendly_name"), include["has_light"], ) ) friendly_name = include.get("friendly_name") if not friendly_name: friendly_name = device.name # _LOGGER.info("Added included fan: '%s' as '%s' %s." % # (device.name, friendly_name, "with light" if # include['has_light'] else "without light")) # make sure all included fans were discovered for include in include_list: discovered = False for hub in hubs: if include["name"] == hub.name: discovered = True break if discovered == False: _LOGGER.error("Included fan not found: '%s'." % (include["name"])) else: # add only not excluded fans for device in devices: # add only if NOT excluded if device.name not in exclude_list: newDevice = SenseMe( ip=device.ip, name=device.name, monitor_frequency=SENSEME_UPDATE_DELAY, monitor=True, ) hubs.append(SenseMeHub(newDevice, None, HAS_LIGHT_DEFAULT)) # _LOGGER.debug("Added not excluded fan: '%s', %s." % # (device.name, "with light" if # HAS_LIGHT_DEFAULT else "without light")) # SenseME fan and light platforms use hub to communicate with the fan hass.data[DATA_HUBS] = hubs # Add fan and light platform load_platform(hass, "fan", DOMAIN, {}, config) load_platform(hass, "light", DOMAIN, {}, config) return True
def _system_callback_handler(hass, config, src, *args): """System callback handler.""" # New devices available at hub if src == "newDevices": (interface_id, dev_descriptions) = args interface = interface_id.split("-")[-1] # Device support active? if not hass.data[DATA_CONF][interface]["connect"]: return addresses = [] for dev in dev_descriptions: address = dev["ADDRESS"].split(":")[0] if address not in hass.data[DATA_STORE]: hass.data[DATA_STORE].add(address) addresses.append(address) # Register EVENTS # Search all devices with an EVENTNODE that includes data bound_event_callback = partial(_hm_event_handler, hass, interface) for dev in addresses: hmdevice = hass.data[DATA_HOMEMATIC].devices[interface].get(dev) if hmdevice.EVENTNODE: hmdevice.setEventCallback(callback=bound_event_callback, bequeath=True) # Create Home Assistant entities if addresses: for component_name, discovery_type in ( ("switch", DISCOVER_SWITCHES), ("light", DISCOVER_LIGHTS), ("cover", DISCOVER_COVER), ("binary_sensor", DISCOVER_BINARY_SENSORS), ("sensor", DISCOVER_SENSORS), ("climate", DISCOVER_CLIMATE), ("lock", DISCOVER_LOCKS), ("binary_sensor", DISCOVER_BATTERY), ): # Get all devices of a specific type found_devices = _get_devices(hass, discovery_type, addresses, interface) # When devices of this type are found # they are setup in Home Assistant and a discovery event is fired if found_devices: discovery.load_platform( hass, component_name, DOMAIN, { ATTR_DISCOVER_DEVICES: found_devices, ATTR_DISCOVERY_TYPE: discovery_type, }, config, ) # Homegear error message elif src == "error": _LOGGER.error("Error: %s", args) (interface_id, errorcode, message) = args hass.bus.fire(EVENT_ERROR, { ATTR_ERRORCODE: errorcode, ATTR_MESSAGE: message })
def _system_callback_handler(hass, config, src, *args): """Callback handler.""" if src == 'newDevices': _LOGGER.debug("newDevices with: %s", args) # pylint: disable=unused-variable (interface_id, dev_descriptions) = args proxy = interface_id.split('-')[-1] # device support active? if not hass.data[DATA_DEVINIT][proxy]: return ## # Get list of all keys of the devices (ignoring channels) key_dict = {} for dev in dev_descriptions: key_dict[dev['ADDRESS'].split(':')[0]] = True ## # remove device they allready init by HA tmp_devs = key_dict.copy() for dev in tmp_devs: if dev in hass.data[DATA_STORE]: del key_dict[dev] else: hass.data[DATA_STORE].append(dev) # Register EVENTS # Search all device with a EVENTNODE that include data bound_event_callback = partial(_hm_event_handler, hass, proxy) for dev in key_dict: hmdevice = hass.data[DATA_HOMEMATIC].devices[proxy].get(dev) # have events? if len(hmdevice.EVENTNODE) > 0: _LOGGER.debug("Register Events from %s", dev) hmdevice.setEventCallback(callback=bound_event_callback, bequeath=True) # If configuration allows autodetection of devices, # all devices not configured are added. if key_dict: for component_name, discovery_type in (('switch', DISCOVER_SWITCHES), ('light', DISCOVER_LIGHTS), ('cover', DISCOVER_COVER), ('binary_sensor', DISCOVER_BINARY_SENSORS), ('sensor', DISCOVER_SENSORS), ('climate', DISCOVER_CLIMATE)): # Get all devices of a specific type found_devices = _get_devices(hass, discovery_type, key_dict, proxy) # When devices of this type are found # they are setup in HA and an event is fired if found_devices: # Fire discovery event discovery.load_platform( hass, component_name, DOMAIN, {ATTR_DISCOVER_DEVICES: found_devices}, config)
def setup(hass, config): """Set up the Dwelo parent component.""" _LOGGER.info("Creating new Dwelo component") if DWELO_DEVICES not in hass.data: hass.data[DWELO_DEVICES] = [] dwelo_client = DweloAccount( config[DOMAIN].get(CONF_USERNAME), config[DOMAIN].get(CONF_PASSWORD) ) logged = dwelo_client.login() if not logged: _LOGGER.error("Not connected to Dwelo account. Unable to add devices") return False _LOGGER.info("Connected to Dwelo account") dwelo_devices = dwelo_client.get_devices() for d in dwelo_devices: hass.data[DWELO_DEVICES].append(d) # temp = list(filter(lambda d: isinstance(d, DweloThermostat), dwelo_devices))[0] # switches = list(filter(lambda d: isinstance(d, DweloSwitch), dwelo_devices)) # hass.data[DWELO_DEVICES].append(temp) # hass.data[DWELO_DEVICES].append(switches) # _LOGGER.info(hass.data[DWELO_DEVICES]) # if CONF_DEVICES in config[DOMAIN] and config[DOMAIN].get(CONF_DEVICES): # configured_devices = config[DOMAIN].get(CONF_DEVICES) # for device in configured_devices: # dyson_device = next( # (d for d in dyson_devices if d.serial == device["device_id"]), None # ) # if dyson_device: # try: # connected = dyson_device.connect(device["device_ip"]) # if connected: # _LOGGER.info("Connected to device %s", dyson_device) # hass.data[DYSON_DEVICES].append(dyson_device) # else: # _LOGGER.warning("Unable to connect to device %s", dyson_device) # except OSError as ose: # _LOGGER.error( # "Unable to connect to device %s: %s", # str(dyson_device.network_device), # str(ose), # ) # else: # _LOGGER.warning( # "Unable to find device %s in Dyson account", device["device_id"] # ) # else: # # Not yet reliable # for device in dyson_devices: # _LOGGER.info( # "Trying to connect to device %s with timeout=%i and retry=%i", # device, # timeout, # retry, # ) # connected = device.auto_connect(timeout, retry) # if connected: # _LOGGER.info("Connected to device %s", device) # hass.data[DYSON_DEVICES].append(device) # else: # _LOGGER.warning("Unable to connect to device %s", device) # # Start fan/sensors components if hass.data[DWELO_DEVICES]: _LOGGER.debug("Starting sensor/fan components") for platform in DWELO_PLATFORMS: discovery.load_platform(hass, platform, DOMAIN, {}, config) return True
def add_device(info: dict): info['yandex_token'] = yandex_token load_platform(hass, 'media_player', DOMAIN, info, hass_config)
def async_setup(hass, config_hosts): """Setup the enerPI Platform.""" enerpi_config = {} for enerpi_name, config in config_hosts[DOMAIN].items(): name = config.get(CONF_NAME, enerpi_name) clean_name = slugify(name) host = config.get(CONF_HOST) port = config.get(CONF_PORT) prefix = config.get(CONF_PREFIX) monitored_sensors = config.get(CONF_MONITORED_VARIABLES) monitored_tiles = config.get(CONF_MONITORED_TILES) data_refresh = config.get(CONF_SCAN_INTERVAL) delta_refresh = config.get(CONF_DELTA_REFRESH) svgs_refresh = config.get(CONF_TILES_REFRESH) width_tiles = config.get(CONF_WIDTH_TILES) # Get ENERPI Config & last data all_sensors_data = yield from \ hass.async_add_job(partial( get_last_data_request, host, port, prefix, retries=5)) if all_sensors_data is None: LOGGER.error('Unable to fetch enerPI REST data') # return False elif not all([k in all_sensors_data for k in KEYS_REQUIRED_MSG]): LOGGER.error( 'enerPI BAD DATA fetched --> {}'.format(all_sensors_data)) # return False else: # Drop aux vars from all_sensors_data: [all_sensors_data.pop(k) for k in KEYS_REQUIRED_MSG] # Filter enerpi sensors to add d_sensors = {} req_conf = yield from hass.async_add_job( partial(requests.get, URL_SENSORS_MASK.format(host, port, prefix), timeout=30)) if req_conf.ok: sensors_conf = req_conf.json() d_sensors = {s['name']: s for s in sensors_conf} if (len(monitored_sensors) == 1) \ and (monitored_sensors[0] == 'all'): sensors_append = list(d_sensors.keys()) else: # present_sensors = list(filter( # lambda x: not x.startswith('ref'), all_sensors_data.keys())) sensors_append = monitored_sensors # Get consumption of last week (to init that counter): start = dt.datetime.today().date() - dt.timedelta(days=7) consumption_kwh_week = None url = URL_CONSUMPTION_LASTWEEK.format(host, port, prefix, start) req_week = yield from hass.async_add_job( partial(requests.get, url, timeout=30)) if req_week.ok: data = req_week.json() consumption_kwh_week = [ round(data[k], 1) for k in sorted(data.keys()) ] LOGGER.info( 'Last week consumption is {}'.format(consumption_kwh_week)) mask_svg_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'camera', '{}_{}_tile_' + str(width_tiles) + 'h.' + CONF_TILE_EXTENSION) main_power, devices_ids, tile_cameras = None, [], [] for sensor_key in sensors_append: svg_file = mask_svg_file.format(clean_name, sensor_key) if (sensor_key in d_sensors.keys()) \ or (sensor_key in all_sensors_data.keys()): if sensor_key not in d_sensors.keys(): # ref sensor friendly_name, unit, is_rms, icon, c1, c2 \ = sensor_key, '', True, 'numeric', \ '#FF2211', '#DDDDDD' else: sensor = d_sensors[sensor_key] sensor_key, friendly_name, unit, is_rms, icon, c1, c2 \ = _extract_sensor_params(sensor) if is_rms and main_power is None: main_power = sensor_key devices_ids.append( ('{}.{}_{}'.format('sensor', clean_name, sensor_key), sensor_key, unit, is_rms, friendly_name, icon)) if not monitored_tiles or (sensor_key in monitored_tiles): # Create empty local files open(svg_file, 'w').close() tile_cameras.append( ('{}_{}_{}'.format(clean_name, 'tile', sensor_key), svg_file, sensor_key, friendly_name, c1, c2)) else: LOGGER.error("Sensor type: {} does not exist in {}".format( sensor_key, d_sensors.keys())) if tile_cameras: # Append tile consumo s_key = 'kWh' c1, c2 = (140, 39, 211, 0.83), (191, 160, 245, 0.27) svg_file = mask_svg_file.format(clean_name, s_key) open(svg_file, 'w').close() tile_cameras.append(('{}_{}_{}'.format(clean_name, 'tile', s_key), svg_file, s_key, 'Consumption', c1, c2)) enerpi_config[clean_name] = { CONF_NAME: name, CONF_HOST: host, CONF_PORT: port, CONF_PREFIX: prefix, CONF_DEVICES: devices_ids, CONF_TILE_CAMERAS: tile_cameras, CONF_SCAN_INTERVAL: data_refresh, CONF_DELTA_REFRESH: delta_refresh, CONF_TILES_SVGS_REFRESH: svgs_refresh, CONF_WIDTH_TILES: width_tiles, CONF_MAIN_POWER: main_power, CONF_LASTWEEK: consumption_kwh_week } # Load platforms sensor & camera with the enerpi_config: if enerpi_config: load_platform(hass, 'sensor', DOMAIN, enerpi_config) load_platform(hass, 'camera', DOMAIN, enerpi_config) return True else: LOGGER.error('ENERPI PLATFORM NOT LOADED') return False
def setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the Mycroft component.""" hass.data[DOMAIN] = config[DOMAIN][CONF_HOST] discovery.load_platform(hass, Platform.NOTIFY, DOMAIN, {}, config) return True
def setup(hass, config): """Set up the Wink component.""" import pywink import requests from pubnubsubhandler import PubNubSubscriptionHandler user_agent = config[DOMAIN].get(CONF_USER_AGENT) if user_agent: pywink.set_user_agent(user_agent) access_token = config[DOMAIN].get(CONF_ACCESS_TOKEN) client_id = config[DOMAIN].get('client_id') if access_token: pywink.set_bearer_token(access_token) elif client_id: email = config[DOMAIN][CONF_EMAIL] password = config[DOMAIN][CONF_PASSWORD] client_id = config[DOMAIN]['client_id'] client_secret = config[DOMAIN]['client_secret'] pywink.set_wink_credentials(email, password, client_id, client_secret) else: email = config[DOMAIN][CONF_EMAIL] password = config[DOMAIN][CONF_PASSWORD] payload = {'username': email, 'password': password} token_response = requests.post(CONF_TOKEN_URL, data=payload) try: token = token_response.text.split(':')[1].split()[0].rstrip('<br') except IndexError: _LOGGER.error("Error getting token. Please check email/password.") return False pywink.set_bearer_token(token) hass.data[DOMAIN] = {} hass.data[DOMAIN]['entities'] = [] hass.data[DOMAIN]['unique_ids'] = [] hass.data[DOMAIN]['pubnub'] = PubNubSubscriptionHandler( pywink.get_subscription_key(), pywink.wink_api_fetch) def start_subscription(event): """Start the pubnub subscription.""" hass.data[DOMAIN]['pubnub'].subscribe() hass.bus.listen(EVENT_HOMEASSISTANT_START, start_subscription) def stop_subscription(event): """Stop the pubnub subscription.""" hass.data[DOMAIN]['pubnub'].unsubscribe() hass.bus.listen(EVENT_HOMEASSISTANT_STOP, stop_subscription) def force_update(call): """Force all devices to poll the Wink API.""" _LOGGER.info("Refreshing Wink states from API") for entity in hass.data[DOMAIN]['entities']: entity.update_ha_state(True) hass.services.register(DOMAIN, 'Refresh state from Wink', force_update) def pull_new_devices(call): """Pull new devices added to users Wink account since startup.""" _LOGGER.info("Getting new devices from Wink API.") for component in WINK_COMPONENTS: discovery.load_platform(hass, component, DOMAIN, {}, config) hass.services.register(DOMAIN, 'Add new devices', pull_new_devices) # Load components for the devices in Wink that we support for component in WINK_COMPONENTS: discovery.load_platform(hass, component, DOMAIN, {}, config) return True
def setup(hass, config): """Set up for the AlarmDecoder devices.""" conf = config.get(DOMAIN) restart = False device = conf[CONF_DEVICE] display = conf[CONF_PANEL_DISPLAY] auto_bypass = conf[CONF_AUTO_BYPASS] code_arm_required = conf[CONF_CODE_ARM_REQUIRED] zones = conf.get(CONF_ZONES) device_type = device[CONF_DEVICE_TYPE] host = DEFAULT_DEVICE_HOST port = DEFAULT_DEVICE_PORT path = DEFAULT_DEVICE_PATH baud = DEFAULT_DEVICE_BAUD def stop_alarmdecoder(event): """Handle the shutdown of AlarmDecoder.""" _LOGGER.debug("Shutting down alarmdecoder") nonlocal restart restart = False controller.close() def open_connection(now=None): """Open a connection to AlarmDecoder.""" nonlocal restart try: controller.open(baud) except NoDeviceError: _LOGGER.debug("Failed to connect. Retrying in 5 seconds") hass.helpers.event.track_point_in_time( open_connection, dt_util.utcnow() + timedelta(seconds=5)) return _LOGGER.debug("Established a connection with the alarmdecoder") restart = True def handle_closed_connection(event): """Restart after unexpected loss of connection.""" nonlocal restart if not restart: return restart = False _LOGGER.warning("AlarmDecoder unexpectedly lost connection.") hass.add_job(open_connection) def handle_message(sender, message): """Handle message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_PANEL_MESSAGE, message) def handle_rfx_message(sender, message): """Handle RFX message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_RFX_MESSAGE, message) def zone_fault_callback(sender, zone): """Handle zone fault from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_ZONE_FAULT, zone) def zone_restore_callback(sender, zone): """Handle zone restore from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_ZONE_RESTORE, zone) def handle_rel_message(sender, message): """Handle relay or zone expander message from AlarmDecoder.""" hass.helpers.dispatcher.dispatcher_send(SIGNAL_REL_MESSAGE, message) controller = False if device_type == "socket": host = device[CONF_HOST] port = device[CONF_DEVICE_PORT] controller = AlarmDecoder(SocketDevice(interface=(host, port))) elif device_type == "serial": path = device[CONF_DEVICE_PATH] baud = device[CONF_DEVICE_BAUD] controller = AlarmDecoder(SerialDevice(interface=path)) elif device_type == "usb": AlarmDecoder(USBDevice.find()) return False controller.on_message += handle_message controller.on_rfx_message += handle_rfx_message controller.on_zone_fault += zone_fault_callback controller.on_zone_restore += zone_restore_callback controller.on_close += handle_closed_connection controller.on_expander_message += handle_rel_message hass.data[DATA_AD] = controller open_connection() hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_alarmdecoder) load_platform( hass, "alarm_control_panel", DOMAIN, { CONF_AUTO_BYPASS: auto_bypass, CONF_CODE_ARM_REQUIRED: code_arm_required }, config, ) if zones: load_platform(hass, "binary_sensor", DOMAIN, {CONF_ZONES: zones}, config) if display: load_platform(hass, "sensor", DOMAIN, conf, config) return True
def setup(hass, config: dict): _LOGGER.debug("Setup") global GLOB_MOWER_NAME, GLOB_MOWER_USERNAME, GLOB_MOWER_PASSWORD, GLOB_MOWER_SERIAL, GLOB_MOWER_BATTERY GLOB_MOWER_NAME = config[DOMAIN].get(CONF_NAME) GLOB_MOWER_USERNAME = config[DOMAIN].get(CONF_USERNAME) GLOB_MOWER_PASSWORD = config[DOMAIN].get(CONF_PASSWORD) GLOB_MOWER_SERIAL = config[DOMAIN].get(CONF_ID) GLOB_MOWER_BATTERY = config[DOMAIN].get(CONF_BATTERY) _LOGGER.debug("Idego pyIndego call Mower") Mower() # Should this be here or in Mower() ??? for component in INDEGO_COMPONENTS: discovery.load_platform(hass, component, DOMAIN, {}, config) # Update every minute now = datetime.datetime.now() track_utc_time_change(hass, Mower.refresh_1m, second=0) # Update every 5 minutes now = datetime.datetime.now() track_utc_time_change(hass, Mower.refresh_5m, minute=range(0, 60, 5), second=0) # Update every hour now = datetime.datetime.now() track_utc_time_change(hass, Mower.refresh_60m, minute=1, second=0) # Update battery at user interval #now = datetime.datetime.now() #track_utc_time_change(hass, Mower.refresh_battery, minute=[1,16,31,46]) DEFAULT_NAME = None SERVICE_NAME = 'mower_command' def send_command(call): """Handle the service call.""" name = call.data.get(CONF_SEND_COMMAND, DEFAULT_NAME) _LOGGER.debug("Indego.send_command service called") _LOGGER.debug("Command: %s", name) IndegoAPI_Instance.putCommand(name) hass.services.register(DOMAIN, SERVICE_NAME, send_command, schema=SERVICE_SCHEMA) DEFAULT_NAME = None SERVICE_NAME = 'smart_mow' def send_smart_mow(call): """Handle the service call.""" name = call.data.get(CONF_SMART_MOW, DEFAULT_NAME) _LOGGER.debug("Indego.send_smart_mow service called") _LOGGER.debug("Command: %s", str(name)) IndegoAPI_Instance.putMowMode(name) hass.services.register(DOMAIN, SERVICE_NAME, send_smart_mow, schema=SERVICE_SCHEMA2) return True
def update(self): """ Get the latest data from BLNET and update the state. Also adds new states on discovery. """ data = self.blnet.fetch(self.node) _LOGGER.info("Checking for new sensors...") # Check if there are new sensors that are to be added i = 0 # iterate through the list and create a sensor for every value for domain in ['analog', 'speed', 'power', 'energy']: for sensor_id in data[domain]: name = '{} {} {}'.format(DOMAIN, domain, sensor_id) if name in self.sensors: continue self.sensors.add(name) _LOGGER.info("Discovered {} sensor {} in use, adding".format(domain, sensor_id)) i += 1 disc_info = { 'name': name, 'domain': domain, 'id': sensor_id, } load_platform(self._hass, 'sensor', DOMAIN, disc_info, self._config) # iterate through the list and create a sensor for every value for sensor_id in data['digital']: name = '{} digital {}'.format(DOMAIN, sensor_id) if name in self.sensors: continue self.sensors.add(name) _LOGGER.info("Discovered digital sensor {} in use, adding".format(sensor_id)) i += 1 disc_info = { 'name': name, 'domain': 'digital', 'id': sensor_id, } if self._config.get(CONF_USE_WEB): component = 'switch' else: component = 'sensor' load_platform(self._hass, component, DOMAIN, disc_info, self._config) if i > 0: _LOGGER.info("Added overall {} sensors".format(i)) for domain in ['analog', 'speed', 'power', 'energy']: # iterate through the list and create a sensor for every value for key, sensor in data.get(domain, {}).items(): attributes = {} entity_id = '{} {} {}'.format(DOMAIN, domain, key) attributes['value'] = sensor.get('value') attributes['unit_of_measurement'] = sensor.get('unit_of_measurement', UNIT[domain]) attributes['friendly_name'] = sensor.get('name') attributes['icon'] = ICON[domain] self.data[entity_id] = attributes # iterate through the list and create a sensor for every value for key, sensor in data.get('digital', {}).items(): attributes = {} entity_id = '{} digital {}'.format(DOMAIN, key) attributes['friendly_name'] = sensor.get('name') attributes['mode'] = sensor.get('mode') attributes['value'] = sensor.get('value') # Change the symbol according to current mode and setting # Automated switch => gear symbol if sensor.get('mode') == 'AUTO': attributes['icon'] = 'mdi:settings' # Nonautomated switch, toggled on => switch on elif sensor.get('mode') == 'EIN': attributes['icon'] = 'mdi:toggle-switch' # Nonautomated switch, toggled off => switch off else: attributes['icon'] = 'mdi:toggle-switch-off' self.data[entity_id] = attributes # save that the data was updated now self._last_updated = datetime.now() return data
def discover_mysensors_platform(hass, platform, new_devices): """Discover a mysensors platform.""" discovery.load_platform(hass, platform, DOMAIN, { ATTR_DEVICES: new_devices, CONF_NAME: DOMAIN })
def setup(hass, config): """Set up the Egardia platform.""" from pythonegardia import egardiadevice from pythonegardia import egardiaserver conf = config[DOMAIN] username = conf.get(CONF_USERNAME) password = conf.get(CONF_PASSWORD) host = conf.get(CONF_HOST) port = conf.get(CONF_PORT) version = conf.get(CONF_VERSION) rs_enabled = conf.get(CONF_REPORT_SERVER_ENABLED) rs_port = conf.get(CONF_REPORT_SERVER_PORT) try: device = hass.data[EGARDIA_DEVICE] = egardiadevice.EgardiaDevice( host, port, username, password, "", version ) except requests.exceptions.RequestException: _LOGGER.error( "An error occurred accessing your Egardia device. " "Please check configuration" ) return False except egardiadevice.UnauthorizedError: _LOGGER.error("Unable to authorize. Wrong password or username") return False # Set up the egardia server if enabled if rs_enabled: _LOGGER.debug("Setting up EgardiaServer") try: if EGARDIA_SERVER not in hass.data: server = egardiaserver.EgardiaServer("", rs_port) bound = server.bind() if not bound: raise OSError( "Binding error occurred while " + "starting EgardiaServer." ) hass.data[EGARDIA_SERVER] = server server.start() def handle_stop_event(event): """Handle Home Assistant stop event.""" server.stop() # listen to home assistant stop event hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, handle_stop_event) except OSError: _LOGGER.error("Binding error occurred while starting EgardiaServer") return False discovery.load_platform( hass, "alarm_control_panel", DOMAIN, discovered=conf, hass_config=config ) # Get the sensors from the device and add those sensors = device.getsensors() discovery.load_platform( hass, "binary_sensor", DOMAIN, {ATTR_DISCOVER_DEVICES: sensors}, config ) return True