def async_add_entity(self, entity, platform=None): """Add entity to component. This method must be run in the event loop. """ if entity is None or entity in self.entities.values(): return False entity.hass = self.hass if getattr(entity, 'entity_id', None) is None: object_id = entity.name or DEVICE_DEFAULT_NAME if platform is not None and platform.entity_namespace is not None: object_id = '{} {}'.format(platform.entity_namespace, object_id) entity.entity_id = async_generate_entity_id( self.entity_id_format, object_id, self.entities.keys()) self.entities[entity.entity_id] = entity yield from entity.async_update_ha_state() return True
def __init__(self, hass, device_id, friendly_name, state_template, icon_template, entity_picture_template, on_action, off_action, level_action, level_template, entity_ids): """Initialize the light.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._icon_template = icon_template self._entity_picture_template = entity_picture_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._level_script = None if level_action is not None: self._level_script = Script(hass, level_action) self._level_template = level_template self._state = False self._icon = None self._entity_picture = None self._brightness = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._level_template is not None: self._level_template.hass = self.hass if self._icon_template is not None: self._icon_template.hass = self.hass if self._entity_picture_template is not None: self._entity_picture_template.hass = self.hass
def create_service(call): """Handle a create notification service call.""" title = call.data.get(ATTR_TITLE) message = call.data.get(ATTR_MESSAGE) notification_id = call.data.get(ATTR_NOTIFICATION_ID) if notification_id is not None: entity_id = ENTITY_ID_FORMAT.format(slugify(notification_id)) else: entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, DEFAULT_OBJECT_ID, hass=hass) attr = {} if title is not None: try: title.hass = hass title = title.async_render() except TemplateError as ex: _LOGGER.error('Error rendering title %s: %s', title, ex) title = title.template attr[ATTR_TITLE] = title try: message.hass = hass message = message.async_render() except TemplateError as ex: _LOGGER.error('Error rendering message %s: %s', message, ex) message = message.template hass.states.async_set(entity_id, message, attr)
def __init__(self, hass, device_id, friendly_name, state_template, position_template, tilt_template, icon_template, open_action, close_action, stop_action, position_action, tilt_action, entity_ids): """Initialize the Template cover.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._position_template = position_template self._tilt_template = tilt_template self._icon_template = icon_template self._open_script = Script(hass, open_action) self._close_script = Script(hass, close_action) self._stop_script = Script(hass, stop_action) self._position_script = None if position_action is not None: self._position_script = Script(hass, position_action) self._tilt_script = None if tilt_action is not None: self._tilt_script = Script(hass, tilt_action) self._icon = None self._position = None self._tilt_value = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._position_template is not None: self._position_template.hass = self.hass if self._tilt_template is not None: self._tilt_template.hass = self.hass if self._icon_template is not None: self._icon_template.hass = self.hass
def async_create_group(hass, name, entity_ids=None, user_defined=True, visible=True, icon=None, view=False, control=None, object_id=None): """Initialize a group. This method must be run in the event loop. """ group = Group( hass, name, order=len(hass.states.async_entity_ids(DOMAIN)), visible=visible, icon=icon, view=view, control=control, user_defined=user_defined, entity_ids=entity_ids ) group.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, object_id or name, hass=hass) # If called before the platform async_setup is called (test cases) component = hass.data.get(DOMAIN) if component is None: component = hass.data[DOMAIN] = \ EntityComponent(_LOGGER, DOMAIN, hass) yield from component.async_add_entities([group], True) return group
def async_request_config( self, name, callback, description, submit_caption, fields, entity_picture): """Set up a request for configuration.""" entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, name, hass=self.hass) if fields is None: fields = [] request_id = self._generate_unique_id() self._requests[request_id] = (entity_id, fields, callback) data = { ATTR_CONFIGURE_ID: request_id, ATTR_FIELDS: fields, ATTR_FRIENDLY_NAME: name, ATTR_ENTITY_PICTURE: entity_picture, } data.update({ key: value for key, value in [ (ATTR_DESCRIPTION, description), (ATTR_SUBMIT_CAPTION, submit_caption), ] if value is not None }) self.hass.states.async_set(entity_id, STATE_CONFIGURE, data) return request_id
def __init__(self, hass, scene, room_data): """Initialize the scene.""" self._scene = scene self.hass = hass self._room_name = None self._sync_room_data(room_data) self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, str(self._scene.id), hass=hass)
def __init__(self, hass, sensor_name, friendly_name, mac): self._hass = hass self.entity_id = async_generate_entity_id('sensor.{}', sensor_name, hass=self._hass) self._name = friendly_name self._mac = mac self._state = None self._attributes = None
def __init__(self, hass, connection, deviceID, alias=None): self.hass = hass self.connection = connection self.deviceID = deviceID self._data = {} prefix = hass.data[DOMAIN][DATA_CONFIG].get(CONFIG_PREFIX, '') self.entity_id = async_generate_entity_id(self.domain + ".{}", alias or f"{prefix}{deviceID}", hass=hass)
def __init__(self, hass, scene_data, room_data, hub): """Initialize the scene.""" self.hub = hub self.hass = hass self._sync_room_data(room_data, scene_data) self._name = scene_data[SCENE_NAME] self._scene_id = scene_data[SCENE_ID] self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, str(scene_data[SCENE_ID]), hass=hass)
def __init__(self, gw_dev, var, device_class, friendly_name_format): """Initialize the binary sensor.""" self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass) self._gateway = gw_dev self._var = var self._state = None self._device_class = device_class self._friendly_name = friendly_name_format.format(gw_dev.name)
async def async_setup_platform( hass: HomeAssistant, config: ConfigType, async_add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the CityBikes platform.""" if PLATFORM not in hass.data: hass.data[PLATFORM] = {MONITORED_NETWORKS: {}} latitude = config.get(CONF_LATITUDE, hass.config.latitude) longitude = config.get(CONF_LONGITUDE, hass.config.longitude) network_id = config.get(CONF_NETWORK) stations_list = set(config.get(CONF_STATIONS_LIST, [])) radius = config.get(CONF_RADIUS, 0) name = config[CONF_NAME] if not hass.config.units.is_metric: radius = distance.convert(radius, LENGTH_FEET, LENGTH_METERS) # Create a single instance of CityBikesNetworks. networks = hass.data.setdefault(CITYBIKES_NETWORKS, CityBikesNetworks(hass)) if not network_id: network_id = await networks.get_closest_network_id(latitude, longitude) if network_id not in hass.data[PLATFORM][MONITORED_NETWORKS]: network = CityBikesNetwork(hass, network_id) hass.data[PLATFORM][MONITORED_NETWORKS][network_id] = network hass.async_create_task(network.async_refresh()) async_track_time_interval(hass, network.async_refresh, SCAN_INTERVAL) else: network = hass.data[PLATFORM][MONITORED_NETWORKS][network_id] await network.ready.wait() devices = [] for station in network.stations: dist = location.distance(latitude, longitude, station[ATTR_LATITUDE], station[ATTR_LONGITUDE]) station_id = station[ATTR_ID] station_uid = str(station.get(ATTR_EXTRA, {}).get(ATTR_UID, "")) if radius > dist or stations_list.intersection( (station_id, station_uid)): if name: uid = "_".join([network.network_id, name, station_id]) else: uid = "_".join([network.network_id, station_id]) entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, uid, hass=hass) devices.append(CityBikesStation(network, station_id, entity_id)) async_add_entities(devices, True)
def __init__(self, inverter, name_prefix, hass): super().__init__() self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, "inverter", hass=hass) self.inverter = inverter self._name_prefix = name_prefix self._uuid = f"{DOMAIN}-{inverter.serial_number}" self._value = None self._sensor = "ppv" self._data = {}
def get_next_id(hass): """Provide the next unused id.""" if (hass is None): return 1 for i in range(1, 999): if (async_generate_entity_id(ENTITY_ID_FORMAT, "ics_" + str(i), hass=hass) == PLATFORM + ".ics_" + str(i)): return i return 999
def check_data(user_input, hass, own_id=None): """Check validity of the provided date.""" ret = {} if (CONF_ICS_URL in user_input): try: cal_string = load_data(user_input[CONF_ICS_URL]) try: Calendar.from_ical(cal_string) except Exception: _LOGGER.error(traceback.format_exc()) ret["base"] = ERROR_ICS return ret except Exception: _LOGGER.error(traceback.format_exc()) ret["base"] = ERROR_URL return ret if (CONF_TIMEFORMAT in user_input): try: datetime.datetime.now(get_localzone()).strftime( user_input[CONF_TIMEFORMAT]) except Exception: _LOGGER.error(traceback.format_exc()) ret["base"] = ERROR_TIMEFORMAT return ret if (CONF_ID in user_input): if (user_input[CONF_ID] < 0): _LOGGER.error("ICS: ID below zero") ret["base"] = ERROR_SMALL_ID return ret if (CONF_LOOKAHEAD in user_input): if (user_input[CONF_LOOKAHEAD] < 1): _LOGGER.error("ICS: Lookahead < 1") ret["base"] = ERROR_SMALL_LOOKAHEAD return ret if (CONF_ID in user_input): if ((own_id != user_input[CONF_ID]) and (hass is not None)): if (async_generate_entity_id(ENTITY_ID_FORMAT, "ics_" + str(user_input[CONF_ID]), hass=hass) != PLATFORM + ".ics_" + str(user_input[CONF_ID])): _LOGGER.error("ICS: ID not unique") ret["base"] = ERROR_ID_NOT_UNIQUE return ret if (CONF_N_SKIP in user_input): if (user_input[CONF_N_SKIP] < 0): _LOGGER.error("ICS: Skip below zero") ret["base"] = ERROR_NEGATIVE_SKIP return ret return ret
def __init__(self, hass, device_id, name, entity_dry_temp, entity_rel_hum): """Initialize the sensor.""" self.hass = hass self._state = None self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = name self._entity_dry_temp = entity_dry_temp self._entity_rel_hum = entity_rel_hum
def __init__(self, hass, config): """Initialize the sensor.""" self._state_attributes = None self._state = None self._url = config.get(CONF_ICS_URL) self._name = config.get(CONF_NAME) self._sw = config.get(CONF_SW) self._timeformat = config.get(CONF_TIMEFORMAT) self._lookahead = config.get(CONF_LOOKAHEAD) self._show_blank = config.get(CONF_SHOW_BLANK) self._force_update = config.get(CONF_FORCE_UPDATE) self._show_remaining = config.get(CONF_SHOW_REMAINING) self._show_ongoing = config.get(CONF_SHOW_ONGOING) self._group_events = config.get(CONF_GROUP_EVENTS) self._n_skip = config.get(CONF_N_SKIP) self._description_in_state = config.get(CONF_DESCRIPTION_IN_STATE) self._icon = config.get(CONF_ICON) _LOGGER.debug("ICS config: ") _LOGGER.debug("\tname: " + self._name) _LOGGER.debug("\tID: " + str(config.get(CONF_ID))) _LOGGER.debug("\turl: " + self._url) _LOGGER.debug("\tsw: " + self._sw) _LOGGER.debug("\ttimeformat: " + self._timeformat) _LOGGER.debug("\tlookahead: " + str(self._lookahead)) _LOGGER.debug("\tshow_blank: " + str(self._show_blank)) _LOGGER.debug("\tforce_update: " + str(self._force_update)) _LOGGER.debug("\tshow_remaining: " + str(self._show_remaining)) _LOGGER.debug("\tshow_ongoing: " + str(self._show_ongoing)) _LOGGER.debug("\tgroup_events: " + str(self._group_events)) _LOGGER.debug("\tn_skip: " + str(self._n_skip)) _LOGGER.debug("\tdescription_in_state: " + str(self._description_in_state)) _LOGGER.debug("\ticon: " + str(self._icon)) self._lastUpdate = -1 self.ics = { 'extra': { 'start': None, 'end': None, 'remaining': -999, 'description': "-", 'location': '-', 'last_updated': None, 'reload_at': None, }, 'pickup_date': "-", } self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, "ics_" + str(config.get(CONF_ID)), hass=hass)
def __init__(self, hass, device_id, friendly_name, source_type, state_template, entity_id): """Initialize the sensor.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._source_type = source_type self._template = state_template self._state = False self._entity = entity_id
async def async_setup_entry(hass, entry, async_add_entities): """Setup binary_sensor platform.""" coordinator = hass.data[DOMAIN][entry.entry_id] sensors: list = [] for sensor_type in BINARY_SENSOR_TYPES: uid = f"{entry.unique_id}_{sensor_type[ATTR_RISK]})" entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, uid, hass=hass) sensors.append( DpcBinarySensor(coordinator, entry, sensor_type, entity_id)) async_add_entities(sensors)
def __init__(self, hass, network, station_id, base_name=''): """Initialize the sensor.""" self._network = network self._station_id = station_id self._station_data = {} if base_name: uid = "_".join([network.network_id, base_name, station_id]) else: uid = "_".join([network.network_id, station_id]) self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, uid, hass=hass)
def __init__(self, hass, device_id, friendly_name, host, uuid, local_key): """Initialize the switch.""" # from pytuya import OutletDevice self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) # OutletDevice('DEVICE_ID_HERE', 'IP_ADDRESS_HERE', 'LOCAL_KEY_HERE') self._smartplug = OutletDevice(uuid, host, local_key) self._name = friendly_name self._state = None self._available = True
def __init__(self, hass, network, station_id, base_name=''): """Initialize the sensor.""" self._network = network self._station_id = station_id self._station_data = {} if base_name: uid = "_".join([network.network_id, base_name, station_id]) else: uid = "_".join([network.network_id, station_id]) self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, uid, hass=hass)
def __init__(self, hass: HomeAssistantType, trash_type_id, data): """Initialize the sensor.""" self._state_attributes = None self._state = None self._trash_type_id = trash_type_id self._name = "Loading (" + str(trash_type_id) + ")" self.data = data self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, "trash_" + str(trash_type_id), hass=hass)
def __init__(self, media_player, var, unit): """Initialize a KEF DSP sensor.""" self._name = f"{media_player.name}_{var}" _LOGGER.debug(f"Setting up {self._name}") self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, self._name, hass=media_player.hass) self._media_player = media_player self._var = var self._value = None self._unit = unit
async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the OpenTherm Gateway binary sensors.""" sensors = [] deprecated_sensors = [] gw_dev = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][ config_entry.data[CONF_ID]] ent_reg = er.async_get(hass) for var, info in BINARY_SENSOR_INFO.items(): device_class = info[0] friendly_name_format = info[1] status_sources = info[2] for source in status_sources: sensors.append( OpenThermBinarySensor( gw_dev, var, source, device_class, friendly_name_format, )) old_style_entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass) old_ent = ent_reg.async_get(old_style_entity_id) if old_ent and old_ent.config_entry_id == config_entry.entry_id: if old_ent.disabled: ent_reg.async_remove(old_style_entity_id) else: deprecated_sensors.append( DeprecatedOpenThermBinarySensor( gw_dev, var, device_class, friendly_name_format, )) sensors.extend(deprecated_sensors) if deprecated_sensors: _LOGGER.warning( "The following binary_sensor entities are deprecated and may " "no longer behave as expected. They will be removed in a " "future version. You can force removal of these entities by " "disabling them and restarting Home Assistant.\n%s", pformat([s.entity_id for s in deprecated_sensors]), ) async_add_entities(sensors)
def __init__(self, hass, device, friendly_name, device_class, value_template, entity_ids): """Initialize the Template binary sensor.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device, hass=hass) self._name = friendly_name self._device_class = device_class self._template = value_template self._state = None self._entities = entity_ids
def __init__(self, hass, coordinator, unique_id, name): self._attr_icon = "mdi:refresh" self._attr_entity_category = EntityCategory.CONFIG self._attr_name = name self._coordinator = coordinator self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, unique_id or name, hass=hass) self._attr_unique_id = unique_id
def __init__(self, hass: HomeAssistantType, nokia_client): """Initialize the Nokia Health sensor.""" self.hass = hass self._client = nokia_client self._measures = None user_id = self._client.credentials.user_id user = self._client.get_user()['users'][0] self._name = '{} {}'.format(user['firstname'], user['lastname']) self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, 'nokia_{}'.format(user_id), hass=hass)
def __init__( self, hass: HomeAssistant, config: dict[str, Any], unique_id: str | None, ) -> None: """Initialize the Template binary sensor.""" super().__init__(config=config) if (object_id := config.get(CONF_OBJECT_ID)) is not None: self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, object_id, hass=hass)
def __init__(self, hass, name, url): """initialize the sensor entity""" self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, name, hass=hass) self.hass = hass self._name = name self._url = url self._state = send_api_request() async_track_time_interval(hass, self.async_update_current, datetime.timedelta(seconds=600)) _LOGGER.debug(self._name + " initiated")
async def async_setup_entry(hass, config_entry): """Set up zone as config entry.""" entry = config_entry.data name = entry[CONF_NAME] zone = Zone(hass, name, entry[CONF_LATITUDE], entry[CONF_LONGITUDE], entry.get(CONF_RADIUS, DEFAULT_RADIUS), entry.get(CONF_ICON), entry.get(CONF_PASSIVE, DEFAULT_PASSIVE)) zone.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, name, None, hass) hass.async_add_job(zone.async_update_ha_state()) hass.data[DOMAIN][slugify(name)] = zone return True
async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the OpenTherm Gateway sensors.""" sensors = [] deprecated_sensors = [] gw_dev = hass.data[DATA_OPENTHERM_GW][DATA_GATEWAYS][ config_entry.data[CONF_ID]] ent_reg = await async_get_registry(hass) for var, info in SENSOR_INFO.items(): device_class = info[0] unit = info[1] friendly_name_format = info[2] status_sources = info[3] for source in status_sources: sensors.append( OpenThermSensor( gw_dev, var, source, device_class, unit, friendly_name_format, )) old_style_entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass) old_ent = ent_reg.async_get(old_style_entity_id) if old_ent and old_ent.config_entry_id == config_entry.entry_id: if old_ent.disabled: ent_reg.async_remove(old_style_entity_id) else: deprecated_sensors.append( DeprecatedOpenThermSensor( gw_dev, var, device_class, unit, friendly_name_format, )) sensors.extend(deprecated_sensors) if deprecated_sensors: _LOGGER.warning( "The following sensor entities are deprecated and may no " "longer behave as expected. They will be removed in a future " "version. You can force removal of these entities by disabling " "them and restarting Safegate Pro.\n%s", pformat([s.entity_id for s in deprecated_sensors]), ) async_add_entities(sensors)
def __init__(self, hass, device, friendly_name, device_class, value_template, entity_ids): """Initialize the Template binary sensor.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device, hass=hass) self._name = friendly_name self._device_class = device_class self._template = value_template self._state = None self._entities = entity_ids
def __init__( self, hass, device_id, friendly_name, friendly_name_template, condition_template, temperature_template, temperature_unit_template, pressure_template, humidity_template, wind_template, wind_bearing_template, ozone_template, attribution_template, visibility_template, forecast_template, availability_template, unique_id, ): """Initialize the entity.""" super().__init__(availability_template=availability_template) self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._friendly_name_template = friendly_name_template self._condition = None self._condition_template = condition_template self._temperature = None self._temperature_template = temperature_template self._temperature_units = None self._temperature_unit_template = temperature_unit_template self._pressure = None self._pressure_template = pressure_template self._humidity = None self._humidity_template = humidity_template self._wind = None self._wind_template = wind_template self._wind_bearing = None self._wind_bearing_template = wind_bearing_template self._ozone = None self._ozone_template = ozone_template self._attribution = None self._attribution_template = attribution_template self._visibility = None self._visibility_template = visibility_template self._forecast = None self._forecast_template = forecast_template self._unique_id = unique_id _LOGGER.debug("Created entity %s: %s", self.entity_id, friendly_name)
def __init__(self, gw_dev, var, device_class, unit, friendly_name_format): """Initialize the OpenTherm Gateway sensor.""" self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass) self._gateway = gw_dev self._var = var self._value = None self._device_class = device_class self._unit = unit self._friendly_name = friendly_name_format.format(gw_dev.name) self._unsub_updates = None
def __init__(self, hass: HomeAssistantType, strava_client): self.hass = hass self._client = strava_client self._stats = None athlete = self._client.get_athlete() self._name = '{} {}'.format(athlete.firstname, athlete.lastname) self.athlete_id = athlete.id self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, 'strava_{}'.format( self.athlete_id), hass=hass)
def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False self._entities = entity_ids
def __init__(self, hass, controller, sensor_type: str): """Initialize sensor.""" self._hass = hass self._controller = controller self._sensor_type = sensor_type self._unique_id = f"{self._controller.unique_id}_{self._sensor_type}" self._name = "{} {}".format(self._controller.name, SENSORS[self._sensor_type]) self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, self._unique_id, hass=hass)
def __init__(self, gw_dev, var, device_class, friendly_name_format): """Initialize the binary sensor.""" self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, f"{var}_{gw_dev.gw_id}", hass=gw_dev.hass ) self._gateway = gw_dev self._var = var self._source = DEPRECATED_BINARY_SENSOR_SOURCE_LOOKUP[var] self._state = None self._device_class = device_class self._friendly_name = friendly_name_format.format(gw_dev.name) self._unsub_updates = None
async def async_setup_entry(hass, config_entry): """Set up zone as config entry.""" entry = config_entry.data name = entry[CONF_NAME] zone = Zone(hass, name, entry[CONF_LATITUDE], entry[CONF_LONGITUDE], entry.get(CONF_RADIUS), entry.get(CONF_ICON), entry.get(CONF_PASSIVE)) zone.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, name, None, hass) hass.async_add_job(zone.async_update_ha_state()) hass.data[DOMAIN][slugify(name)] = zone return True
def __init__(self, hass, device_id, friendly_name, unit_of_measurement, state_template, icon_template, entity_ids): """Initialize the sensor.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._unit_of_measurement = unit_of_measurement self._template = state_template self._state = None self._icon_template = icon_template self._icon = None self._entities = entity_ids
def __init__(self, hass, lacrosse, device_id, name, expire_after, config): """Initialize the sensor.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._config = config self._name = name self._value = None self._expire_after = expire_after self._expiration_trigger = None lacrosse.register_callback( int(self._config['id']), self._callback_lacrosse, None)
def __init__(self, hass, device_id, friendly_name, state_template, speed_template, oscillating_template, direction_template, on_action, off_action, set_speed_action, set_oscillating_action, set_direction_action, speed_list, entity_ids): """Initialize the fan.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._speed_template = speed_template self._oscillating_template = oscillating_template self._direction_template = direction_template self._supported_features = 0 self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._set_speed_script = None if set_speed_action: self._set_speed_script = Script(hass, set_speed_action) self._set_oscillating_script = None if set_oscillating_action: self._set_oscillating_script = Script(hass, set_oscillating_action) self._set_direction_script = None if set_direction_action: self._set_direction_script = Script(hass, set_direction_action) self._state = STATE_OFF self._speed = None self._oscillating = None self._direction = None self._template.hass = self.hass if self._speed_template: self._speed_template.hass = self.hass self._supported_features |= SUPPORT_SET_SPEED if self._oscillating_template: self._oscillating_template.hass = self.hass self._supported_features |= SUPPORT_OSCILLATE if self._direction_template: self._direction_template.hass = self.hass self._supported_features |= SUPPORT_DIRECTION self._entities = entity_ids # List of valid speeds self._speed_list = speed_list
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up the CityBikes platform.""" if PLATFORM not in hass.data: hass.data[PLATFORM] = {MONITORED_NETWORKS: {}} latitude = config.get(CONF_LATITUDE, hass.config.latitude) longitude = config.get(CONF_LONGITUDE, hass.config.longitude) network_id = config.get(CONF_NETWORK) stations_list = set(config.get(CONF_STATIONS_LIST, [])) radius = config.get(CONF_RADIUS, 0) name = config[CONF_NAME] if not hass.config.units.is_metric: radius = distance.convert(radius, LENGTH_FEET, LENGTH_METERS) # Create a single instance of CityBikesNetworks. networks = hass.data.setdefault( CITYBIKES_NETWORKS, CityBikesNetworks(hass)) if not network_id: network_id = await networks.get_closest_network_id(latitude, longitude) if network_id not in hass.data[PLATFORM][MONITORED_NETWORKS]: network = CityBikesNetwork(hass, network_id) hass.data[PLATFORM][MONITORED_NETWORKS][network_id] = network hass.async_create_task(network.async_refresh()) async_track_time_interval(hass, network.async_refresh, SCAN_INTERVAL) else: network = hass.data[PLATFORM][MONITORED_NETWORKS][network_id] await network.ready.wait() devices = [] for station in network.stations: dist = location.distance( latitude, longitude, station[ATTR_LATITUDE], station[ATTR_LONGITUDE]) station_id = station[ATTR_ID] station_uid = str(station.get(ATTR_EXTRA, {}).get(ATTR_UID, '')) if radius > dist or stations_list.intersection( (station_id, station_uid)): if name: uid = "_".join([network.network_id, name, station_id]) else: uid = "_".join([network.network_id, station_id]) entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, uid, hass=hass) devices.append(CityBikesStation(network, station_id, entity_id)) async_add_entities(devices, True)
def __init__(self, hass: HomeAssistantType, rest, condition): """Initialize the sensor.""" self.rest = rest self._condition = condition self._state = None self._attributes = { ATTR_ATTRIBUTION: CONF_ATTRIBUTION, } self._icon = None self._entity_picture = None self._unit_of_measurement = self._cfg_expand("unit_of_measurement") self.rest.request_feature(SENSOR_TYPES[condition].feature) self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, "pws_" + condition, hass=hass)
def _async_add_entity(self, entity, update_before_add, component_entities): """Helper method to add an entity to the platform.""" if entity is None: raise ValueError('Entity cannot be None') # Do nothing if entity has already been added based on unique id. if entity in self.component.entities: return entity.hass = self.component.hass entity.platform = self entity.parallel_updates = self.parallel_updates # Update properties before we generate the entity_id if update_before_add: try: yield from entity.async_device_update(warning=False) except Exception: # pylint: disable=broad-except self.component.logger.exception( "%s: Error on device update!", self.platform) return # Write entity_id to entity if getattr(entity, 'entity_id', None) is None: object_id = entity.name or DEVICE_DEFAULT_NAME if self.entity_namespace is not None: object_id = '{} {}'.format(self.entity_namespace, object_id) entity.entity_id = async_generate_entity_id( self.component.entity_id_format, object_id, component_entities) # Make sure it is valid in case an entity set the value themselves if not valid_entity_id(entity.entity_id): raise HomeAssistantError( 'Invalid entity id: {}'.format(entity.entity_id)) elif entity.entity_id in component_entities: raise HomeAssistantError( 'Entity id already exists: {}'.format(entity.entity_id)) self.entities[entity.entity_id] = entity component_entities.add(entity.entity_id) if hasattr(entity, 'async_added_to_hass'): yield from entity.async_added_to_hass() yield from entity.async_update_ha_state()
def create_service(call): """Handle a create notification service call.""" title = call.data.get(ATTR_TITLE) message = call.data.get(ATTR_MESSAGE) notification_id = call.data.get(ATTR_NOTIFICATION_ID) if notification_id is not None: entity_id = ENTITY_ID_FORMAT.format(slugify(notification_id)) else: entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, DEFAULT_OBJECT_ID, hass=hass) notification_id = entity_id.split('.')[1] attr = {} if title is not None: try: title.hass = hass title = title.async_render() except TemplateError as ex: _LOGGER.error('Error rendering title %s: %s', title, ex) title = title.template attr[ATTR_TITLE] = title try: message.hass = hass message = message.async_render() except TemplateError as ex: _LOGGER.error('Error rendering message %s: %s', message, ex) message = message.template attr[ATTR_MESSAGE] = message hass.states.async_set(entity_id, STATE, attr) # Store notification and fire event # This will eventually replace state machine storage persistent_notifications[entity_id] = { ATTR_MESSAGE: message, ATTR_NOTIFICATION_ID: notification_id, ATTR_STATUS: STATUS_UNREAD, ATTR_TITLE: title, ATTR_CREATED_AT: dt_util.utcnow(), } hass.bus.async_fire(EVENT_PERSISTENT_NOTIFICATIONS_UPDATED)
def async_add_entity(self, entity, platform=None, update_before_add=False): """Add entity to component. This method must be run in the event loop. """ if entity is None or entity in self.entities.values(): return False entity.hass = self.hass # Update properties before we generate the entity_id if update_before_add: try: yield from entity.async_device_update(warning=False) except Exception: # pylint: disable=broad-except self.logger.exception("Error on device update!") return False # Write entity_id to entity if getattr(entity, 'entity_id', None) is None: object_id = entity.name or DEVICE_DEFAULT_NAME if platform is not None and platform.entity_namespace is not None: object_id = '{} {}'.format(platform.entity_namespace, object_id) entity.entity_id = async_generate_entity_id( self.entity_id_format, object_id, self.entities.keys()) # Make sure it is valid in case an entity set the value themselves if entity.entity_id in self.entities: raise HomeAssistantError( 'Entity id already exists: {}'.format(entity.entity_id)) elif not valid_entity_id(entity.entity_id): raise HomeAssistantError( 'Invalid entity id: {}'.format(entity.entity_id)) self.entities[entity.entity_id] = entity if hasattr(entity, 'async_added_to_hass'): yield from entity.async_added_to_hass() yield from entity.async_update_ha_state() return True
def __init__(self, hass, device, friendly_name, sensor_class, value_template, entity_ids): """Initialize the Template binary sensor.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device, hass=hass) self._name = friendly_name self._sensor_class = sensor_class self._template = value_template self._state = None @callback def template_bsensor_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" hass.async_add_job(self.async_update_ha_state, True) async_track_state_change( hass, entity_ids, template_bsensor_state_listener)
def __init__(self, hass, device_id, friendly_name, unit_of_measurement, state_template, entity_ids): """Initialize the sensor.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._unit_of_measurement = unit_of_measurement self._template = state_template self._state = None @callback def template_sensor_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" hass.async_add_job(self.async_update_ha_state, True) async_track_state_change( hass, entity_ids, template_sensor_state_listener)
def async_add_entity(self, entity, platform=None, update_before_add=False): """Add entity to component. This method must be run in the event loop. """ if entity is None or entity in self.entities.values(): return False entity.hass = self.hass # update/init entity data if update_before_add: if hasattr(entity, 'async_update'): yield from entity.async_update() else: yield from self.hass.async_add_job(entity.update) if getattr(entity, 'entity_id', None) is None: object_id = entity.name or DEVICE_DEFAULT_NAME if platform is not None and platform.entity_namespace is not None: object_id = '{} {}'.format(platform.entity_namespace, object_id) entity.entity_id = async_generate_entity_id( self.entity_id_format, object_id, self.entities.keys()) # Make sure it is valid in case an entity set the value themselves if entity.entity_id in self.entities: raise HomeAssistantError( 'Entity id already exists: {}'.format(entity.entity_id)) elif not valid_entity_id(entity.entity_id): raise HomeAssistantError( 'Invalid entity id: {}'.format(entity.entity_id)) self.entities[entity.entity_id] = entity if hasattr(entity, 'async_added_to_hass'): yield from entity.async_added_to_hass() yield from entity.async_update_ha_state() return True
def __init__(self, hass: HomeAssistantType, rest, condition, namespace: str): """Initialize the sensor.""" self.rest = rest self._condition = condition self._state = None self._attributes = { ATTR_ATTRIBUTION: CONF_ATTRIBUTION, } self._icon = None self._entity_picture = None self._unit_of_measurement = self._cfg_expand("unit_of_measurement") self.rest.request_feature(SENSOR_TYPES[condition].feature) current_ids = set(hass.states.async_entity_ids(sensor.DOMAIN)) current_ids |= hass.data[ADDED_ENTITY_IDS_KEY] self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, "{} {}".format(namespace, condition), current_ids=current_ids) hass.data[ADDED_ENTITY_IDS_KEY].add(self.entity_id)
def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False @callback def template_switch_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" hass.async_add_job(self.async_update_ha_state(True)) async_track_state_change( hass, entity_ids, template_switch_state_listener)
def async_create_group(hass, name, entity_ids=None, user_defined=True, icon=None, view=False, object_id=None): """Initialize a group. This method must be run in the event loop. """ group = Group( hass, name, order=len(hass.states.async_entity_ids(DOMAIN)), user_defined=user_defined, icon=icon, view=view) group.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, object_id or name, hass=hass) # run other async stuff if entity_ids is not None: yield from group.async_update_tracked_entity_ids(entity_ids) else: yield from group.async_update_ha_state(True) return group
def async_setup(hass, config): """Set up the zone.""" entities = set() tasks = [] for _, entry in config_per_platform(config, DOMAIN): name = entry.get(CONF_NAME) zone = Zone(hass, name, entry[CONF_LATITUDE], entry[CONF_LONGITUDE], entry.get(CONF_RADIUS), entry.get(CONF_ICON), entry.get(CONF_PASSIVE)) zone.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, name, entities) tasks.append(zone.async_update_ha_state()) entities.add(zone.entity_id) if ENTITY_ID_HOME not in entities: zone = Zone(hass, hass.config.location_name, hass.config.latitude, hass.config.longitude, DEFAULT_RADIUS, ICON_HOME, False) zone.entity_id = ENTITY_ID_HOME tasks.append(zone.async_update_ha_state()) yield from asyncio.wait(tasks, loop=hass.loop) return True
async def async_setup(hass, config): """Setup configured zones as well as home assistant zone if necessary.""" hass.data[DOMAIN] = {} entities = set() zone_entries = configured_zones(hass) for _, entry in config_per_platform(config, DOMAIN): if slugify(entry[CONF_NAME]) not in zone_entries: zone = Zone(hass, entry[CONF_NAME], entry[CONF_LATITUDE], entry[CONF_LONGITUDE], entry.get(CONF_RADIUS), entry.get(CONF_ICON), entry.get(CONF_PASSIVE)) zone.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, entry[CONF_NAME], entities) hass.async_add_job(zone.async_update_ha_state()) entities.add(zone.entity_id) if ENTITY_ID_HOME not in entities and HOME_ZONE not in zone_entries: zone = Zone(hass, hass.config.location_name, hass.config.latitude, hass.config.longitude, DEFAULT_RADIUS, ICON_HOME, False) zone.entity_id = ENTITY_ID_HOME hass.async_add_job(zone.async_update_ha_state()) return True
async def async_setup_platform( hass, config, async_add_entities, discovery_info=None): """Set up the OpenTherm Gateway binary sensors.""" if discovery_info is None: return gw_vars = hass.data[DATA_OPENTHERM_GW][DATA_GW_VARS] sensor_info = { # [device_class, friendly_name] gw_vars.DATA_MASTER_CH_ENABLED: [ None, "Thermostat Central Heating Enabled"], gw_vars.DATA_MASTER_DHW_ENABLED: [ None, "Thermostat Hot Water Enabled"], gw_vars.DATA_MASTER_COOLING_ENABLED: [ None, "Thermostat Cooling Enabled"], gw_vars.DATA_MASTER_OTC_ENABLED: [ None, "Thermostat Outside Temperature Correction Enabled"], gw_vars.DATA_MASTER_CH2_ENABLED: [ None, "Thermostat Central Heating 2 Enabled"], gw_vars.DATA_SLAVE_FAULT_IND: [ DEVICE_CLASS_PROBLEM, "Boiler Fault Indication"], gw_vars.DATA_SLAVE_CH_ACTIVE: [ DEVICE_CLASS_HEAT, "Boiler Central Heating Status"], gw_vars.DATA_SLAVE_DHW_ACTIVE: [ DEVICE_CLASS_HEAT, "Boiler Hot Water Status"], gw_vars.DATA_SLAVE_FLAME_ON: [ DEVICE_CLASS_HEAT, "Boiler Flame Status"], gw_vars.DATA_SLAVE_COOLING_ACTIVE: [ DEVICE_CLASS_COLD, "Boiler Cooling Status"], gw_vars.DATA_SLAVE_CH2_ACTIVE: [ DEVICE_CLASS_HEAT, "Boiler Central Heating 2 Status"], gw_vars.DATA_SLAVE_DIAG_IND: [ DEVICE_CLASS_PROBLEM, "Boiler Diagnostics Indication"], gw_vars.DATA_SLAVE_DHW_PRESENT: [None, "Boiler Hot Water Present"], gw_vars.DATA_SLAVE_CONTROL_TYPE: [None, "Boiler Control Type"], gw_vars.DATA_SLAVE_COOLING_SUPPORTED: [None, "Boiler Cooling Support"], gw_vars.DATA_SLAVE_DHW_CONFIG: [ None, "Boiler Hot Water Configuration"], gw_vars.DATA_SLAVE_MASTER_LOW_OFF_PUMP: [ None, "Boiler Pump Commands Support"], gw_vars.DATA_SLAVE_CH2_PRESENT: [ None, "Boiler Central Heating 2 Present"], gw_vars.DATA_SLAVE_SERVICE_REQ: [ DEVICE_CLASS_PROBLEM, "Boiler Service Required"], gw_vars.DATA_SLAVE_REMOTE_RESET: [None, "Boiler Remote Reset Support"], gw_vars.DATA_SLAVE_LOW_WATER_PRESS: [ DEVICE_CLASS_PROBLEM, "Boiler Low Water Pressure"], gw_vars.DATA_SLAVE_GAS_FAULT: [ DEVICE_CLASS_PROBLEM, "Boiler Gas Fault"], gw_vars.DATA_SLAVE_AIR_PRESS_FAULT: [ DEVICE_CLASS_PROBLEM, "Boiler Air Pressure Fault"], gw_vars.DATA_SLAVE_WATER_OVERTEMP: [ DEVICE_CLASS_PROBLEM, "Boiler Water Overtemperature"], gw_vars.DATA_REMOTE_TRANSFER_DHW: [ None, "Remote Hot Water Setpoint Transfer Support"], gw_vars.DATA_REMOTE_TRANSFER_MAX_CH: [ None, "Remote Maximum Central Heating Setpoint Write Support"], gw_vars.DATA_REMOTE_RW_DHW: [ None, "Remote Hot Water Setpoint Write Support"], gw_vars.DATA_REMOTE_RW_MAX_CH: [ None, "Remote Central Heating Setpoint Write Support"], gw_vars.DATA_ROVRD_MAN_PRIO: [ None, "Remote Override Manual Change Priority"], gw_vars.DATA_ROVRD_AUTO_PRIO: [ None, "Remote Override Program Change Priority"], gw_vars.OTGW_GPIO_A_STATE: [None, "Gateway GPIO A State"], gw_vars.OTGW_GPIO_B_STATE: [None, "Gateway GPIO B State"], gw_vars.OTGW_IGNORE_TRANSITIONS: [None, "Gateway Ignore Transitions"], gw_vars.OTGW_OVRD_HB: [None, "Gateway Override High Byte"], } sensors = [] for var in discovery_info: device_class = sensor_info[var][0] friendly_name = sensor_info[var][1] entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, var, hass=hass) sensors.append(OpenThermBinarySensor(entity_id, var, device_class, friendly_name)) async_add_entities(sensors)
async def async_setup_platform( hass, config, async_add_entities, discovery_info=None): """Set up the OpenTherm Gateway sensors.""" if discovery_info is None: return gw_vars = hass.data[DATA_OPENTHERM_GW][DATA_GW_VARS] sensor_info = { # [device_class, unit, friendly_name] gw_vars.DATA_CONTROL_SETPOINT: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Control Setpoint"], gw_vars.DATA_MASTER_MEMBERID: [None, None, "Thermostat Member ID"], gw_vars.DATA_SLAVE_MEMBERID: [None, None, "Boiler Member ID"], gw_vars.DATA_SLAVE_OEM_FAULT: [None, None, "Boiler OEM Fault Code"], gw_vars.DATA_COOLING_CONTROL: [ None, UNIT_PERCENT, "Cooling Control Signal"], gw_vars.DATA_CONTROL_SETPOINT_2: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Control Setpoint 2"], gw_vars.DATA_ROOM_SETPOINT_OVRD: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Room Setpoint Override"], gw_vars.DATA_SLAVE_MAX_RELATIVE_MOD: [ None, UNIT_PERCENT, "Boiler Maximum Relative Modulation"], gw_vars.DATA_SLAVE_MAX_CAPACITY: [ None, UNIT_KW, "Boiler Maximum Capacity"], gw_vars.DATA_SLAVE_MIN_MOD_LEVEL: [ None, UNIT_PERCENT, "Boiler Minimum Modulation Level"], gw_vars.DATA_ROOM_SETPOINT: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Room Setpoint"], gw_vars.DATA_REL_MOD_LEVEL: [ None, UNIT_PERCENT, "Relative Modulation Level"], gw_vars.DATA_CH_WATER_PRESS: [ None, UNIT_BAR, "Central Heating Water Pressure"], gw_vars.DATA_DHW_FLOW_RATE: [None, UNIT_L_MIN, "Hot Water Flow Rate"], gw_vars.DATA_ROOM_SETPOINT_2: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Room Setpoint 2"], gw_vars.DATA_ROOM_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Room Temperature"], gw_vars.DATA_CH_WATER_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Central Heating Water Temperature"], gw_vars.DATA_DHW_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water Temperature"], gw_vars.DATA_OUTSIDE_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Outside Temperature"], gw_vars.DATA_RETURN_WATER_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Return Water Temperature"], gw_vars.DATA_SOLAR_STORAGE_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Solar Storage Temperature"], gw_vars.DATA_SOLAR_COLL_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Solar Collector Temperature"], gw_vars.DATA_CH_WATER_TEMP_2: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Central Heating 2 Water Temperature"], gw_vars.DATA_DHW_TEMP_2: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water 2 Temperature"], gw_vars.DATA_EXHAUST_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Exhaust Temperature"], gw_vars.DATA_SLAVE_DHW_MAX_SETP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water Maximum Setpoint"], gw_vars.DATA_SLAVE_DHW_MIN_SETP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water Minimum Setpoint"], gw_vars.DATA_SLAVE_CH_MAX_SETP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Boiler Maximum Central Heating Setpoint"], gw_vars.DATA_SLAVE_CH_MIN_SETP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Boiler Minimum Central Heating Setpoint"], gw_vars.DATA_DHW_SETPOINT: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Hot Water Setpoint"], gw_vars.DATA_MAX_CH_SETPOINT: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Maximum Central Heating Setpoint"], gw_vars.DATA_OEM_DIAG: [None, None, "OEM Diagnostic Code"], gw_vars.DATA_TOTAL_BURNER_STARTS: [ None, None, "Total Burner Starts"], gw_vars.DATA_CH_PUMP_STARTS: [ None, None, "Central Heating Pump Starts"], gw_vars.DATA_DHW_PUMP_STARTS: [None, None, "Hot Water Pump Starts"], gw_vars.DATA_DHW_BURNER_STARTS: [ None, None, "Hot Water Burner Starts"], gw_vars.DATA_TOTAL_BURNER_HOURS: [ None, UNIT_HOUR, "Total Burner Hours"], gw_vars.DATA_CH_PUMP_HOURS: [ None, UNIT_HOUR, "Central Heating Pump Hours"], gw_vars.DATA_DHW_PUMP_HOURS: [None, UNIT_HOUR, "Hot Water Pump Hours"], gw_vars.DATA_DHW_BURNER_HOURS: [ None, UNIT_HOUR, "Hot Water Burner Hours"], gw_vars.DATA_MASTER_OT_VERSION: [ None, None, "Thermostat OpenTherm Version"], gw_vars.DATA_SLAVE_OT_VERSION: [ None, None, "Boiler OpenTherm Version"], gw_vars.DATA_MASTER_PRODUCT_TYPE: [ None, None, "Thermostat Product Type"], gw_vars.DATA_MASTER_PRODUCT_VERSION: [ None, None, "Thermostat Product Version"], gw_vars.DATA_SLAVE_PRODUCT_TYPE: [None, None, "Boiler Product Type"], gw_vars.DATA_SLAVE_PRODUCT_VERSION: [ None, None, "Boiler Product Version"], gw_vars.OTGW_MODE: [None, None, "Gateway/Monitor Mode"], gw_vars.OTGW_DHW_OVRD: [None, None, "Gateway Hot Water Override Mode"], gw_vars.OTGW_ABOUT: [None, None, "Gateway Firmware Version"], gw_vars.OTGW_BUILD: [None, None, "Gateway Firmware Build"], gw_vars.OTGW_CLOCKMHZ: [None, None, "Gateway Clock Speed"], gw_vars.OTGW_LED_A: [None, None, "Gateway LED A Mode"], gw_vars.OTGW_LED_B: [None, None, "Gateway LED B Mode"], gw_vars.OTGW_LED_C: [None, None, "Gateway LED C Mode"], gw_vars.OTGW_LED_D: [None, None, "Gateway LED D Mode"], gw_vars.OTGW_LED_E: [None, None, "Gateway LED E Mode"], gw_vars.OTGW_LED_F: [None, None, "Gateway LED F Mode"], gw_vars.OTGW_GPIO_A: [None, None, "Gateway GPIO A Mode"], gw_vars.OTGW_GPIO_B: [None, None, "Gateway GPIO B Mode"], gw_vars.OTGW_SB_TEMP: [ DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, "Gateway Setback Temperature"], gw_vars.OTGW_SETP_OVRD_MODE: [ None, None, "Gateway Room Setpoint Override Mode"], gw_vars.OTGW_SMART_PWR: [None, None, "Gateway Smart Power Mode"], gw_vars.OTGW_THRM_DETECT: [None, None, "Gateway Thermostat Detection"], gw_vars.OTGW_VREF: [None, None, "Gateway Reference Voltage Setting"], } sensors = [] for var in discovery_info: device_class = sensor_info[var][0] unit = sensor_info[var][1] friendly_name = sensor_info[var][2] entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, var, hass=hass) sensors.append( OpenThermSensor(entity_id, var, device_class, unit, friendly_name)) async_add_entities(sensors)