def resolve_area_entities( hass: HomeAssistantType, area_id_or_name: str) -> dict[str, entity_registry.RegistryEntry]: """Get a listing of al entities in a given area""" area_reg = area_registry.async_get(hass) area = area_reg.async_get_area(area_id_or_name) if area is None: area = area_reg.async_get_area_by_name(str(area_id_or_name)) if area is None: raise SensorConfigurationError( f"No area with id or name '{area_id_or_name}' found in your HA instance" ) area_id = area.id entity_reg = entity_registry.async_get(hass) entities = entity_registry.async_entries_for_area(entity_reg, area_id) device_reg = device_registry.async_get(hass) # We also need to add entities tied to a device in the area that don't themselves # have an area specified since they inherit the area from the device. entities.extend([ entity for device in device_registry.async_entries_for_area( device_reg, area_id) for entity in entity_registry.async_entries_for_device( entity_reg, device.id) if entity.area_id is None ]) return { entity.entity_id: entity for entity in entities if entity.domain == LIGHT_DOMAIN }
def async_get_nodes_from_area_id( hass: HomeAssistant, area_id: str, ent_reg: er.EntityRegistry | None = None, dev_reg: dr.DeviceRegistry | None = None, ) -> set[ZwaveNode]: """Get nodes for all Z-Wave JS devices and entities that are in an area.""" nodes: set[ZwaveNode] = set() if ent_reg is None: ent_reg = er.async_get(hass) if dev_reg is None: dev_reg = dr.async_get(hass) # Add devices for all entities in an area that are Z-Wave JS entities nodes.update({ async_get_node_from_device_id(hass, entity.device_id, dev_reg) for entity in er.async_entries_for_area(ent_reg, area_id) if entity.platform == DOMAIN and entity.device_id is not None }) # Add devices in an area that are Z-Wave JS devices for device in dr.async_entries_for_area(dev_reg, area_id): if next( (config_entry_id for config_entry_id in device.config_entries if cast( ConfigEntry, hass.config_entries.async_get_entry(config_entry_id), ).domain == DOMAIN), None, ): nodes.add(async_get_node_from_device_id(hass, device.id, dev_reg)) return nodes
def _resolve_area(self, area_id) -> None: """Resolve an area.""" for device in device_registry.async_entries_for_area(self._device_reg, area_id): self._add_or_resolve("device", device.id) for entity_entry in entity_registry.async_entries_for_area( self._entity_reg, area_id ): self._add_or_resolve("entity", entity_entry.entity_id)
async def find_entity(hass, name, type=None): # 遍历所有实体 states = hass.states.async_all() for state in states: entity_id = state.entity_id domain = state.domain attributes = state.attributes friendly_name = attributes.get('friendly_name') # 查询对应的设备名称 if friendly_name is not None and friendly_name.lower() == name.lower(): # 指定类型 if isMatchDomain(type, domain): return state # 如果没有匹配到实体,则开始从区域里查找 arr = name.split('的', 1) if len(arr) == 2: area_name = arr[0] device_name = arr[1] # 获取所有区域 area = await area_registry.async_get_registry(hass) area_list = area.async_list_areas() _list = list(filter(lambda item: item.name == area_name, area_list)) if (len(_list) > 0): area_id = _list[0].id entity = await entity_registry.async_get_registry(hass) entity_list = entity_registry.async_entries_for_area( entity, area_id) # 有设备才处理 if len(entity_list) > 0: # 查找完整设备 _list = list( filter( lambda item: item.name == device_name or item. original_name == device_name, entity_list)) if (len(_list) > 0): # print(_list) item = _list[0] state = hass.states.get(item.entity_id) if isMatchDomain(type, state.domain): return state # 如果直接说了灯或开关 if device_name == '灯': # 如果只有一个设备 if len(entity_list) == 1: item = entity_list[0] state = hass.states.get(item.entity_id) if isMatchDomain(type, state.domain): return state else: # 取第一个含有灯字的设备(这里可以通过其他属性来判断,以后再考虑) for item in entity_list: state = hass.states.get(item.entity_id) friendly_name = state.attributes.get( 'friendly_name') if '灯' in friendly_name and isMatchDomain( type, state.domain): return state
def _resolve_area(self, area_id) -> None: """Resolve an area.""" for device in device_registry.async_entries_for_area( self._device_reg, area_id): self._add_or_resolve("device", device.id) for entity_entry in entity_registry.async_entries_for_area( self._entity_reg, area_id): self._add_or_resolve("entity", entity_entry.entity_id) for entity_id in script.scripts_with_area(self.hass, area_id): self._add_or_resolve("entity", entity_id) for entity_id in automation.automations_with_area(self.hass, area_id): self._add_or_resolve("entity", entity_id)
async def discoveryDevice(hass): timestampOfSample = date_now() # 获取所有区域 area = await area_registry.async_get_registry(hass) area_list = area.async_list_areas() for area_item in area_list: # 获取设备 # entity = await device_registry.async_get_registry(hass) # entity_list = device_registry.async_entries_for_area(entity, area_item.id) # 获取区域实体 entity = await entity_registry.async_get_registry(hass) entity_list = entity_registry.async_entries_for_area( entity, area_item.id) for entity_item in entity_list: area_entity.update({ entity_item.entity_id: { "name": "location", "value": area_item.name, "scale": "", "timestampOfSample": timestampOfSample, "uncertaintyInMilliseconds": 10, "legalValue": "STRING" } }) # 获取所有设备 devices = [] states = hass.states.async_all() for state in states: # 过滤无效设置 if state.state == 'unavailable': continue attributes = state.attributes entity_id = state.entity_id domain = attributes.get('xiaodu_domain', state.domain) # 过滤空名称 friendly_name = get_friendly_name(attributes) if friendly_name is None: continue # 过滤非中文名称 if re.match(r'^[\u4e00-\u9fff]+$', friendly_name) is None: continue # 设备类型 device_type = attributes.get('xiaodu_type') # 默认开关操作 actions = ['setMode', 'unSetMode', 'timingSetMode', 'timingUnsetMode', \ "turnOn", "timingTurnOn", "turnOff", "timingTurnOff", "getTurnOnState", "setComplexActions", "getLocation"] if domain == 'switch' or domain == 'input_boolean': # 开关 device_type = attributes.get('xiaodu_type', 'SWITCH') elif domain == 'light': # 灯 device_type = 'LIGHT' actions.extend(["setBrightnessPercentage", "incrementBrightnessPercentage", "decrementBrightnessPercentage", \ "incrementColorTemperature", "decrementColorTemperature", "setColorTemperature", "setColor"]) elif domain == 'climate': # 空调 device_type = 'AIR_CONDITION' actions.extend(["incrementTemperature", "decrementTemperature", "setTemperature", \ 'getTemperatureReading', 'getTemperature', 'getTargetTemperature', 'getHumidity', 'getTargetHumidity', \ "incrementFanSpeed", "decrementFanSpeed", "setFanSpeed", "setGear"]) elif domain == 'cover': actions.extend(['pause', 'continue', 'setDirection']) # 窗帘 和 晾衣架 if '窗帘' in friendly_name: device_type = 'CURTAIN' elif '晾衣架' in friendly_name: device_type = 'CLOTHES_RACK' actions.extend(['incrementHeight', 'decrementHeight']) elif domain == 'media_player': actions.extend(['pause', 'continue', 'incrementVolume', 'decrementVolume', 'setVolume', 'setVolumeMute', \ 'decrementTVChannel', 'incrementTVChannel', 'setTVChannel']) if '电视' in friendly_name: device_type = 'TV_SET' actions.extend(['returnTVChannel']) elif domain == 'fan': actions.extend(['incrementFanSpeed', 'decrementFanSpeed', 'setFanSpeed', 'setGear', \ 'getTemperatureReading', 'getAirPM25', 'getAirPM10', 'getCO2Quantity', 'getAirQualityIndex', 'getTemperature', \ 'getTargetTemperature', 'getHumidity', 'getTargetHumidity']) if '净化' in friendly_name: device_type = 'AIR_PURIFIER' if '扇' in friendly_name: device_type = 'FAN' elif domain == 'scene': device_type = 'SCENE_TRIGGER' elif domain == 'camera': device_type = attributes.get('xiaodu_type', 'WEBCAM') actions.extend(['setDirection', 'reset']) # elif domain == 'script': # device_type = 'ACTIVITY_TRIGGER' elif domain == 'sensor': # ['getTargetHumidity', 'getTemperatureReading', 'getTargetTemperature'] if '温度传感器' == friendly_name: device_type = 'AIR_MONITOR' actions = ['getTemperature', 'getTemperatureReading'] elif '湿度传感器' == friendly_name: device_type = 'AIR_MONITOR' actions = ['getHumidity'] # 不支持设备 if device_type is None: continue # 移除开关操作 if ['sensor'].count(domain) > 0: remove_action(actions, 'turnOff') remove_action(actions, 'timingTurnOff') # 添加设备 devices.append({ 'applianceId': entity_id, 'friendlyName': friendly_name, 'friendlyDescription': friendly_name, 'additionalApplianceDetails': {}, 'applianceTypes': [device_type], 'isReachable': True, 'manufacturerName': 'HassLink', 'modelName': domain, 'version': '1.0', 'actions': actions, 'attributes': get_attributes(state) }) # 自定义设备 xiaodu_devices = attributes.get('xiaodu_devices', []) for xd in xiaodu_devices: name = xd['name'] devices.append({ 'applianceId': md5(name), 'friendlyName': name, 'friendlyDescription': name, 'additionalApplianceDetails': { 'service': xd['service'], 'data': xd.get('data', {}) }, 'applianceTypes': ["ACTIVITY_TRIGGER"], 'isReachable': True, 'manufacturerName': 'HassLink', 'modelName': "xiaodu", 'version': '1.0', 'actions': ["turnOn", "timingTurnOn"], 'attributes': {} }) return {'discoveredAppliances': devices}
async def discoveryDevice(hass): # 获取所有区域 area = await area_registry.async_get_registry(hass) area_list = area.async_list_areas() for area_item in area_list: # 获取区域实体 entity = await entity_registry.async_get_registry(hass) entity_list = entity_registry.async_entries_for_area( entity, area_item.id) for entity_item in entity_list: area_entity.update({entity_item.entity_id: area_item.name}) # 获取所有设备 devices = [] states = hass.states.async_all() for state in states: # 过滤无效设置 if state.state == 'unavailable': continue attributes = state.attributes entity_id = state.entity_id domain = attributes.get('tmall_domain', state.domain) # 过滤空名称 friendly_name = get_friendly_name(attributes) if friendly_name is None: continue # 过滤非中文名称 if re.match(r'^[\u4e00-\u9fff]+$', friendly_name) is None: continue # 设备类型 device_type = attributes.get('tmall_type') if domain == 'switch' or domain == 'input_boolean': # 开关 device_type = attributes.get('tmall_type', 'switch') elif domain == 'light': device_type = 'light' elif domain == 'climate': # 空调 device_type = 'aircondition' elif domain == 'cover': # 窗帘 和 晾衣架 if '窗帘' in friendly_name: device_type = 'curtain' elif '晾衣架' in friendly_name: device_type = 'hanger' elif domain == 'media_player': if '电视' in friendly_name: device_type = 'television' elif domain == 'fan': if '净化' in friendly_name: device_type = 'airpurifier' if '扇' in friendly_name: device_type = 'fan' elif domain == 'camera': device_type = 'camera' ''' elif domain == 'sensor': device_type = 'sensor' ''' # 不支持设备 if device_type is None: continue # 添加设备 devices.append({ 'deviceId': entity_id, 'deviceName': friendly_name, 'deviceType': device_type, 'brand': 'HASSKIT', 'model': 'x1', 'zone': area_entity.get(entity_id, ''), "status": get_attributes(state), "extensions": {} }) return {'devices': devices}