package xiaomi import ( "sort" "strings" ) // deviceTypeToKind maps SPEC URN device types to Kind. // URN format: urn:miot-spec-v2:device:{TYPE}:... var deviceTypeToKind = map[string]Kind{ "air-conditioner": KindAirConditioner, "air-condition-outlet": KindAirConditioner, "air-condition-eco": KindAirConditioner, "airer": KindAirConditioner, "ac-partner": KindAirConditioner, "light": KindLight, "lightbulb": KindLight, "night-light": KindLight, "ceiling-light": KindLight, "switch": KindSwitch, "powerstrip": KindSwitch, "toggle-switch": KindSwitch, "wireless-switch": KindSwitch, "curtain-switch": KindSwitch, "fan": KindFan, "ceiling-fan": KindFan, "ventilator": KindFan, "air-fresh": KindFan, "air-purifier": KindFan, "curtain": KindCover, "airer-rack": KindCover, "humidifier": KindHumidifier, "dehumidifier": KindHumidifier, "humidifier-dehumidifier": KindHumidifier, "vacuum": KindVacuum, "sweeper": KindVacuum, "robot-cleaner": KindVacuum, "water-heater": KindWaterHeater, "water-cooler": KindWaterHeater, "kettle": KindWaterHeater, "heater": KindThermostat, "electric-blanket": KindThermostat, "thermostat": KindThermostat, "speaker": KindSpeaker, "bluetooth-speaker": KindSpeaker, "alarm-clock": KindSpeaker, "media-player": KindSpeaker, "playback": KindSpeaker, "music": KindSpeaker, "gateway": KindGateway, "plug": KindPlug, "outlet": KindPlug, "sensor-occupy": KindOccupancySensor, "sensor_occupy": KindOccupancySensor, "occupancy-sensor": KindOccupancySensor, "occupancy_sensor": KindOccupancySensor, "motion-sensor": KindOccupancySensor, "motion_sensor": KindOccupancySensor, "magnet": KindOccupancySensor, "sensor": KindSensor, "sensor-ht": KindSensor, "sensor_ht": KindSensor, "sensor-temp": KindSensor, "sensor_temp": KindSensor, "sensor-humidity": KindSensor, "sensor_humidity": KindSensor, "illumination": KindSensor, "sensor-smoke": KindSensor, "sensor_gasm": KindSensor, "sensor-gasm": KindSensor, } // classifyKeys 按长度降序排列的 key,保证长/具体 key 先匹配(如 sensor-occupy 先于 sensor)。 var classifyKeys = func() []string { keys := make([]string, 0, len(deviceTypeToKind)) for k := range deviceTypeToKind { keys = append(keys, k) } sort.Slice(keys, func(i, j int) bool { return len(keys[i]) > len(keys[j]) }) return keys }() // Classify 从 DeviceInfo 判断设备种类。 // 优先从 URN 的 device type 段精确提取,降至 model 子串匹配。 func Classify(info *DeviceInfo) Kind { if info == nil { return KindUnknown } // 从 URN 精确解析 device type if k := classifyByURN(info.URN); k != KindUnknown { return k } // 降至 model 匹配 if k := classifyByModel(info.Model); k != KindUnknown { return k } return KindUnknown } // classifyByURN 从 URN 中提取 device type 并映射 Kind。 func classifyByURN(urn string) Kind { parts := strings.Split(urn, ":") if len(parts) >= 4 && parts[2] == "device" { if k, ok := deviceTypeToKind[parts[3]]; ok { return k } } return KindUnknown } // classifyByModel 对 model 字符串做子串匹配(用于无 URN 或 URN 不标准时)。 // 按 key 长度降序匹配,保证 sensor-occupy 先于 sensor。 func classifyByModel(model string) Kind { model = strings.ToLower(model) for _, t := range classifyKeys { if strings.Contains(model, t) { return deviceTypeToKind[t] } } return KindUnknown } // FilterByKind 按设备种类过滤。 func FilterByKind(kind Kind) DeviceFilter { return func(d *DeviceInfo) bool { return d.DeviceKind() == kind } } // Or 返回任意一个 filter 满足即通过的组合过滤器。 func Or(filters ...DeviceFilter) DeviceFilter { return func(d *DeviceInfo) bool { for _, f := range filters { if f(d) { return true } } return false } }