iot

package module
v0.0.0-...-4859fc7 Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2019 License: MIT Imports: 8 Imported by: 0

README

IoT

A simple framework for implementing a Google IoT device.

This package makes use of the context package to handle request cancelation, timeouts, and deadlines.

gocover.io Go Report Card Go Docs Mentioned in Awesome Go

Copyright 2018, Andrew C. Young <andrew@vaelen.org>

License: MIT

Here is an example showing how to use this library:

package main

import (
	"context"
	"log"
	"github.com/vaelen/iot"
	// Your client must include the paho package
	// to use the default Eclipse Paho MQTT client.
	_ "github.com/vaelen/iot/paho"
)

func main() {
	ctx := context.Background()

	id := &iot.ID{
		DeviceID:  "deviceName",
		Registry:  "my-registry",
		Location:  "asia-east1",
		ProjectID: "my-project",
	}

	credentials, err := iot.LoadRSACredentials("rsa_cert.pem", "rsa_private.pem")
	if err != nil {
		panic("Couldn't load credentials")
	}

	options := iot.DefaultOptions(id, credentials)
	options.DebugLogger = log.Println
	options.InfoLogger = log.Println
	options.ErrorLogger = log.Println
	options.ConfigHandler = func(thing iot.Thing, config []byte) {
		// Do something here to process the updated config and create an updated state string
		state := []byte("ok")
		thing.PublishState(ctx, state)
	}

	thing := iot.New(options)

	err = thing.Connect(ctx, "ssl://mqtt.googleapis.com:443")
	if err != nil {
		panic("Couldn't connect to server")
	}
	defer thing.Disconnect(ctx)

	// This publishes to /events
	thing.PublishEvent(ctx, []byte("Top level telemetry event"))
	// This publishes to /events/a
	thing.PublishEvent(ctx, []byte("Sub folder telemetry event"), "a")
	// This publishes to /events/a/b
	thing.PublishEvent(ctx, []byte("Sub folder telemetry event"), "a", "b")
}

Thanks to Infostellar for supporting my development of this project.

Documentation

Overview

Package iot provides a simple implementation of a Google IoT Core device.

Note: Your application must import the iot/paho package to use the default Eclipse Paho MQTT client.

Index

Examples

Constants

View Source
const DefaultAuthTokenExpiration = time.Hour

DefaultAuthTokenExpiration is the default value for Thing.AuthTokenExpiration

Variables

View Source
var ErrCancelled = fmt.Errorf("operation was cancelled or timed out")

ErrCancelled is returned when a context is canceled or times out.

View Source
var ErrConfigurationError = fmt.Errorf("required configuration values are mising")

ErrConfigurationError is returned from Connect() if either the ID or Credentials have not been set.

View Source
var ErrNotConnected = fmt.Errorf("not connected")

ErrNotConnected is returned if a message is published but the client is not connected

View Source
var ErrPublishFailed = fmt.Errorf("could not publish message")

ErrPublishFailed is returned if the client was unable to send the message

Functions

This section is empty.

Types

type ClientConstructor

type ClientConstructor func(thing Thing, options *ThingOptions) MQTTClient

ClientConstructor defines a function for creating an MQTT client instance

var NewClient ClientConstructor

NewClient is the ClientConstructor used to create MQTT client instances Override this value during testing to provide an MQTT client mock implementation

type ConfigHandler

type ConfigHandler func(thing Thing, config []byte)

ConfigHandler handles configuration updates received from the server.

type CredentialType

type CredentialType uint8

CredentialType defines the key type of the credential key pair.

const (
	// CredentialTypeRSA specfies that the credentials use RSA keys
	CredentialTypeRSA CredentialType = 0
	// CredentialTypeEC specifies that the credentials use Eliptic Curve keys
	CredentialTypeEC CredentialType = 1
)

type Credentials

type Credentials struct {
	Type        CredentialType
	Certificate tls.Certificate
	PrivateKey  interface{}
}

Credentials wraps the public and private key for a device

func LoadECCredentials

func LoadECCredentials(certificatePath string, privateKeyPath string) (*Credentials, error)

LoadECCredentials creates a Credentials struct from the given EC private key and certificate

func LoadRSACredentials

func LoadRSACredentials(certificatePath string, privateKeyPath string) (*Credentials, error)

LoadRSACredentials creates a Credentials struct from the given RSA private key and certificate

type ID

type ID struct {
	ProjectID string
	Location  string
	Registry  string
	DeviceID  string
}

ID represents the various components that uniquely identify this device

type Logger

type Logger func(args ...interface{})

Logger is used to write log output. If no Logger is provided, no logging will be performed.

type MQTTClient

