package devices import ( "context" "xiaomihome/xiaomi" ) // WaterHeater 热水器统一控制接口 type WaterHeater interface { Device TurnOn(ctx context.Context) error TurnOff(ctx context.Context) error IsOn(ctx context.Context) (bool, error) SetTargetTemp(ctx context.Context, celsius float64) error GetTargetTemp(ctx context.Context) (float64, error) GetCurrentTemp(ctx context.Context) (float64, error) } type waterHeaterDevice struct { BaseDevice propOn siidPiid // "on" propTargetTemp siidPiid // "target-temperature" propCurrentTemp siidPiid // "temperature" } // NewWaterHeater creates a WaterHeater control for the given device. func NewWaterHeater(client *xiaomi.Client, info *xiaomi.DeviceInfo) (WaterHeater, error) { d := &waterHeaterDevice{ BaseDevice: NewBaseDevice(client, info), } resolver := d.getSpecResolver() if resolver == nil { return nil, xiaomi.ErrNoSPEC } siid, piid, ok := resolver.find("on") if !ok { return nil, xiaomi.ErrNotSupported } d.propOn = siidPiid{siid, piid, true} if s, p, ok := resolver.find("target-temperature"); ok { d.propTargetTemp = siidPiid{s, p, true} } if s, p, ok := resolver.find("temperature"); ok { d.propCurrentTemp = siidPiid{s, p, true} } return d, nil } func (d *waterHeaterDevice) TurnOn(ctx context.Context) error { if !d.propOn.valid { return xiaomi.ErrNotSupported } return d.SetProp(ctx, d.propOn.siid, d.propOn.piid, true) } func (d *waterHeaterDevice) TurnOff(ctx context.Context) error { if !d.propOn.valid { return xiaomi.ErrNotSupported } return d.SetProp(ctx, d.propOn.siid, d.propOn.piid, false) } func (d *waterHeaterDevice) IsOn(ctx context.Context) (bool, error) { if !d.propOn.valid { return false, xiaomi.ErrNotSupported } prop, err := d.GetProp(ctx, d.propOn.siid, d.propOn.piid) if err != nil { return false, err } if b, ok := prop.Value.(bool); ok { return b, nil } return false, nil } func (d *waterHeaterDevice) SetTargetTemp(ctx context.Context, celsius float64) error { if !d.propTargetTemp.valid { return xiaomi.ErrNotSupported } return d.SetProp(ctx, d.propTargetTemp.siid, d.propTargetTemp.piid, celsius) } func (d *waterHeaterDevice) GetTargetTemp(ctx context.Context) (float64, error) { if !d.propTargetTemp.valid { return 0, xiaomi.ErrNotSupported } prop, err := d.GetProp(ctx, d.propTargetTemp.siid, d.propTargetTemp.piid) if err != nil { return 0, err } return toFloat(prop.Value), nil } func (d *waterHeaterDevice) GetCurrentTemp(ctx context.Context) (float64, error) { if !d.propCurrentTemp.valid { return 0, xiaomi.ErrNotSupported } prop, err := d.GetProp(ctx, d.propCurrentTemp.siid, d.propCurrentTemp.piid) if err != nil { return 0, err } return toFloat(prop.Value), nil }