shelly

package module
v0.0.0-...-cfc8522 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2026 License: MPL-2.0 Imports: 27 Imported by: 0

README

go-shellies

Go library and CLI for Shelly Gen2+ devices.

Originally extracted from home-automation via git filter-repo — full per-file history is preserved (git log --follow works).

Layout

Three Go modules:

  • github.com/asnowfix/go-shellies — the library: device, registrar, mDNS, per-component packages (ble, blu, kvs, mqtt, schedule, sswitch, system, wifi, ...) and the shelly CLI binary under cmd/shelly/.
  • github.com/asnowfix/go-shellies/script — goja-based JS runtime for emulating Shelly device-side scripts (heavy goja+minify deps; isolated).
  • github.com/asnowfix/go-shellies/gen1 — gen1 device support (gorilla/schema dep; isolated).

A go.work file ties the three together for local development.

CLI

go install github.com/asnowfix/go-shellies/cmd/shelly@latest
shelly --help

The shelly binary discovers devices on the local network via mDNS by default, or addresses them by MQTT topic id with --via mqtt. It does not depend on any home-automation daemon.

Subcommands:

Subcommand What it does
call <device> <method> [params-json] Direct RPC call
kvs get / set / delete Key-Value Store ops
wifi config / status / scan / list-ap-clients WiFi config & status
mqtt config / status MQTT config & status (--mqtt-broker URL for config)
sys config / reboot System config & reboot
status Component statuses
reboot Reboot a device
components List components
jobs show / cancel / schedule Schedule jobs
mcp Run an MCP stdio server exposing shelly_list and shelly_call
emulate <script.js> Run a Shelly JS script in the goja runtime locally
Examples
# Discover and list status for every shellyplus device
shelly status 'shellyplus*'

# Call an RPC method directly
shelly call shellyplusht-d4b9f4 Switch.Set '{"id":0,"on":true}'

# Run a JS script locally with an initial KVS snapshot
shelly emulate ./pool-pump.js --device-state ./pool-state.json --duration 30s

Library use

import (
    shelly "github.com/asnowfix/go-shellies"
    "github.com/asnowfix/go-shellies/mqtt"
    "github.com/asnowfix/go-shellies/script"
)

// Optional extras: pull in the script package, embed your scripts FS.
script.SetFS(myEmbed.GetFS())
shelly.Init(log, mqttClient, timeout, rateLimit, script.Init)

Build

go build ./...
go test ./...

(or, equivalently, from each sub-module directory).

License

GPL-3.0 — see LICENSE.

Documentation

Index

Constants

View Source
const MDNS_SHELLIES string = "_shelly._tcp."

Variables

This section is empty.

Functions

func ConfigureDeviceSettings

func ConfigureDeviceSettings(ctx context.Context, log logr.Logger, device *Device, name string, ecoMode *bool) error

ConfigureDeviceSettings updates Shelly device configuration on the device itself (Gen2+ only). This function should only be called for Gen2+ devices. It updates the device name and/or eco mode on the device.

func Foreach

func Foreach(ctx context.Context, log logr.Logger, deviceList []devices.Device, via types.Channel, do Do, args []string) (any, error)

func Init

func Init(log logr.Logger, mc mqtt.Client, timeout time.Duration, rateLimitInterval time.Duration, extras ...InitExtra)

Init wires up the registrar, rate limiter, and the always-present method handlers. Optional extras (e.g. script.Init) are invoked at the end so a caller can opt into the heavier sub-packages.

func IsBluDevice

func IsBluDevice(deviceId string) bool

func IsGen1Device

func IsGen1Device(deviceId string) bool

IsGen1Device returns true if the device ID indicates a Gen1 device Gen1 devices are identified by their ID prefix (e.g., "shellyht-", "shellyflood-")

func NewDeviceFromIp

func NewDeviceFromIp(ctx context.Context, log logr.Logger, ip net.IP) (devices.Device, error)

func NewDeviceFromMqttId

func NewDeviceFromMqttId(ctx context.Context, log logr.Logger, id string) (devices.Device, error)

func NewDeviceFromSummary

func NewDeviceFromSummary(ctx context.Context, log logr.Logger, summary devices.Device) (devices.Device, error)

func NewDeviceFromZeroConfEntry

func NewDeviceFromZeroConfEntry(ctx context.Context, log logr.Logger, resolver devices.Resolver, entry *zeroconf.ServiceEntry) (devices.Device, error)

func Print

func Print(log logr.Logger, d any) error

Types

type Device

type Device struct {
	Id_         string           `json:"id"`
	MacAddress_ net.HardwareAddr `json:"-"`
	Name_       string           `json:"name"`
	Host_       net.IP           `json:"host"`
	// contains filtered or unexported fields
}

func (*Device) CallE

func (d *Device) CallE(ctx context.Context, via types.Channel, method string, params any) (any, error)

func (*Device) Channel

func (d *Device) Channel(via types.Channel) types.Channel

func (*Device) ClearHost

func (d *Device) ClearHost()

func (*Device) Config

func (d *Device) Config() *shelly.Config

func (*Device) ConfigRevision

func (d *Device) ConfigRevision() uint32

func (*Device) From

func (d *Device) From() <-chan []byte

func (*Device) Host

func (d *Device) Host() string

func (*Device) Id

func (d *Device) Id() string

func (*Device) Info

func (d *Device) Info() *shelly.DeviceInfo

func (*Device) Init

func (d *Device) Init(ctx context.Context) error

Init initializes the device, setting up HTTP and MQTT channels as needed. This is the exported version of init() for use by external packages.

func (*Device) Ip

func (d *Device) Ip() net.IP

func (*Device) IsHttpReady

func (d *Device) IsHttpReady() bool

