Documentation
¶
Overview ¶
Package ratgdo is a Go client for ratgdo garage-door controllers running the upstream ESPHome firmware (https://github.com/ratgdo/esphome-ratgdo).
It speaks the ESPHome native API on TCP port 6053 with Noise-protocol encryption. The device must be flashed with an api.encryption.key; the matching base64 PSK is passed to Dial.
The Client is long-lived. After a successful Dial it maintains the TCP session in the background, reconnecting with exponential backoff whenever the connection drops (device reboot, WiFi glitch, etc.). Commands issued while disconnected block until reconnection or the caller's context expires.
The entity schema is hardcoded for ratgdo boards — one cover entity named "door", one light, and the standard motion/obstruction/motor/button sensors. Other ESPHome devices will not work with this package.
Index ¶
- Constants
- Variables
- type Client
- func (c *Client) Close() error
- func (c *Client) CloseDoor(ctx context.Context) error
- func (c *Client) Connected() bool
- func (c *Client) DeviceInfo(ctx context.Context) (*DeviceInfo, error)
- func (c *Client) OpenDoor(ctx context.Context) error
- func (c *Client) Ping(ctx context.Context) error
- func (c *Client) QueryStatus(ctx context.Context) error
- func (c *Client) SetDoorPosition(ctx context.Context, position float32) error
- func (c *Client) State() State
- func (c *Client) StopDoor(ctx context.Context) error
- func (c *Client) Subscribe() <-chan Event
- func (c *Client) Sync(ctx context.Context) error
- func (c *Client) ToggleLight(ctx context.Context) error
- func (c *Client) TurnOffLight(ctx context.Context) error
- func (c *Client) TurnOnLight(ctx context.Context) error
- func (c *Client) WaitFor(ctx context.Context, pred func(State) bool) error
- type Config
- type DeviceInfo
- type DoorOp
- type Event
- type EventKind
- type State
Constants ¶
const Version = "0.4.0"
Version is the semantic version of this library and CLI. Bump with github.com/kevinburke/bump_version.
Variables ¶
var ( // ErrClosed is returned by commands issued after Close. ErrClosed = errors.New("ratgdo: client closed") // ErrNoEntity is returned when the firmware doesn't expose the entity // a command requires — i.e. this library is talking to something that // isn't a ratgdo after all. ErrNoEntity = errors.New("ratgdo: device does not expose the required entity") )
Errors returned by Client methods.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a long-lived connection to a ratgdo device. Construct it with Dial; release it with Close.
func Dial ¶
Dial opens a connection to the ratgdo at addr (e.g. "ratgdo.local:6053") and performs the Noise handshake with the given base64 encryption key. If encryptionKey is empty, a plaintext session is used — only do that on a completely trusted network.
Pass nil for cfg to accept all defaults. If the initial session setup fails, Dial returns the error and no Client.
After Dial returns, the Client maintains the session in the background: on disconnect it reconnects with exponential backoff until Close.
func (*Client) Close ¶
Close disconnects from the device, stops the background reconnect loop, and closes all Subscribe channels. It is safe to call Close more than once; subsequent calls return nil.
func (*Client) Connected ¶
Connected reports whether the client currently has a live, authenticated session with the device.
func (*Client) DeviceInfo ¶
func (c *Client) DeviceInfo(ctx context.Context) (*DeviceInfo, error)
DeviceInfo queries the device for its identity metadata. Unlike the other commands, DeviceInfo blocks until a response arrives or ctx expires.
func (*Client) OpenDoor ¶
OpenDoor sends an open command to the opener. The call returns as soon as the command is on the wire; observe State or Subscribe to confirm the door actually moved.
func (*Client) Ping ¶
Ping probes the active API session. It blocks until the device responds, ctx expires, or the client disconnects.
func (*Client) QueryStatus ¶
QueryStatus presses the "Query status" template button on the device.
func (*Client) SetDoorPosition ¶
SetDoorPosition drives the door to the given fractional position (0 = fully closed, 1 = fully open). Ratgdo supports this natively.
func (*Client) State ¶
State returns a snapshot of the most recently observed device state. Safe to call at any time, including while disconnected (returns stale data — check State.LastSeenAt).
func (*Client) Subscribe ¶
Subscribe returns a channel that receives every state change plus connect/disconnect notifications. The channel is buffered; if a consumer falls more than the buffer behind, older events are dropped (logged). The channel closes when Close is called.
func (*Client) Sync ¶
Sync asks the device to re-query the opener for its current state. Useful if the ratgdo's state drifted from reality.
func (*Client) ToggleLight ¶
ToggleLight flips the current light state.
func (*Client) TurnOffLight ¶
TurnOffLight turns the opener light off.
func (*Client) TurnOnLight ¶
TurnOnLight turns the opener light on.
type Config ¶
type Config struct {
// ClientID is sent to the device as ClientInfo in the Hello handshake
// and appears in the device's logs. Defaults to "ratgdo-go".
ClientID string
// Timeout bounds each network operation: the initial dial, the Noise
// handshake, and individual wire writes. Defaults to 10s.
Timeout time.Duration
// Logger handles reconnect/error logging. Defaults to slog.Default().
Logger *slog.Logger
}
Config holds the optional knobs for a Client. Pass nil to Dial for all defaults, or set only the fields you care about (zero values mean "use the default").
type DeviceInfo ¶
type DeviceInfo struct {
Name, Model, MACAddress, ESPHomeVersion, CompilationTime string
}
DeviceInfo holds static metadata about a ratgdo device.
type Event ¶
Event is a change notification delivered on the channel returned by Client.Subscribe. For EventStateChange, Prev and Curr show the delta. For connection events, Prev and Curr are equal (both hold the most recent known state).
func (Event) DoorFinishedClosing ¶
DoorFinishedClosing reports the door reaching the fully-closed state.
func (Event) DoorFinishedOpening ¶
DoorFinishedOpening reports the door reaching the fully-open state.
func (Event) DoorStartedClosing ¶
DoorStartedClosing reports the door transitioning into the closing state.
func (Event) DoorStartedOpening ¶
DoorStartedOpening reports whether this event represents the door transitioning from closed or stopped into the opening state.
func (Event) OpeningsIncreased ¶
OpeningsIncreased reports whether the lifetime opening counter advanced in this event. Useful for detecting activity missed during a disconnect: a single EventConnected can report many openings if the gap was long.
type EventKind ¶
type EventKind int
EventKind distinguishes state deltas from connection-lifecycle events.
const ( // EventStateChange is emitted whenever any field of State differs from // the previous State. EventStateChange EventKind = iota // EventConnected is emitted after the initial Dial returns and after // every successful reconnection. EventConnected // EventDisconnected is emitted when the background session drops. A // reconnect attempt follows automatically unless Close was called. EventDisconnected )
type State ¶
type State struct {
Door DoorOp
Position float32 // 0 = fully closed, 1 = fully open
Light bool
// Motion is true while the opener's motion sensor is active. It
// typically auto-resets after a few seconds on the device.
Motion bool
Obstruction bool
// Openings is the lifetime count of door openings, persisted on-device
// across reboots.
Openings int
// UpdatedAt is the time we last observed any state change. Zero before
// the first state event.
UpdatedAt time.Time
// LastSeenAt is the time we last received any message from the device,
// including pings and unchanged state updates. Zero until first message.
LastSeenAt time.Time
}
State is a snapshot of the ratgdo's observable state. All fields reflect the last value received from the device.