Files
xiaomihome/miot/const.go
T
4566704 8ffc9e4e44 refactor: 重构 token 管理,新增 NATS adapter 和多示例
按照 TOKEN_REFACTOR.md / FIX_CONFIG.md 方案重构核心层:
- miot: Init() 优先读 storage token,新增 RefreshAuthInfo() 和刷新回调
- xiaomi: Config 改用 AuthInfo 结构体(含 UUID/UID/DataDir/OnTokenRefreshed)
- xiaomi: NewClient(ctx, Config) 新签名,新增 RefreshToken(),后台自动刷新
- xiaomi/devices: 设备控制接口重构
- 新增示例 12_ac_subscribe,其余示例适配新 Config
2026-06-30 12:16:49 +08:00

280 lines
9.7 KiB
Go

// Package miot provides MIoT core client for Xiaomi Home devices.
// This file is a direct port of py-miot/const.py constants system.
package miot
import (
"fmt"
"strings"
)
// ============================================================================
// String constants (aligned with Python miot/const.py)
// ============================================================================
const (
DOMAIN = "xiaomi_home"
DEFAULT_NAME = "Xiaomi Home"
DEFAULT_NICK_NAME = "Xiaomi"
OAUTH2_CLIENT_ID = "2882303761520251711"
OAUTH2_AUTH_URL = "https://account.xiaomi.com/oauth2/authorize"
DEFAULT_OAUTH2_API_HOST = "ha.api.io.mi.com"
DEFAULT_CLOUD_BROKER_HOST = "ha.mqtt.io.mi.com"
DEFAULT_CLOUD_SERVER = "cn"
DEFAULT_CTRL_MODE = "auto"
DEFAULT_INTEGRATION_LANGUAGE = "en"
OAUTH_REDIRECT_URL = "http://homeassistant.local:8123"
)
// ============================================================================
// Numeric constants (aligned with Python miot/const.py)
// ============================================================================
const (
MIHOME_HTTP_API_TIMEOUT = 30
MIHOME_MQTT_KEEPALIVE = 60
// seconds, 3 days
MIHOME_CERT_EXPIRE_MARGIN = 3600 * 24 * 3
// seconds, 1 hour — token 过期前刷新(比 Python 60s 更保守)
MIHOME_REFRESH_THRESHOLD = 3600 * 6
NETWORK_REFRESH_INTERVAL = 30
// seconds, 14 days
SPEC_STD_LIB_EFFECTIVE_TIME = 3600 * 24 * 14
// seconds, 14 days
MANUFACTURER_EFFECTIVE_TIME = 3600 * 24 * 14
)
// ============================================================================
// Variables — slices, maps, and configurable values (aligned with Python miot/const.py)
// ============================================================================
var (
// SUPPORTED_PLATFORMS lists Home Assistant platforms supported by MIoT integration.
SUPPORTED_PLATFORMS = []string{
"binary_sensor",
"button",
"climate",
"cover",
"device_tracker",
"event",
"fan",
"humidifier",
"light",
"media_player",
"notify",
"number",
"select",
"sensor",
"switch",
"text",
"vacuum",
"water_heater",
}
// UNSUPPORTED_MODELS lists device models explicitly not supported.
UNSUPPORTED_MODELS = []string{
"chuangmi.ir.v2",
"era.airp.cwb03",
"hmpace.motion.v6nfc",
"k0918.toothbrush.t700",
}
// CLOUD_SERVERS maps cloud server region codes to human-readable names.
CLOUD_SERVERS = map[string]string{
"cn": "中国大陆",
"de": "Europe",
"i2": "India",
"ru": "Russia",
"sg": "Singapore",
"us": "United States",
}
// SUPPORT_CENTRAL_GATEWAY_CTRL lists regions that support central gateway control.
SUPPORT_CENTRAL_GATEWAY_CTRL = []string{"cn"}
// INTEGRATION_LANGUAGES maps language codes to human-readable names.
INTEGRATION_LANGUAGES = map[string]string{
"de": "Deutsch",
"en": "English",
"es": "Español",
"fr": "Français",
"it": "Italiano",
"ja": "日本語",
"nl": "Nederlands",
"pt": "Português",
"pt-BR": "Português (Brasil)",
"ru": "Русский",
"tr": "Türkçe",
"zh-Hans": "简体中文",
"zh-Hant": "繁體中文",
}
)
// Cover dead zone width — configurable at runtime.
var (
DEFAULT_COVER_DEAD_ZONE_WIDTH = 0
MIN_COVER_DEAD_ZONE_WIDTH = 0
MAX_COVER_DEAD_ZONE_WIDTH = 5
)
// ============================================================================
// CA Certificate constants (aligned with Python miot/const.py)
// ============================================================================
// MIHOME_CA_CERT_STR is the MIoT CA certificate in PEM format.
// Contains: Mijia Root CA + MIOT Central Gateway CA.
const MIHOME_CA_CERT_STR = `-----BEGIN CERTIFICATE-----
MIIBazCCAQ+gAwIBAgIEA/UKYDAMBggqhkjOPQQDAgUAMCIxEzARBgNVBAoTCk1p
amlhIFJvb3QxCzAJBgNVBAYTAkNOMCAXDTE2MTEyMzAxMzk0NVoYDzIwNjYxMTEx
MDEzOTQ1WjAiMRMwEQYDVQQKEwpNaWppYSBSb290MQswCQYDVQQGEwJDTjBZMBMG
ByqGSM49AgEGCCqGSM49AwEHA0IABL71iwLa4//4VBqgRI+6xE23xpovqPCxtv96
2VHbZij61/Ag6jmi7oZ/3Xg/3C+whglcwoUEE6KALGJ9vccV9PmjLzAtMAwGA1Ud
EwQFMAMBAf8wHQYDVR0OBBYEFJa3onw5sblmM6n40QmyAGDI5sURMAwGCCqGSM49
BAMCBQADSAAwRQIgchciK9h6tZmfrP8Ka6KziQ4Lv3hKfrHtAZXMHPda4IYCIQCG
az93ggFcbrG9u2wixjx1HKW4DUA5NXZG0wWQTpJTbQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIBjzCCATWgAwIBAgIBATAKBggqhkjOPQQDAjAiMRMwEQYDVQQKEwpNaWppYSBS
b290MQswCQYDVQQGEwJDTjAgFw0yMjA2MDkxNDE0MThaGA8yMDcyMDUyNzE0MTQx
OFowLDELMAkGA1UEBhMCQ04xHTAbBgNVBAoMFE1JT1QgQ0VOVFJBTCBHQVRFV0FZ
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdYrzbnp/0x/cZLZnuEDXTFf8mhj4
CVpZPwgj9e9Ve5r3K7zvu8Jjj7JF1JjQYvEC6yhp1SzBgglnK4L8xQzdiqNQME4w
HQYDVR0OBBYEFCf9+YBU7pXDs6K6CAQPRhlGJ+cuMB8GA1UdIwQYMBaAFJa3onw5
sblmM6n40QmyAGDI5sURMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIh
AKUv+c8v98vypkGMTzMwckGjjVqTef8xodsy6PhcSCq+AiA/n9mDs62hAo5zXyJy
Bs1s7mqXPf1XgieoxIvs1MqyiA==
-----END CERTIFICATE-----`
// MIHOME_CA_CERT_SHA256 is the SHA256 hash of the MIoT CA certificate.
const MIHOME_CA_CERT_SHA256 = "8b7bf306be3632e08b0ead308249e5f2b2520dc921ad143872d5fcc7c68d6759"
// ============================================================================
// CtrlMode — control mode enum (migrated from deleted constants.go)
// ============================================================================
// CtrlMode represents the control mode for devices.
type CtrlMode int
const (
// CtrlModeCloud represents cloud control mode.
CtrlModeCloud CtrlMode = iota
// CtrlModeGateway represents gateway control mode.
CtrlModeGateway
// CtrlModeLAN represents LAN control mode.
CtrlModeLAN
// CtrlModeAuto represents auto control mode.
CtrlModeAuto
)
// String returns the string representation of CtrlMode.
func (m CtrlMode) String() string {
switch m {
case CtrlModeAuto:
return "auto"
case CtrlModeCloud:
return "cloud"
case CtrlModeGateway:
return "gateway"
case CtrlModeLAN:
return "lan"
default:
return "unknown"
}
}
// ParseCtrlMode parses a string into a CtrlMode value.
// "cloud" → CtrlModeCloud, "gateway" → CtrlModeGateway, "lan" → CtrlModeLAN.
// Returns an error for unknown strings.
// Aligns with Python: CtrlMode.load(mode).
func ParseCtrlMode(s string) (CtrlMode, error) {
switch strings.ToLower(s) {
case "auto":
return CtrlModeAuto, nil
case "cloud":
return CtrlModeCloud, nil
case "gateway":
return CtrlModeGateway, nil
case "lan":
return CtrlModeLAN, nil
default:
return 0, fmt.Errorf("unknown ctrl mode: %s", s)
}
}
// ============================================================================
// Refresh / retry timings (migrated from deleted constants.go)
// ============================================================================
// RefreshPropsDelay is the delay before executing property refresh (200ms, aligns with Python).
const RefreshPropsDelay = 200
// RefreshPropsRetryMax is the maximum number of retries for property refresh (3, aligns with Python).
const RefreshPropsRetryMax = 3
// RefreshPropsRetryDelay is the delay between property refresh retries (3s, aligns with Python).
const RefreshPropsRetryDelay = 3 * 1000 // 3 seconds in milliseconds
// RefreshCloudDevicesDelay is the delay before refreshing cloud devices (6s, aligns with Python).
const RefreshCloudDevicesDelay = 6 * 1000 // 6 seconds in milliseconds
// RefreshCloudDevicesRetryDelay is the delay before retrying cloud device refresh (60s, aligns with Python).
const RefreshCloudDevicesRetryDelay = 60 * 1000 // 60 seconds in milliseconds
// TokenRefreshInterval is the interval for refreshing OAuth token (aligns with Python).
const TokenRefreshInterval = 3600 * 1000 // 1 hour in milliseconds
// CertRefreshInterval is the interval for refreshing certificate (aligns with Python).
const CertRefreshInterval = 24 * 3600 * 1000 // 24 hours in milliseconds
// RefreshAuthRetryDelay is the delay before retrying token refresh (3600s, aligns with Python).
const RefreshAuthRetryDelay = 3600
// RefreshCertRetryDelay is the delay before retrying cert refresh (300s, aligns with Python).
const RefreshCertRetryDelay = 300
// ============================================================================
// MQTT topics (migrated from deleted constants.go)
// ============================================================================
// TopicProp is the MQTT topic for property changes.
const TopicProp = "properties_changed"
// TopicEvent is the MQTT topic for event occurrences.
const TopicEvent = "event_occured"
// TopicState is the MQTT topic for device state changes.
const TopicState = "state"
// ============================================================================
// API paths / defaults (migrated from deleted constants.go)
// ============================================================================
// APIPathGetDevices is the API path for getting devices.
const APIPathGetDevices = "/v2/home/device/list"
// APIPathGetProps is the API path for getting properties.
const APIPathGetProps = "/v2/home/device/prop/get"
// APIPathSetProps is the API path for setting properties.
const APIPathSetProps = "/v2/home/device/prop/set"
// APIPathDoAction is the API path for executing actions.
const APIPathDoAction = "/v2/home/device/action"
// DefaultCloudServer is the default cloud server.
const DefaultCloudServer = "cn"
// DefaultOAUTH2APIHost is the default OAuth2 API host (aligned with Python).
const DefaultOAUTH2APIHost = "ha.api.io.mi.com"
// MHomeHTTPAPITimeout is the HTTP API timeout in seconds (aligned with Python).
const MHomeHTTPAPITimeout = 30
// DefaultMQTTBroker is the default MQTT broker address.
const DefaultMQTTBroker = "ssl://cn-ha.mqtt.io.mi.com:8883"
// DefaultMQTTKeepAlive is the default MQTT keep-alive interval in seconds.
const DefaultMQTTKeepAlive = 60
// DefaultMQTTQoS is the default MQTT QoS level.
const DefaultMQTTQoS = 1