package devices import ( "context" "fmt" "xiaomihome/xiaomi" ) // TempHumiditySensor 温湿度传感器读取接口(只读)。 type TempHumiditySensor interface { Device GetTemperature(ctx context.Context) (float64, error) GetHumidity(ctx context.Context) (float64, error) } // NewTempHumiditySensor 创建温湿度传感器。失败返回错误(含无 SPEC / 无相关属性)。 func NewTempHumiditySensor(client *xiaomi.Client, info *xiaomi.DeviceInfo) (TempHumiditySensor, error) { if info == nil { return nil, xiaomi.ErrDeviceNotFound } miotDev := client.GetMIoTDevice(info.DID) if miotDev == nil { return nil, fmt.Errorf("%w: device not initialized", xiaomi.ErrDeviceNotFound) } spec := miotDev.SpecInstance() if spec == nil { return nil, fmt.Errorf("%w: device has no SPEC information", xiaomi.ErrNotSupported) } d := &tempHumidityDevice{ BaseDevice: BaseDevice{client: client, info: info}, } for _, svc := range spec.Services { for _, prop := range svc.Properties { switch propertyShortName(prop.Type) { case "temperature": if !d.propTemp.valid { d.propTemp = siidPiid{svc.IID, prop.PIID, true} } case "relative-humidity": if !d.propHumidity.valid { d.propHumidity = siidPiid{svc.IID, prop.PIID, true} } } } } if !d.propTemp.valid && !d.propHumidity.valid { return nil, fmt.Errorf("%w: no temperature or humidity property in SPEC", xiaomi.ErrNotSupported) } return d, nil } type tempHumidityDevice struct { BaseDevice propTemp siidPiid propHumidity siidPiid } func (d *tempHumidityDevice) GetTemperature(ctx context.Context) (float64, error) { if !d.propTemp.valid { return 0, xiaomi.ErrNotSupported } prop, err := d.GetProp(ctx, d.propTemp.siid, d.propTemp.piid) if err != nil { return 0, err } return toFloat(prop.Value), nil } func (d *tempHumidityDevice) GetHumidity(ctx context.Context) (float64, error) { if !d.propHumidity.valid { return 0, xiaomi.ErrNotSupported } prop, err := d.GetProp(ctx, d.propHumidity.siid, d.propHumidity.piid) if err != nil { return 0, err } return toFloat(prop.Value), nil }