Esempio n. 1
0
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
    }
Esempio n. 2
0
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
Esempio n. 3
0
 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)
Esempio n. 4
0
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
Esempio n. 5
0
    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)
Esempio n. 6
0
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}
Esempio n. 7
0
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}