type MQTTClient interface {
	// IsConnected should return true when the client is connected to the server
	IsConnected() bool

	// Connect should connect to the given MQTT server
	Connect(ctx context.Context, servers ...string) error

	// Disconnect should disconnect from the given MQTT server and clean up all client resources
	Disconnect(ctx context.Context) error

	// Publish should publish the given payload to the given topic with the given quality of service level
	Publish(ctx context.Context, topic string, qos uint8, payload interface{}) error

	// Subscribe should subscribe to the given topic with the given quality of service level and message handler
	Subscribe(ctx context.Context, topic string, qos uint8, callback ConfigHandler) error

	// Unsubscribe should unsubscribe from the given topic
	Unsubscribe(ctx context.Context, topic string) error

	// SetDebugLogger should set the logger to use for logging debug messages
	SetDebugLogger(logger Logger)

	// SetInfoLogger should set the logger to use for logging information or warning messages
	SetInfoLogger(logger Logger)

	// SetErrorLogger should set the logger to use for logging error or critical messages
	SetErrorLogger(logger Logger)

	// SetClientID should set the MQTT client id.
	SetClientID(clientID string)

	// SetCredentialsProvider should set the CredentialsProvider used by the MQTT client
	SetCredentialsProvider(crendentialsProvider MQTTCredentialsProvider)

	// SetOnConnectHandler provides a callback that should be called after the client connects to the server
	SetOnConnectHandler(handler MQTTOnConnectHandler)
}

The MQTTClient interface represents an underlying MQTT client implementation in an abstract way.

type MQTTCredentialsProvider

type MQTTCredentialsProvider func() (username string, password string)

MQTTCredentialsProvider should return the current username and password for the MQTT client to use.

type MQTTOnConnectHandler

type MQTTOnConnectHandler func(client MQTTClient)

MQTTOnConnectHandler will be called after the client connects. It should be used to resubscribe to topics and perform other connection related tasks.

type MockMQTTClient

type MockMQTTClient struct {
	Connected           bool
	ConnectedTo         []string
	Messages            map[string][]interface{}
	Subscriptions       map[string]ConfigHandler
	DebugLogger         Logger
	InfoLogger          Logger
	ErrorLogger         Logger
	ClientID            string
	CredentialsProvider MQTTCredentialsProvider
	OnConnectHandler    MQTTOnConnectHandler
	// contains filtered or unexported fields
}

MockMQTTClient implements a mock MQTT client for use in testing To use this client, use code like the following: set iot.NewClient = iot.NewMockClient

Example
var mockClient *MockMQTTClient
NewClient = func(t Thing, o *ThingOptions) MQTTClient {
	mockClient = NewMockClient(t, o)
	return mockClient
}

// Put your test code here
Output:

func NewMockClient

func NewMockClient(t Thing, o *ThingOptions) *MockMQTTClient

NewMockClient returns an instance of MockMQTTClient The MockMQTTClient documentation explains how to use this method when writing tests.

func (*MockMQTTClient) Connect

func (c *MockMQTTClient) Connect(ctx context.Context, servers ...string) error

Connect sets the Connected field to true and the ConnectedTo field to the list of servers

func (*MockMQTTClient) Disconnect

func (c *MockMQTTClient) Disconnect(ctx context.Context) error

Disconnect sets the Connected field to false and clears the ConnectedTo field

func (*MockMQTTClient) IsConnected

func (c *MockMQTTClient) IsConnected() bool

IsConnected returns the value of the Connected field

func (*MockMQTTClient) Publish

func (c *MockMQTTClient) Publish(ctx context.Context, topic string, qos uint8, payload interface{}) error

Publish adds the given payload to the Messages map under the given topic

func (*MockMQTTClient) Receive

func (c *MockMQTTClient) Receive(topic string, message []byte)

Receive imitates the client receiving a message on the given topic for testing purposes.

func (*MockMQTTClient) SetClientID

func (c *MockMQTTClient) SetClientID(clientID string)

SetClientID sets ClientID

func (*MockMQTTClient) SetCredentialsProvider

func (c *MockMQTTClient) SetCredentialsProvider(crendentialsProvider MQTTCredentialsProvider)

SetCredentialsProvider sets CredentialsProvider

func (*MockMQTTClient) SetDebugLogger

func (c *MockMQTTClient) SetDebugLogger(logger Logger)

SetDebugLogger sets DebugLogger

func (*MockMQTTClient) SetErrorLogger

func (c *MockMQTTClient) SetErrorLogger(logger Logger)

SetErrorLogger sets ErrorLogger

func (*MockMQTTClient) SetInfoLogger

func (c *MockMQTTClient) SetInfoLogger(logger Logger)

SetInfoLogger sets InfoLogger

func (*MockMQTTClient) SetOnConnectHandler

func (c *MockMQTTClient) SetOnConnectHandler(handler MQTTOnConnectHandler)

SetOnConnectHandler sets OnConnectHandler

func (*MockMQTTClient) Subscribe

func (c *MockMQTTClient) Subscribe(ctx context.Context, topic string, qos uint8, callback ConfigHandler) error