func (*Device) IsModified

func (d *Device) IsModified() bool

func (*Device) IsMqttReady

func (d *Device) IsMqttReady() bool

func (*Device) Mac

func (d *Device) Mac() net.HardwareAddr

func (*Device) Manufacturer

func (d *Device) Manufacturer() string

func (*Device) MethodHandlerE

func (d *Device) MethodHandlerE(v any) (types.MethodHandler, error)

func (*Device) Name

func (d *Device) Name() string

func (*Device) Refresh

func (d *Device) Refresh(ctx context.Context, via types.Channel) (bool, error)

func (*Device) ReplyTo

func (d *Device) ReplyTo() string

func (*Device) ResetModified

func (d *Device) ResetModified()

func (*Device) StartDialog

func (d *Device) StartDialog(ctx context.Context) uint32

func (*Device) Status

func (d *Device) Status() *shelly.Status

func (*Device) StopDialog

func (d *Device) StopDialog(ctx context.Context, id uint32)

func (*Device) String

func (d *Device) String() string

func (*Device) To

func (d *Device) To() chan<- []byte

func (*Device) UpdateHost

func (d *Device) UpdateHost(host string)

func (*Device) UpdateId

func (d *Device) UpdateId(id string)

func (*Device) UpdateMac

func (d *Device) UpdateMac(mac string)

func (*Device) UpdateName

func (d *Device) UpdateName(name string)

type DeviceMqttChannels

type DeviceMqttChannels struct {
	ReplyTo string
	To      chan<- []byte
	From    <-chan []byte
	// contains filtered or unexported fields
}

DeviceMqttChannels holds MQTT channels for each device ID to prevent goroutine leaks. When Device structs are recreated (e.g., loaded from database), they reuse existing channels instead of creating new subscriptions/publishers that would leak goroutines.

func (*DeviceMqttChannels) Init

func (m *DeviceMqttChannels) Init(ctx context.Context, deviceId string) (*DeviceMqttChannels, error)

Init initializes MQTT channels for a device. Returns an existing instance from the registry if available, or creates new channels and registers them.

func (*DeviceMqttChannels) IsReady

func (m *DeviceMqttChannels) IsReady() bool

func (*DeviceMqttChannels) Lock

func (m *DeviceMqttChannels) Lock()

Lock acquires the mutex to serialize MQTT request-response cycles

func (*DeviceMqttChannels) Unlock

func (m *DeviceMqttChannels) Unlock()

Unlock releases the mutex

type DeviceResult

type DeviceResult struct {
	Device devices.Device
	Result any
	Error  error
}

DeviceResult represents the result of an operation on a single device

type InitExtra

type InitExtra func(log logr.Logger, r types.MethodsRegistrar)

InitExtra registers extra method handlers against the package-level registrar — used to plug optional sub-packages (script, gen1, ...) without pulling them in unconditionally.

type Registrar

type Registrar struct {
	// contains filtered or unexported fields
}

func GetRegistrar

func GetRegistrar() *Registrar

return singleton registrar

func (*Registrar) CallE

func (r *Registrar) CallE(ctx context.Context, d types.Device, via types.Channel, mh types.MethodHandler, params any) (any, error)

func (*Registrar) Init

func (r *Registrar) Init(log logr.Logger)

func (*Registrar) MethodHandlerE

func (r *Registrar) MethodHandlerE(m string) (types.MethodHandler, error)

func (*Registrar) RegisterDeviceCaller

func (r *Registrar) RegisterDeviceCaller(ch types.Channel, dc types.DeviceCaller)

func (*Registrar) RegisterMethodHandler

func (r *Registrar) RegisterMethodHandler(verb string, mh types.MethodHandler)

type ShellyDevice

type ShellyDevice struct {
	// contains filtered or unexported fields
}

func (ShellyDevice) Host

func (d ShellyDevice) Host() string

func (ShellyDevice) Id

func (d ShellyDevice) Id() string

func (ShellyDevice) Ip

func (d ShellyDevice) Ip() net.IP

func (ShellyDevice) Mac

func (d ShellyDevice) Mac() net.HardwareAddr

func (ShellyDevice) Manufacturer

func (d ShellyDevice) Manufacturer() string

func (ShellyDevice) MarshalJSON

func (d ShellyDevice) MarshalJSON() ([]byte, error)

func (ShellyDevice) Name

func (d ShellyDevice) Name() string

func (ShellyDevice) Online

func (d ShellyDevice) Online() bool

func (ShellyDevice) Provider

func (d ShellyDevice) Provider() string

Directories

Path Synopsis
cmd
shelly command
Command shelly is a standalone CLI for talking to Shelly devices over the local network (HTTP/mDNS or MQTT).
Command shelly is a standalone CLI for talking to Shelly devices over the local network (HTTP/mDNS or MQTT).
shelly/dispatch
Package dispatch resolves a user-supplied device identifier (name, id, hostname, IP, or wildcard) to one or more devices.Device values and runs a per-device operation against each, in parallel.
Package dispatch resolves a user-supplied device identifier (name, id, hostname, IP, or wildcard) to one or more devices.Device values and runs a per-device operation against each, in parallel.
shelly/emulate
Package emulate exposes the script package's goja-based Shelly device emulator as a CLI subcommand.
Package emulate exposes the script package's goja-based Shelly device emulator as a CLI subcommand.
shelly/options
Package options holds CLI flags shared across subcommands of the shelly binary.
Package options holds CLI flags shared across subcommands of the shelly binary.
https://shelly-api-docs.shelly.cloud/gen2/ComponentsAndServices/Input/
https://shelly-api-docs.shelly.cloud/gen2/ComponentsAndServices/Input/
script module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL