Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

云米C1烟机状态属性过少,无法获取灶头状态,无法设置延迟关机时间。 #1826

Closed
jarod360 opened this issue Aug 18, 2024 · 3 comments

Comments

@jarod360
Copy link

jarod360 commented Aug 18, 2024

Device model / 设备型号

viomi.hood.c1

Component version / 插件版本

0.7.19

HA core version / HA版本

2023.12.4

Integrated mode / 集成方式

Local (本地模式)

The problem / 问题详情

云米C1烟机本地控制,可以正常控制烟机的转速大小和灯光,从开发文档获知,stove1_is_on stove2_is_on 是灶头的大小火状态,poweroff_delaytime是延迟关机时间,可以直接对设备赋值设置延迟关机时间。link_state表示设备的联动状态。之前通过chatGPT写了一个自定义插件脚本,希望大佬能增加烟机的其他状态属性。脚本如下:

import voluptuous as vol
import homeassistant.helpers.config_validation as cv
from homeassistant.exceptions import PlatformNotReady
from homeassistant.components.fan import FanEntity, SUPPORT_PRESET_MODE
from homeassistant.const import ATTR_ENTITY_ID, CONF_NAME, CONF_HOST, CONF_TOKEN
from datetime import timedelta
from miio import Device, DeviceException
from . import DOMAIN
import logging

_LOGGER = logging.getLogger(__name__)

SERVICE_SET_LIGHT_ON = "set_light_on"
SERVICE_SET_LIGHT_OFF = "set_light_off"
SET_LIGHT_SCHEMA = vol.Schema({
    vol.Required(ATTR_ENTITY_ID): cv.entity_id
})

YUNMI_FAN_DEVICES = "yunmi_fan_devices"

# 设置速度等级
SPEED_LEVELS = [0, 1, 16, 4]
PRESET_MODE_OFF = "off"
PRESET_MODES = {0: PRESET_MODE_OFF, 1: "low", 16: "high", 4: "stir-fry"}

async def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
    host = config.get(CONF_HOST)
    name = config.get(CONF_NAME)
    token = config.get(CONF_TOKEN)
    _LOGGER.info("Initializing Yunmi Hood with host %s (token %s...)", host, token[:5])

    devices = []
    try:
        device = Device(host, token)
        yumihood = YunmiHood(device, name, token[:6])
        devices.append(yumihood)
        async_add_devices(devices, True)
        hass.data[YUNMI_FAN_DEVICES] = devices
    except DeviceException:
        _LOGGER.error('Failed to setup Yunmi Hood')
        raise PlatformNotReady

    async def async_service_handle(service):
        entity_id = service.data[ATTR_ENTITY_ID]
        device = next((fan for fan in hass.data[YUNMI_FAN_DEVICES] if
                       fan.entity_id == entity_id), None)
        if device is None:
            _LOGGER.warning("Unable to find Yunmi Hood device %s", entity_id)
            return

        if service.service == SERVICE_SET_LIGHT_ON:
            await device.async_set_light_on()
        elif service.service == SERVICE_SET_LIGHT_OFF:
            await device.async_set_light_off()
    hass.services.async_register(DOMAIN, SERVICE_SET_LIGHT_ON, async_service_handle, schema=SET_LIGHT_SCHEMA)
    hass.services.async_register(DOMAIN, SERVICE_SET_LIGHT_OFF, async_service_handle, schema=SET_LIGHT_SCHEMA)
