docs(iot): 存量英文注释中文化(仅注释,代码零字节改动)

- 5 个文件:123 行英文注释 → 99 行中文注释(中文更紧凑,内容无删减)。
- 机械校验(git diff -U0 去掉 // 行与空行)输出为空;gofmt -l 干净(改动前亦干净)。
- 验收:go build/vet/test ./internal/iot/... 全绿。
This commit is contained in:
AskaEth committed 2026-10-04 16:58:00 +08:00
1 parent 127c32b440
commit 2593765add
5 files changed
+99 -123

No files matched your search

+39 -50
View File
@@ -1,72 +1,62 @@
// Package iot provides the IoT device source abstraction for Cyrene v2. // Package iot 提供 Cyrene v2 的 IoT 设备来源抽象。
// //
// It models smart-home devices (light, AC, curtain, sensor, lock) as typed // 它把智能家居设备(灯、空调、窗帘、传感器、门锁)建模为强类型设备,交由可插拔的
// devices managed by pluggable providers. A Provider is a device source; the // Provider 管理。Provider 即设备来源;Manager 依据配置选定 Provider,对外提供
// Manager selects a provider from configuration, exposes List/Control/Status, // List/Control/Status,并把设备状态跃迁作为事件发布到进程内 bus,使其他子系统
// and publishes device state transitions as events on the in-process bus so // (前端、记忆、推送)无需轮询即可感知设备变化(对照
// other subsystems (frontend, memory, push) observe changes without polling // DevDocs/02-development-constraints.md "IoT 设备状态 bus 事件驱动")。
// (DevDocs/02-development-constraints.md "IoT 设备状态 bus 事件驱动").
// //
// Milestone M5 delivers the pluggable provider skeleton plus a mock provider // 里程碑 M5 交付可插拔 Provider 骨架,外加一个 mock Provider:内置八台模拟设备,
// with eight simulated devices and the control_rules that bound what each device // 以及界定每种设备类型支持范围的 control_rules。真实 Provider 集成(MQTT、
// type supports. Real provider integrations (MQTT, Home Assistant) plug in later // Home Assistant)后续通过同一套 Provider 接口接入。
// through the same Provider interface.
package iot package iot
import "errors" import "errors"
// DeviceUpdateSubject is the bus subject on which device state transitions are // DeviceUpdateSubject 是设备状态跃迁事件发布所用的 bus 主题。订阅方使用该主题
// published. Subscribers use this subject (or "iot.>") to observe device // (或 "iot.>")观察设备变化。
// changes.
const DeviceUpdateSubject = "iot.device_update" const DeviceUpdateSubject = "iot.device_update"
// Sentinel errors returned by the iot subsystem. Use errors.Is to test for them. // iot 子系统返回的哨兵错误,判定时请用 errors.Is。
var ( var (
// ErrDeviceNotFound is returned when a device ID is unknown to every // ErrDeviceNotFound 表示该设备 ID 对全部已注册 Provider 均未知。
// registered provider.
ErrDeviceNotFound = errors.New("iot: device not found") ErrDeviceNotFound = errors.New("iot: device not found")
// ErrUnsupported is returned when an action is not supported for a device's // ErrUnsupported 表示某动作不被该设备类型支持(受该类型的 capability 约束),
// type (the device type's capability constraint), or when an action // 或动作参数取值超出该类型的规则集合。
// parameter value is outside the type's rule set.
ErrUnsupported = errors.New("iot: unsupported action") ErrUnsupported = errors.New("iot: unsupported action")
// ErrOffline is returned when a Control call targets an offline device. // ErrOffline 表示 Control 调用指向了离线设备。
ErrOffline = errors.New("iot: device offline") ErrOffline = errors.New("iot: device offline")
// ErrInvalidParam is returned when an action parameter is missing or has the // ErrInvalidParam 表示动作参数缺失或类型错误。
// wrong type.
ErrInvalidParam = errors.New("iot: invalid parameter") ErrInvalidParam = errors.New("iot: invalid parameter")
// ErrUnknownProvider is returned when configuration names an unknown // ErrUnknownProvider 表示配置指定了未知的 Provider。
// provider.
ErrUnknownProvider = errors.New("iot: unknown provider") ErrUnknownProvider = errors.New("iot: unknown provider")
// ErrProviderNotRegistered is returned when a device operation is attempted // ErrProviderNotRegistered 表示尝试执行设备操作,但没有任何已注册的 Provider
// but no provider is registered (for example the "none" provider). // (例如 "none" Provider)。
ErrProviderNotRegistered = errors.New("iot: no provider registered") ErrProviderNotRegistered = errors.New("iot: no provider registered")
// ErrInvalidArgument is returned when an argument is nil or empty. // ErrInvalidArgument 表示传入参数为 nil 或空。
ErrInvalidArgument = errors.New("iot: invalid argument") ErrInvalidArgument = errors.New("iot: invalid argument")
// ErrDuplicate is returned when a provider with the same name is registered // ErrDuplicate 表示同名 Provider 被注册了两次。
// twice.
ErrDuplicate = errors.New("iot: provider already registered") ErrDuplicate = errors.New("iot: provider already registered")
) )
// Device is a single smart-home device exposed by a Provider. // Device 是由某个 Provider 暴露的单台智能家居设备。
type Device struct { type Device struct {
// ID is the globally unique device identifier used to target Control and // ID 是设备全局唯一标识,Control 与 Status 调用据此定位设备。
// Status calls.
ID string `json:"id"` ID string `json:"id"`
// Name is the human-readable device label. // Name 是供人阅读的设备名称。
Name string `json:"name"` Name string `json:"name"`
// Type is the device kind, for example "light", "ac", "curtain", "sensor" or // Type 是设备种类,例如 "light"、"ac"、"curtain"、"sensor"、"lock";
// "lock". The type determines the control_rules a Provider enforces. // 类型决定 Provider 施加的 control_rules。
Type string `json:"type"` Type string `json:"type"`
// State holds the device's current key/value state; the keys depend on the // State 保存设备当前的键值状态;具体键取决于设备的 Type。
// device Type.
State map[string]any `json:"state"` State map[string]any `json:"state"`
// Online reports whether the device is currently reachable. // Online 表示设备当前是否可达。
Online bool `json:"online"` Online bool `json:"online"`
} }
// Clone returns a copy of d with an independent State map, so callers can mutate // Clone 返回 d 的副本,其中 State 为独立 map,因此调用方可以随意修改返回的设备
// the returned device without affecting the provider's internal state. Values in // 而不影响 Provider 的内部状态。State 中的值按引用复制;mock Provider 只存放
// State are copied by reference; the mock provider stores only primitives. // 基本类型值。
func (d Device) Clone() Device { func (d Device) Clone() Device {
cp := d cp := d
if d.State != nil { if d.State != nil {
@@ -78,18 +68,17 @@ func (d Device) Clone() Device {
return cp return cp
} }
// DeviceUpdate is the payload published to DeviceUpdateSubject when a device // DeviceUpdate 是设备状态跃迁时发布到 DeviceUpdateSubject 的载荷,通常由一次
// state transitions, typically as the result of a Control call. // Control 调用产生。
type DeviceUpdate struct { type DeviceUpdate struct {
// Provider is the name of the provider that owns the device. // Provider 是拥有该设备的 Provider 名称。
Provider string `json:"provider"` Provider string `json:"provider"`
// Device is the post-transition device snapshot. // Device 是跃迁后的设备快照。
Device Device `json:"device"` Device Device `json:"device"`
// Action is the control action that produced the transition. // Action 是触发该次跃迁的控制动作。
Action string `json:"action"` Action string `json:"action"`
// Params are the optional control parameters. // Params 是可选的控制参数。
Params map[string]any `json:"params,omitempty"` Params map[string]any `json:"params,omitempty"`
// Message is a human-readable summary of the transition, surfaced to the // Message 是跃迁的可读摘要,会呈现到前端的 device_update 信息流中。
// frontend device_update feed.
Message string `json:"message,omitempty"` Message string `json:"message,omitempty"`
} }
+3 -3
View File
@@ -10,8 +10,8 @@ import (
"git.yeij.top/AskaEth/Cyrene_v2/internal/config" "git.yeij.top/AskaEth/Cyrene_v2/internal/config"
) )
// fakeProvider is a stub Provider used to exercise Manager.Register and the // fakeProvider 是桩 Provider,用于验证 Manager.Register 与设备操作路由,
// device-operation routing without touching the concrete mockProvider. // 而不触碰具体的 mockProvider。
type fakeProvider struct { type fakeProvider struct {
name string name string
device Device device Device
@@ -40,7 +40,7 @@ func (f fakeProvider) Status(_ context.Context, id string) (*Device, error) {
return &cp, nil return &cp, nil
} }
// recvIoT blocks until a DeviceUpdate is delivered or the deadline passes. // recvIoT 阻塞等待,直到收到一条 DeviceUpdate 或超过等待时限。
func recvIoT(t *testing.T, ch <-chan DeviceUpdate, d time.Duration) DeviceUpdate { func recvIoT(t *testing.T, ch <-chan DeviceUpdate, d time.Duration) DeviceUpdate {
t.Helper() t.Helper()
select { select {
+27 -32
View File
@@ -13,35 +13,32 @@ import (
"git.yeij.top/AskaEth/Cyrene_v2/internal/logger" "git.yeij.top/AskaEth/Cyrene_v2/internal/logger"
) )
// Manager is the IoT subsystem facade. It selects a Provider from // Manager 是 IoT 子系统的门面:依据配置选定 Provider,对外提供
// configuration, serves List/Control/Status, and publishes device state // List/Control/Status,并把设备状态跃迁以 DeviceUpdate 事件的形式发布到进程内 bus。
// transitions on the in-process bus as DeviceUpdate events.
type Manager struct { type Manager struct {
providers []Provider providers []Provider
bus bus.Bus bus bus.Bus
log *slog.Logger log *slog.Logger
} }
// Option customizes a Manager built by New. // Option 用于定制由 New 构建的 Manager。
type Option func(*Manager) type Option func(*Manager)
// WithBus injects an existing bus instead of letting the Manager create one. It // WithBus 注入现成的 bus,而不让 Manager 自建一个。此设计与其余子系统保持一致:
// mirrors the other subsystems so iot.device_update flows on the shared bus and // iot.device_update 由此流经共享 bus,能到达 gateway hub / 后台触发订阅者,
// reaches the gateway hub / background-trigger subscribers rather than staying // 而不是滞留在一个 Manager 私有的隔离 bus 上。
// on an isolated manager-owned bus.
func WithBus(b bus.Bus) Option { func WithBus(b bus.Bus) Option {
return func(m *Manager) { m.bus = b } return func(m *Manager) { m.bus = b }
} }
// New builds a Manager from cfg, selecting the device Provider by cfg.Provider. // New 依据 cfg 构建 Manager,并以 cfg.Provider 选定设备 Provider。
// //
// Supported providers: "" or "mock" registers the built-in mock provider with // 支持的 Provider 取值:"" 或 "mock" 注册内置 mock Provider(八台模拟设备);
// eight simulated devices; "none" disables the subsystem (no provider is // "none" 关闭该子系统(不注册任何 Provider,List 返回空切片,Control/Status 以
// registered, List returns an empty slice and Control/Status fail with // ErrDeviceNotFound 失败)。其他取值返回 ErrUnknownProvider。
// ErrDeviceNotFound). Any other value returns ErrUnknownProvider.
// //
// log may be nil; it is replaced with a discard logger. The Manager owns a // log 可为 nil,此时会替换为丢弃输出的 logger。Manager 自持一个全新且隔离的 bus,
// fresh, isolated bus exposed via Bus for subscribers to attach to. // 经 Bus 暴露给订阅方挂接。
func New(cfg config.IoTConfig, log *slog.Logger, opts ...Option) (*Manager, error) { func New(cfg config.IoTConfig, log *slog.Logger, opts ...Option) (*Manager, error) {
m := &Manager{ m := &Manager{
bus: bus.New(), bus: bus.New(),
@@ -58,7 +55,7 @@ func New(cfg config.IoTConfig, log *slog.Logger, opts ...Option) (*Manager, erro
} }
m.providers = append(m.providers, mp) m.providers = append(m.providers, mp)
case "none": case "none":
// No provider is registered: the subsystem is disabled. // 不注册任何 Provider:子系统处于关闭状态。
default: default:
return nil, fmt.Errorf("iot: new: provider %q: %w", cfg.Provider, ErrUnknownProvider) return nil, fmt.Errorf("iot: new: provider %q: %w", cfg.Provider, ErrUnknownProvider)
} }
@@ -66,8 +63,8 @@ func New(cfg config.IoTConfig, log *slog.Logger, opts ...Option) (*Manager, erro
return m, nil return m, nil
} }
// Register adds p as a device source. Registering a provider whose Name already // Register 把 p 注册为设备来源。注册的 Provider 若 Name 已存在,返回 ErrDuplicate;
// exists returns ErrDuplicate; a nil provider returns ErrInvalidArgument. // p 为 nil 则返回 ErrInvalidArgument。
func (m *Manager) Register(p Provider) error { func (m *Manager) Register(p Provider) error {
if p == nil { if p == nil {
return fmt.Errorf("iot: register: %w", ErrInvalidArgument) return fmt.Errorf("iot: register: %w", ErrInvalidArgument)
@@ -82,13 +79,13 @@ func (m *Manager) Register(p Provider) error {
return nil return nil
} }
// Bus returns the Manager's in-process event bus. Subscribers attach to // Bus 返回 Manager 的进程内事件总线。订阅方挂接 DeviceUpdateSubject
// DeviceUpdateSubject (or "iot.>") to observe device state transitions. // (或 "iot.>")以观察设备状态跃迁。
func (m *Manager) Bus() bus.Bus { func (m *Manager) Bus() bus.Bus {
return m.bus return m.bus
} }
// List returns every device from every registered provider. // List 返回全部已注册 Provider 的所有设备。
func (m *Manager) List(ctx context.Context) ([]Device, error) { func (m *Manager) List(ctx context.Context) ([]Device, error) {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
@@ -105,9 +102,8 @@ func (m *Manager) List(ctx context.Context) ([]Device, error) {
return out, nil return out, nil
} }
// Control applies action to the owning provider's device and, on success, // Control 把 action 施加到拥有该设备的 Provider 上,成功后向 bus 发布一条
// publishes a DeviceUpdate on the bus. It returns ErrDeviceNotFound when no // DeviceUpdate。若没有任何 Provider 拥有该设备,返回 ErrDeviceNotFound。
// provider owns the device.
func (m *Manager) Control(ctx context.Context, deviceID, action string, params map[string]any) (*Device, error) { func (m *Manager) Control(ctx context.Context, deviceID, action string, params map[string]any) (*Device, error) {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
@@ -129,8 +125,8 @@ func (m *Manager) Control(ctx context.Context, deviceID, action string, params m
return nil, fmt.Errorf("iot: control %q: %w", deviceID, ErrDeviceNotFound) return nil, fmt.Errorf("iot: control %q: %w", deviceID, ErrDeviceNotFound)
} }
// Status returns the current state of the device owned by the matching provider. // Status 返回由匹配 Provider 所持有设备的当前状态。若没有任何 Provider 拥有该
// It returns ErrDeviceNotFound when no provider owns the device. // 设备,返回 ErrDeviceNotFound。
func (m *Manager) Status(ctx context.Context, deviceID string) (*Device, error) { func (m *Manager) Status(ctx context.Context, deviceID string) (*Device, error) {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
@@ -151,10 +147,9 @@ func (m *Manager) Status(ctx context.Context, deviceID string) (*Device, error)
return nil, fmt.Errorf("iot: status %q: %w", deviceID, ErrDeviceNotFound) return nil, fmt.Errorf("iot: status %q: %w", deviceID, ErrDeviceNotFound)
} }
// publishUpdate fans a DeviceUpdate out on the bus. A publish failure (for // publishUpdate 把 DeviceUpdate 扇出到 bus。发布失败(例如 ctx 被取消)只记日志、
// example a canceled context) is logged, not returned: the device state already // 不作为错误返回:设备状态已经改变,不应因为某个观察者没收到事件就把本次控制判为
// changed, and control should not be reported as failed because an observer did // 失败。
// not receive the event.
func (m *Manager) publishUpdate(ctx context.Context, provider string, d Device, action string, params map[string]any) { func (m *Manager) publishUpdate(ctx context.Context, provider string, d Device, action string, params map[string]any) {
msg := fmt.Sprintf("设备 %s · %s(%s)", d.Name, action, provider) msg := fmt.Sprintf("设备 %s · %s(%s)", d.Name, action, provider)
if err := m.bus.Publish(ctx, DeviceUpdateSubject, DeviceUpdate{ if err := m.bus.Publish(ctx, DeviceUpdateSubject, DeviceUpdate{
@@ -170,8 +165,8 @@ func (m *Manager) publishUpdate(ctx context.Context, provider string, d Device,
m.log.Debug("iot device update published", "device", d.ID, "action", action, "provider", provider) m.log.Debug("iot device update published", "device", d.ID, "action", action, "provider", provider)
} }
// discardLogger returns log if non-nil, otherwise a logger that writes nowhere, // discardLogger 在 log 非 nil 时原样返回,否则返回一个不写任何输出的 logger,
// so New always has a safe logger to use. // 保证 New 始终有可用的 logger。
func discardLogger(log *slog.Logger) *slog.Logger { func discardLogger(log *slog.Logger) *slog.Logger {
if log != nil { if log != nil {
return log return log
+20 -25
View File
@@ -11,10 +11,8 @@ import (
"git.yeij.top/AskaEth/Cyrene_v2/internal/logger" "git.yeij.top/AskaEth/Cyrene_v2/internal/logger"
) )
// mockProvider is the built-in deterministic Provider with eight simulated // mockProvider 是内置的确定性 Provider,八台模拟设备覆盖全部受支持的设备类型。
// devices spread across every supported device type. It enforces the // 它施加 control_rules(capability 约束),界定每种设备类型的支持范围。
// control_rules (capability constraints) that bound what each device type
// supports.
type mockProvider struct { type mockProvider struct {
mu sync.RWMutex mu sync.RWMutex
log *slog.Logger log *slog.Logger
@@ -22,19 +20,18 @@ type mockProvider struct {
rules map[string]typeRules rules map[string]typeRules
} }
// typeRules holds the control_rules for one device type: the set of supported // typeRules 保存单一设备类型的 control_rules:受支持的动作集合,以及每个动作
// actions and how each mutates the device state. // 如何改动设备状态。
type typeRules struct { type typeRules struct {
supported map[string]applyFunc supported map[string]applyFunc
} }
// applyFunc mutates d.State according to the action. It returns an error when // applyFunc 依据动作修改 d.State;参数非法时返回错误。
// the parameters are invalid.
type applyFunc func(d *Device, params map[string]any) error type applyFunc func(d *Device, params map[string]any) error
const mockProviderName = "mock" const mockProviderName = "mock"
// Name returns the provider identifier. // Name 返回 Provider 标识。
func (m *mockProvider) Name() string { return mockProviderName } func (m *mockProvider) Name() string { return mockProviderName }
func newMockProvider(log *slog.Logger) (*mockProvider, error) { func newMockProvider(log *slog.Logger) (*mockProvider, error) {
@@ -49,7 +46,7 @@ func newMockProvider(log *slog.Logger) (*mockProvider, error) {
return m, nil return m, nil
} }
// List returns every device, sorted by ID for deterministic output. // List 返回全部设备,按 ID 排序以保证输出确定。
func (m *mockProvider) List(ctx context.Context) ([]Device, error) { func (m *mockProvider) List(ctx context.Context) ([]Device, error) {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
@@ -64,7 +61,7 @@ func (m *mockProvider) List(ctx context.Context) ([]Device, error) {
return out, nil return out, nil
} }
// Status returns a clone of the named device. // Status 返回指定设备的副本。
func (m *mockProvider) Status(ctx context.Context, deviceID string) (*Device, error) { func (m *mockProvider) Status(ctx context.Context, deviceID string) (*Device, error) {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
@@ -79,7 +76,7 @@ func (m *mockProvider) Status(ctx context.Context, deviceID string) (*Device, er
return &cp, nil return &cp, nil
} }
// Control applies action to the named device, enforcing the type's control_rules. // Control 对指定设备施加 action,并强制该类型的 control_rules。
func (m *mockProvider) Control(ctx context.Context, deviceID, action string, params map[string]any) (*Device, error) { func (m *mockProvider) Control(ctx context.Context, deviceID, action string, params map[string]any) (*Device, error) {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
@@ -109,7 +106,7 @@ func (m *mockProvider) Control(ctx context.Context, deviceID, action string, par
return &cp, nil return &cp, nil
} }
// buildRules returns the control_rules for every supported device type. // buildRules 返回全部受支持设备类型的 control_rules。
func buildRules() map[string]typeRules { func buildRules() map[string]typeRules {
return map[string]typeRules{ return map[string]typeRules{
"light": lightRules(), "light": lightRules(),
@@ -120,7 +117,7 @@ func buildRules() map[string]typeRules {
} }
} }
// lightRules returns the control_rules for light devices. // lightRules 返回灯类设备的 control_rules。
func lightRules() typeRules { func lightRules() typeRules {
return typeRules{supported: map[string]applyFunc{ return typeRules{supported: map[string]applyFunc{
"on": func(d *Device, _ map[string]any) error { "on": func(d *Device, _ map[string]any) error {
@@ -150,7 +147,7 @@ func lightRules() typeRules {
}} }}
} }
// acRules returns the control_rules for AC devices. // acRules 返回空调设备的 control_rules。
func acRules() typeRules { func acRules() typeRules {
return typeRules{supported: map[string]applyFunc{ return typeRules{supported: map[string]applyFunc{
"on": func(d *Device, _ map[string]any) error { "on": func(d *Device, _ map[string]any) error {
@@ -185,7 +182,7 @@ func acRules() typeRules {
}} }}
} }
// curtainRules returns the control_rules for curtain devices. // curtainRules 返回窗帘设备的 control_rules。
func curtainRules() typeRules { func curtainRules() typeRules {
return typeRules{supported: map[string]applyFunc{ return typeRules{supported: map[string]applyFunc{
"open": func(d *Device, _ map[string]any) error { "open": func(d *Device, _ map[string]any) error {
@@ -208,14 +205,13 @@ func curtainRules() typeRules {
}} }}
} }
// sensorRules returns the control_rules for sensor devices. Sensors are // sensorRules 返回传感器设备的 control_rules。传感器只读:不支持任何动作,
// read-only: no action is supported, so any Control attempt returns // 因此任何 Control 尝试都会返回 ErrUnsupported。
// ErrUnsupported.
func sensorRules() typeRules { func sensorRules() typeRules {
return typeRules{supported: map[string]applyFunc{}} return typeRules{supported: map[string]applyFunc{}}
} }
// lockRules returns the control_rules for lock devices. // lockRules 返回门锁设备的 control_rules。
func lockRules() typeRules { func lockRules() typeRules {
return typeRules{supported: map[string]applyFunc{ return typeRules{supported: map[string]applyFunc{
"lock": func(d *Device, _ map[string]any) error { "lock": func(d *Device, _ map[string]any) error {
@@ -233,9 +229,8 @@ func lockRules() typeRules {
}} }}
} }
// mockDevices returns the eight seeded mock devices. It covers all five types; // mockDevices 返回八台预置的模拟设备,覆盖全部五种类型;ac.bedroom 预置为离线,
// ac.bedroom is seeded offline to exercise the Online field and the offline // 用于检验 Online 字段与离线控制保护逻辑。
// control guard.
func mockDevices() []*Device { func mockDevices() []*Device {
return []*Device{ return []*Device{
{ID: "ac.bedroom", Name: "卧室空调", Type: "ac", Online: false, State: map[string]any{"on": false, "temperature": 26, "mode": "cool"}}, {ID: "ac.bedroom", Name: "卧室空调", Type: "ac", Online: false, State: map[string]any{"on": false, "temperature": 26, "mode": "cool"}},
@@ -274,8 +269,8 @@ func clamp(n, lo, hi int) int {
return n return n
} }
// intParam reads an integer action parameter, accepting int/int64/float64/string // intParam 读取整型动作参数,可接受 int/int64/float64/string 等多种形态,
// shapes so JSON-decoded params work the same as literal ones. // 使 JSON 解码得到的参数与字面量参数行为一致。
func intParam(p map[string]any, key string) (int, error) { func intParam(p map[string]any, key string) (int, error) {
v, ok := p[key] v, ok := p[key]
if !ok { if !ok {
+10 -13
View File
@@ -2,23 +2,20 @@ package iot
import "context" import "context"
// Provider is a pluggable source of IoT devices. Implementations own the device // Provider 是可插拔的 IoT 设备来源。实现方持有设备状态,并为每种设备类型施加
// state and enforce the control_rules (capability constraints) for each device // control_rules(capability 约束)——因此某类型支持的动作集合即其能力边界。
// type, so a type's set of supported actions is its capability.
// //
// Implementations must be safe for concurrent use, because the Manager may serve // 实现必须是并发安全的,因为 Manager 可能从多个 goroutine 并发调用
// List/Control/Status from multiple goroutines. // List/Control/Status。
type Provider interface { type Provider interface {
// Name returns the stable provider identifier, used for logging and to // Name 返回稳定的 Provider 标识,用于日志,以及区分注册在同一 Manager 上的
// disambiguate providers registered on one Manager. // 多个 Provider。
Name() string Name() string
// List returns every device currently known to the provider. // List 返回该 Provider 当前已知的全部设备。
List(ctx context.Context) ([]Device, error) List(ctx context.Context) ([]Device, error)
// Control applies action with params to the named device and returns the // Control 对指定设备施加 action(携带 params),并返回跃迁后的设备。
// post-transition device. It returns ErrDeviceNotFound for an unknown device // 设备未知时返回 ErrDeviceNotFound;设备类型不支持该动作时返回 ErrUnsupported。
// and ErrUnsupported for an action the device's type does not support.
Control(ctx context.Context, deviceID, action string, params map[string]any) (*Device, error) Control(ctx context.Context, deviceID, action string, params map[string]any) (*Device, error)
// Status returns the current state of the named device. It returns // Status 返回指定设备的当前状态;设备未知时返回 ErrDeviceNotFound。
// ErrDeviceNotFound when the device is unknown.
Status(ctx context.Context, deviceID string) (*Device, error) Status(ctx context.Context, deviceID string) (*Device, error)
} }