refactor(logger): 日志改用 logrus 全局包级调用,移除 Logger 注入接口

为什么:并入宿主项目后须与宿主日志体系一致——宿主统一用 pkg/logger 初始化
logrus 全局实例并直接 logrus.Xxx 包级调用;包一层 Logger 接口会让 logrus 的
caller 定位(报告调用文件:行号)失准。

改动:
- 删除 logger 包(Logger 接口 / Default / SetDefault,默认本就是 logrus.StandardLogger)
- 11 个结构体移除 lgr logger.Logger 字段、SetLogger 方法及构造中的 lgr 初始化
- 192 处 lgr.Xxxf 调用改为 logrus.Xxxf,日志消息文本保持不变
- xiaomi.Client 移除 Logger() 访问器,air_conditioner 回读日志去掉判空调用直连 logrus
- miot_i18n.go 两处标准库 log.Printf 改为 logrus.Errorf,统一日志出口
- go.mod:logrus 从 indirect 提升为直接依赖
- goimports/goformat 全树规范化:此前部分文件未 gofmt(单行 if、对齐),本次顺带
  格式化,纯空白/换行变化,无逻辑改动

验证:go build / go vet / go test ./... 全部通过(bridge、miot、xiaomi、devices、specs)
This commit is contained in:
2026-09-15 20:16:26 +08:00
parent 7ae32bd012
commit 2b7de69403
46 changed files with 1166 additions and 903 deletions
+43 -51
View File
@@ -9,6 +9,8 @@ import (
"xiaomihome/miot"
"xiaomihome/xiaomi"
"github.com/sirupsen/logrus"
)
// valMapper maps between device raw values and semantic names. Built from SPEC ValueList.
@@ -36,8 +38,8 @@ func newValMapper(vl miot.MIoTSpecValueList) *valMapper {
display = item.Name
}
key := strings.ToLower(display)
vm.val2name[v] = display // 原始描述做展示
vm.name2val[key] = v // 小写 key 做匹配
vm.val2name[v] = display // 原始描述做展示
vm.name2val[key] = v // 小写 key 做匹配
vm.names = append(vm.names, display)
}
return vm
@@ -122,7 +124,9 @@ func (vm *valMapper) levelValues() []int {
}
func (vm *valMapper) allNames() []string {
if vm == nil { return nil }
if vm == nil {
return nil
}
return vm.names
}
@@ -207,7 +211,7 @@ type AirConditioner interface {
// 功率
HasPower() bool
GetElectricPower(ctx context.Context) (float64, error) // 当前电功率(W)
GetElectricPower(ctx context.Context) (float64, error) // 当前电功率(W)
GetPowerConsumption(ctx context.Context) (float64, error) // 累计耗电量(kWh)
// 订阅
@@ -218,47 +222,47 @@ type AirConditioner interface {
// ACProps 空调完整状态(字段名对齐 SPEC type)
type ACProps struct {
On bool `json:"on"`
Mode string `json:"mode"` // SPEC ValueList 解析后的名称:cool/heat/fan/dry/auto
On bool `json:"on"`
Mode string `json:"mode"` // SPEC ValueList 解析后的名称:cool/heat/fan/dry/auto
TargetTemperature float64 `json:"targetTemperature"`
Temperature float64 `json:"temperature"`
TargetHumidity int `json:"targetHumidity"`
CurrentHumidity int `json:"currentHumidity"`
FanLevel string `json:"fanLevel"` // SPEC ValueList 解析后的名称:low/medium/high/auto
Swing string `json:"swing"` // SPEC ValueList 解析后的名称:off/vertical/horizontal/both
AuxHeat bool `json:"auxHeat"`
Eco bool `json:"eco"`
ElectricPower float64 `json:"electricPower"` // 当前电功率(W),来自 electric-power
PowerConsumption float64 `json:"powerConsumption"` // 累计耗电量(kWh),来自 power-consumption
TargetHumidity int `json:"targetHumidity"`
CurrentHumidity int `json:"currentHumidity"`
FanLevel string `json:"fanLevel"` // SPEC ValueList 解析后的名称:low/medium/high/auto
Swing string `json:"swing"` // SPEC ValueList 解析后的名称:off/vertical/horizontal/both
AuxHeat bool `json:"auxHeat"`
Eco bool `json:"eco"`
ElectricPower float64 `json:"electricPower"` // 当前电功率(W),来自 electric-power
PowerConsumption float64 `json:"powerConsumption"` // 累计耗电量(kWh),来自 power-consumption
}
type acDevice struct {
BaseDevice
propOn siidPiid // "on"
propMode siidPiid // "mode"
propTargetTemp siidPiid // "target-temperature"
propCurrentTemp siidPiid // "temperature"
propFanSpeed siidPiid // "fan-level"
propSwing siidPiid // "swing-mode" or "horizontal-swing" or "vertical-swing"
propTargetHumidity siidPiid // "target-humidity"
propCurrentHumidity siidPiid // "relative-humidity"
propAuxHeat siidPiid // "aux-heat" or "heater"
propEco siidPiid // "eco"
propElectricPower siidPiid // "electric-power"
propOn siidPiid // "on"
propMode siidPiid // "mode"
propTargetTemp siidPiid // "target-temperature"
propCurrentTemp siidPiid // "temperature"
propFanSpeed siidPiid // "fan-level"
propSwing siidPiid // "swing-mode" or "horizontal-swing" or "vertical-swing"
propTargetHumidity siidPiid // "target-humidity"
propCurrentHumidity siidPiid // "relative-humidity"
propAuxHeat siidPiid // "aux-heat" or "heater"
propEco siidPiid // "eco"
propElectricPower siidPiid // "electric-power"
propPowerConsumption siidPiid // "power-consumption"
modeMap *valMapper // SPEC value→name for mode
fanMap *valMapper // SPEC value→name for fan-level
modeMap *valMapper // SPEC value→name for mode
fanMap *valMapper // SPEC value→name for fan-level
swingMap *valMapper // SPEC value→name for swing
propsCache ACProps // MQTT 推送维护的本地缓存
// set 后回读(验证设置是否成功):记录目标值,防抖 + 重试比较
rbMu sync.Mutex
rbPending bool // 是否有回读调度在跑
rbLastSet time.Time // 最近一次 set 时间
rbTargets []rbTarget // 本次待验证的目标(聚合连续 set)
rbHandler func(props ACProps, changed string) // OnPropsChanged 注册的 handler
rbPending bool // 是否有回读调度在跑
rbLastSet time.Time // 最近一次 set 时间
rbTargets []rbTarget // 本次待验证的目标(聚合连续 set)
rbHandler func(props ACProps, changed string) // OnPropsChanged 注册的 handler
}
// rbTarget 回读验证目标:某属性本次 set 的目标值。
@@ -729,9 +733,7 @@ func (d *acDevice) recordReadback(name string, want interface{}) {
}
d.rbPending = true
d.rbMu.Unlock()
if d.client.Logger() != nil {
d.client.Logger().Debugf("[acDevice] readback scheduled: %s (%s) targets=%v\n", d.info.DID, d.info.Model, d.rbTargetNames())
}
logrus.Debugf("[acDevice] readback scheduled: %s (%s) targets=%v\n", d.info.DID, d.info.Model, d.rbTargetNames())
go d.readbackLoop()
}
@@ -768,9 +770,7 @@ func (d *acDevice) readbackLoop() {
}
props, err := d.FetchProps(ctx)
if err != nil {
if d.client.Logger() != nil {
d.client.Logger().Warnf("[acDevice] readback %s attempt %d failed: %v\n", d.info.DID, attempt, err)
}
logrus.Warnf("[acDevice] readback %s attempt %d failed: %v\n", d.info.DID, attempt, err)
if ctx.Err() != nil {
d.finishReadback("timeout")
return
@@ -782,9 +782,7 @@ func (d *acDevice) readbackLoop() {
d.finishReadbackOK(props, targets)
return
}
if d.client.Logger() != nil {
d.client.Logger().Debugf("[acDevice] readback %s attempt %d not applied yet: missed=%v\n", d.info.DID, attempt, missed)
}
logrus.Debugf("[acDevice] readback %s attempt %d not applied yet: missed=%v\n", d.info.DID, attempt, missed)
if attempt >= readbackMaxRetries {
d.finishReadback("not applied after retries")
return
@@ -810,9 +808,7 @@ func (d *acDevice) finishReadbackOK(props ACProps, targets []rbTarget) {
handler := d.rbHandler
d.rbMu.Unlock()
if handler == nil {
if d.client.Logger() != nil {
d.client.Logger().Warnf("[acDevice] readback %s done but handler not registered (OnPropsChanged never called)\n", d.info.DID)
}
logrus.Warnf("[acDevice] readback %s done but handler not registered (OnPropsChanged never called)\n", d.info.DID)
d.rbMu.Lock()
d.rbPending = false
d.rbMu.Unlock()
@@ -821,11 +817,9 @@ func (d *acDevice) finishReadbackOK(props ACProps, targets []rbTarget) {
for _, t := range targets {
handler(props, t.name)
}
if d.client.Logger() != nil {
d.client.Logger().Debugf("[acDevice] readback %s success: %v on=%v mode=%s target=%.0f temp=%.0f fan=%s hum=%d\n",
d.info.DID, d.rbTargetNamesLocked(), props.On, props.Mode, props.TargetTemperature,
props.Temperature, props.FanLevel, props.CurrentHumidity)
}
logrus.Debugf("[acDevice] readback %s success: %v on=%v mode=%s target=%.0f temp=%.0f fan=%s hum=%d\n",
d.info.DID, d.rbTargetNamesLocked(), props.On, props.Mode, props.TargetTemperature,
props.Temperature, props.FanLevel, props.CurrentHumidity)
d.rbMu.Lock()
d.rbPending = false
d.rbMu.Unlock()
@@ -838,9 +832,7 @@ func (d *acDevice) finishReadback(reason string) {
d.rbTargets = nil
d.rbPending = false
d.rbMu.Unlock()
if d.client.Logger() != nil {
d.client.Logger().Warnf("[acDevice] readback %s finished: %s targets=%v\n", d.info.DID, reason, names)
}
logrus.Warnf("[acDevice] readback %s finished: %s targets=%v\n", d.info.DID, reason, names)
}
func (d *acDevice) rbTargetNames() []string {