class YunmiHood(FanEntity):
    def __init__(self, device, name, unique_id) -> None:
        self._device = device
        self._name = name
        self._unique_id = unique_id
        self._supported_features = SUPPORT_PRESET_MODE
        self._is_on = False
        self._is_light_on = False
        self._preset_mode = PRESET_MODE_OFF # Initialize to off
        self._state_attrs = {
            "stove1_is_on": None,
            "stove2_is_on": None,
            "is_light_on": None,
            "preset_mode": None
        }
    @property
    def unique_id(self):
        return self._unique_id

    @property
    def name(self) -> str:
        return self._name

    @property
    def supported_features(self) -> int:
        return self._supported_features

    @property
    def state_attributes(self):
        return self._state_attrs

    async def async_update(self):
        power_state = await self.hass.async_add_executor_job(
            lambda: self._device.send('get_prop', ["power_state"])[0])
        light_state = await self.hass.async_add_executor_job(
            lambda: self._device.send('get_prop', ["light_state"])[0])
        link_state = await self.hass.async_add_executor_job(  
            lambda: self._device.send('get_prop', ["link_state"])[0])
            
        if link_state == 2:
            stove1_data = await self.hass.async_add_executor_job(
                lambda: self._device.send('get_prop', ["stove1_data"])[0])
            stove2_data = await self.hass.async_add_executor_job(
                lambda: self._device.send('get_prop', ["stove2_data"])[0])
        else:
            stove1_data = 0
            stove2_data = 0
            
        preset_mode = await self.hass.async_add_executor_job(
            lambda: self._device.send('get_prop', ["wind_state"])[0])
        run_time = await self.hass.async_add_executor_job(  
            lambda: self._device.send('get_prop', ["run_time"])[0])
        run_status = await self.hass.async_add_executor_job(  
            lambda: self._device.send('get_prop', ["run_status"])[0])
        poweroff_delaytime = await self.hass.async_add_executor_job(  
            lambda: self._device.send('get_prop', ["poweroff_delaytime"])[0])
            
        self._is_on = power_state == 2
        self._is_light_on = light_state != 0

        # 处理模式选择的信息
        self._preset_mode = PRESET_MODES.get(preset_mode, PRESET_MODE_OFF)

        # 更新状态属性
        self._state_attrs.update({
            "stove1_is_on": stove1_data,
            "stove2_is_on": stove2_data,
            "is_light_on": self._is_light_on,
            "preset_mode": self._preset_mode,
            "run_time": run_time,
            "run_status": run_status,
            "link_state": link_state,
            "poweroff_delaytime": poweroff_delaytime
        })

    @property
    def is_on(self) -> bool:
        return self._is_on

    @property
    def preset_modes(self) -> list:
        return list(PRESET_MODES.values())

    @property
    def preset_mode(self) -> str:
        return self._preset_mode

    async def async_set_preset_mode(self, preset_mode: str) -> None:
        for mode, mode_name in PRESET_MODES.items():
            if mode_name == preset_mode:
                await self.hass.async_add_executor_job(
                    lambda: self._device.send('set_wind', [mode]))
                await self.async_update()
                break

    async def async_set_light_on(self) -> None:
        if not self._is_light_on:
            await self.hass.async_add_executor_job(
                lambda: self._device.send('set_light', [1]))
            self._is_light_on = True
            self._state_attrs.update({"is_light_on": True})
            await self.async_update()
    async def async_set_light_off(self) -> None:
        if self._is_light_on:
            await self.hass.async_add_executor_job(
                lambda: self._device.send('set_light', [0]))
            self._is_light_on = False
            self._state_attrs.update({"is_light_on": False})
            await self.async_update()

    async def async_turn_on(self, *args, **kwargs) -> None:
        if not self._is_on:
            await self.hass.async_add_executor_job(
                lambda: self._device.send('set_power', [2]))
            self._is_on = True
            await self.async_update()

    async def async_turn_off(self, **kwargs) -> None:
        if self._is_on:
            await self.hass.async_add_executor_job(
                lambda: self._device.send('set_power', [0]))
            self._is_on = False
            await self.async_update()

Entity attributes / 实体属性

preset_modes: []
percentage: null
percentage_step: 33
preset_mode: null
model: viomi.hood.c1
lan_ip: 192.168.0.87
mac_address: 40:31:3C:77:AC:0D
entity_class: MiotFanEntity
home_room: 我的家 厨房
miot_type: urn:miot-spec-v2:device:hood:0000A01B:viomi-c1:1
hood.on.error: "-4004 Other internal errors"
environment.pm2_5_density.error: "-4004 Other internal errors"
light.on.error: "-4004 Other internal errors"
fan_control.fan_level.error: "-4004 Other internal errors"
state_updater: lan
friendly_name: 抽油烟机 Hood
supported_features: 1

Home Assistant Logs / 系统日志

No response

@al-one
Copy link
Owner

al-one commented Nov 4, 2024

尝试master分支

@jarod360
Copy link
Author

jarod360 commented Nov 4, 2024

尝试master分支

感谢大佬目前控制正常,但是有个问题。状态属性中stove1_data: 0
stove2_data: 2 stove1_data和stove2_data代表左右灶头的状态,0表示关闭 1表示小火2表示大火 目前获取的状态是错误的。显示的右灶头大火,实际为已经关闭,关闭前是大火。其他没有任何问题。

@jarod360
Copy link
Author

jarod360 commented Nov 4, 2024

已经解决,通过先判断link_state:1 的值为1时为灶头未开,为2时为灶头打开,再去获取stove1_data和2的值时就可以。无需修改。感谢老大的本地化。

@al-one al-one closed this as completed Nov 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants