Go SDK for building EDG Platform adapters. Provides typed wrappers around the
NATS subject contract documented in docs/ADAPTER_GUIDE.md
and docs/events.md, so adapter authors do not need
to hand-roll wire types, request/reply, or reconnection logic.
Feature parity with the Python SDK:
- Publish
AssetDatatoplatform.data.asset - Asset and relation CRUD via NATS request/reply
- Subscribe to
platform.meta.*.changedevents Adapterskeleton with collect loop, exponential backoff, device connect / reconnect / health hooks
go get github.com/e7217/edg/adapters/go/sdkThe SDK is its own Go module so you only pull nats.go (and its minimal
transitive dependencies) — the EDG Core's heavier deps (sqlite, migrate,
embedded nats-server) are not transitively required.
package main
import (
"context"
"log"
"os/signal"
"syscall"
"time"
"github.com/e7217/edg/adapters/go/sdk"
)
type tempSensor struct{}
func (tempSensor) Collect(_ context.Context) ([]sdk.TagValue, error) {
n := 25.5
return []sdk.TagValue{
{Name: "temperature", Quality: sdk.QualityGood, Number: &n, Unit: "°C"},
}, nil
}
func main() {
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
a := sdk.NewAdapter(sdk.AdapterConfig{
AssetID: "temp-sensor-001",
CollectInterval: time.Second,
}, tempSensor{})
if err := a.Run(ctx); err != nil {
log.Fatalf("adapter exited: %v", err)
}
}If your collector also implements DeviceLifecycle and DeviceObserver,
the adapter calls those hooks around the collect loop:
type myDevice struct{ /* ... */ }
func (d *myDevice) ConnectDevice(ctx context.Context) error { /* ... */ }
func (d *myDevice) DisconnectDevice(ctx context.Context) error { /* ... */ }
func (d *myDevice) CheckDeviceHealth(ctx context.Context) error { /* ... */ }
func (d *myDevice) Collect(ctx context.Context) ([]sdk.TagValue, error) { /* ... */ }
func (d *myDevice) OnDeviceConnected(ctx context.Context) { /* ... */ }
func (d *myDevice) OnDeviceDisconnected(ctx context.Context, err error) { /* ... */ }
func (d *myDevice) OnDeviceReconnected(ctx context.Context) { /* ... */ }Connect failures are retried with exponential backoff configured via
AdapterConfig.Backoff and AdapterConfig.MaxRetries. Wrap retryable errors
with sdk.ErrDeviceConnection or sdk.ErrDeviceTimeout so the adapter
classifies them correctly. See
examples/temp_sensor_with_recovery
for a runnable example.
If you do not need the adapter loop you can use the Client directly:
c := sdk.NewClient(sdk.Options{URL: "nats://localhost:4222"})
if err := c.Connect(ctx); err != nil { /* ... */ }
defer c.Close()
asset, err := c.CreateAsset(ctx, sdk.CreateAssetRequest{Name: "sensor-9"})
// ...
sub, err := c.SubscribeMetaChanges(func(ev sdk.MetaChangeEvent) {
var a sdk.Asset
_ = ev.DecodeAfter(&a)
log.Printf("%s: %s", ev.EventType, a.Name)
})
defer sub.Unsubscribe()See examples/ — three runnable adapters mirroring the Python
examples in adapters/python/examples:
temp_sensor— simple collect loopvibration_sensor— multi-tag periodic publishingtemp_sensor_with_recovery— device connect / health / reconnect hooks
Run any example with the EDG Core started locally:
go run github.com/e7217/edg/adapters/go/sdk/examples/temp_sensor