Subscribe addes the given ConfigHandler to the Subscriptions map for the given topic

func (*MockMQTTClient) Unsubscribe

func (c *MockMQTTClient) Unsubscribe(ctx context.Context, topic string) error

Unsubscribe removes the ConfigHandler from the Subscriptions map for the given topic

type Thing

type Thing interface {
	// PublishState publishes the current device state
	PublishState(ctx context.Context, message []byte) error

	// PublishEvent publishes an event. An optional hierarchy of event names can be provided.
	PublishEvent(ctx context.Context, message []byte, event ...string) error

	// Connect to the given MQTT server(s)
	Connect(ctx context.Context, servers ...string) error

	// IsConnected returns true of the client is currently connected to MQTT server(s)
	IsConnected() bool

	// Disconnect from the MQTT server(s)
	Disconnect(ctx context.Context)
}

Thing represents an IoT device

Example
ctx := context.Background()

// Your client must include the paho package
// to use the default Eclipse Paho MQTT client.
//
// include 	_ "github.com/vaelen/iot/paho"

id := &ID{
	DeviceID:  "deviceName",
	Registry:  "my-registry",
	Location:  "asia-east1",
	ProjectID: "my-project",
}

credentials, err := LoadRSACredentials("rsa_cert.pem", "rsa_private.pem")
if err != nil {
	panic("Couldn't load credentials")
}

tmpDir, err := ioutil.TempDir("", "queue-")
if err != nil {
	panic("Couldn't create temp directory")
}

options := DefaultOptions(id, credentials)
options.DebugLogger = log.Println
options.InfoLogger = log.Println
options.ErrorLogger = log.Println
options.QueueDirectory = tmpDir
options.ConfigHandler = func(thing Thing, config []byte) {
	// Do something here to process the updated config and create an updated state string
	state := []byte("ok")
	thing.PublishState(ctx, state)
}

thing := New(options)

err = thing.Connect(ctx, "ssl://mqtt.googleapis.com:443")
if err != nil {
	panic("Couldn't connect to server")
}
defer thing.Disconnect(ctx)

// This publishes to /events
thing.PublishEvent(ctx, []byte("Top level telemetry event"))
// This publishes to /events/a
thing.PublishEvent(ctx, []byte("Sub folder telemetry event"), "a")
// This publishes to /events/a/b
thing.PublishEvent(ctx, []byte("Sub folder telemetry event"), "a", "b")
Output:

func New

func New(options *ThingOptions) Thing

New returns a new Thing using the given options.

type ThingOptions

type ThingOptions struct {
	// ID identifies this device.
	// This value is required.
	ID *ID
	// Credentials are used to authenticate with the server.
	// This value is required.
	Credentials *Credentials
	// DebugLogger is used to print debug level log output.
	// If no Logger is provided, no logging will occur.
	DebugLogger Logger
	// InfoLogger is used to print info level log output.
	// If no Logger is provided, no logging will occur.
	InfoLogger Logger
	// ErrorLogger is used to print error level log output.
	// If no Logger is provided, no logging will occur.
	ErrorLogger Logger
	// LogMQTT enables logging of the underlying MQTT client.
	// If enabled, the underlying MQTT client will log at the same level as the Thing itself (WARN, DEBUG, etc).
	LogMQTT bool
	// QueueDirectory should be a directory writable by the process.
	// If not provided, message queues will not be persisted between restarts.
	QueueDirectory string
	// ConfigHandler will be called when a new configuration document is received from the server.
	ConfigHandler ConfigHandler
	// ConfigQOS sets the QoS level for receiving config updates.
	// The default value will only perform best effort delivery.
	// The suggested value is 2.
	ConfigQOS uint8
	// StateQOS sets the QoS level for sending state updates.
	// The default value will only perform best effort delivery.
	// The suggested value is 1.
	// Google does not allow a value of 2 here.
	StateQOS uint8
	// EventQOS sets the QoS level for sending event updates.
	// The default value will only perform best effort delivery.
	// The suggested value is 1.
	// Google does not allow a value of 2 here.
	EventQOS uint8
	// AuthTokenExpiration determines how often a new auth token must be generated.
	// The minimum value is 10 minutes and the maximum value is 24 hours.
	// The default value is 1 hour.
	AuthTokenExpiration time.Duration
	// Clock represents the system clock.
	// This value can be overridden for testing purposes.
	// If not provided, this will default to the regular system clock.
	Clock clock.Clock
}

ThingOptions holds the options that are used to create a Thing

func DefaultOptions

func DefaultOptions(id *ID, credentials *Credentials) *ThingOptions

DefaultOptions returns the default set of options.

Directories

Path Synopsis
Package paho provides an iot.MQTTClient implementation that uses the Eclipse Paho MQTT client.
Package paho provides an iot.MQTTClient implementation that uses the Eclipse Paho MQTT client.

Jump to

Keyboard shortcuts

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