feat: 初始化小米 IoT (MIoT) 智能家居 Go 库
- 实现 MIoT 客户端核心功能(MQTT 连接、设备管理、属性读写) - 支持云端 API 调用与局域网设备发现(mDNS) - 集成国际化(i18n)多语言支持 - 添加 MIoT 设备规约解析器(spec_parser) - 包含单元测试与使用示例
This commit is contained in:
+277
@@ -0,0 +1,277 @@
|
||||
// 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
|
||||
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
|
||||
Reference in New Issue
Block a user