framework: github.com/openchirp/framework Index | Examples | Files | Directories

package framework

import "github.com/openchirp/framework"

Package framework provides the management interfaces for Users, Devices, and Services. Please use the appropriate top level class for the type of interface you need. The parent class is Client.

Users - StartUserClient()
Device - StartDeviceClient()
Service - StartServiceClientManaged()

Index

Examples

Package Files

client.go device.go importpath.go service.go service_managed.go types.go user.go

Variables

var ErrDeviceUpdatesAlreadyStarted = errors.New("Device updates channel already started")
var ErrDeviceUpdatesNotStarted = errors.New("Device updates channel not started")
var ErrMarshalDeviceStatusMessage = errors.New("Failed to marshall device status message into JSON")
var ErrMarshalStatusMessage = errors.New("Failed to marshall status message into JSON")
var ErrNotImplemented = errors.New("This method is not implemented yet")
var MQTTBridgeClient = false

MQTTBridgeClient sets whether the MQTT client will identify itself as a bridge to the broker

type Client Uses

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

Client represents the context for a single client

func (*Client) FetchDeviceInfo Uses

func (c *Client) FetchDeviceInfo(deviceID string) (rest.DeviceNode, error)

FetchDeviceInfo requests and fetches device information from the REST interface

func (*Client) FetchLocation Uses

func (c *Client) FetchLocation(locationID string) (rest.LocationNode, error)

FetchLocation request the information about locationID

func (*Client) FetchLocationDevices Uses

func (c *Client) FetchLocationDevices(locationID string, recursive bool) ([]rest.NodeDescriptor, error)

FetchLocationDevices fetches the node descriptors for devices at locationID. If recursive is true, all devices at sublocation are included.

type ClientTopicHandler Uses

type ClientTopicHandler func(topic string, payload []byte)

ClientTopicHandler is a function prototype for a subscribed topic callback

type Device Uses

type Device interface {
    // ProcessLink is called once, during the initial setup of a
    // device, and is provided the service config for the linking device.
    // The service is expected to parse the provided config for initial setup.
    // The returned string is used as the device's link status.
    ProcessLink(ctrl *DeviceControl) string
    // ProcessUnlink is called once, when the service has been unlinked from
    // the device.
    ProcessUnlink(ctrl *DeviceControl)
    // ProcessConfigChange is called only when the config has truly changed.
    // The specific config key/values which changed are provided in cchange
    // and the original config is provided in coriginal. Upon successful
    // completion of this call, the device's link status will be updated with
    // the returned string.
    //
    // If you do not want to handle incremental config changes, you may return
    // false. In this case, the service manager will restore the original
    // config, call for the device to be unlinked(ProcessUnlinked), clear the
    // device context, and call ProcessLink with the new config.
    // Note that the new config is accessible through ctrl.Config()
    ProcessConfigChange(ctrl *DeviceControl, cchanges, coriginal map[string]string) (string, bool)
    // ProcessMessage is called upon receiving a pubsub message destined for
    // this device. Along with the standard DeviceControl object, the
    // handler is provided a Message object, which contains the received
    // message's payload, subtopic, and the provided Subscribe key.
    ProcessMessage(ctrl *DeviceControl, msg Message)
}

Device is the interface services will implement

type DeviceClient Uses

type DeviceClient struct {
    Client
    // contains filtered or unexported fields
}

DeviceClient represents the context for a single user device session

func StartDeviceClient Uses

func StartDeviceClient(frameworkuri, brokeruri, id, token string) (*DeviceClient, error)

StartDeviceClient starts the device client management layer

func (*DeviceClient) Publish Uses

func (c *DeviceClient) Publish(subtopic string, payload interface{}) error

Publish publishes a payload to a given mqtt topic

func (*DeviceClient) StopClient Uses

func (c *DeviceClient) StopClient()

StopClient shuts down a started device client

func (*DeviceClient) Subscribe Uses

func (c *DeviceClient) Subscribe(subtopic string, callback ClientTopicHandler) error

Subscribe registers a callback for receiving on a device subtopic

func (*DeviceClient) Unsubscribe Uses

func (c *DeviceClient) Unsubscribe(subtopics ...string) error

Unsubscribe deregisters a callback for a given mqtt topics

type DeviceControl Uses

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

DeviceControl provides a simplified set of methods for controlling a single device. A DeviceContol object is provided within the context of a single device. The key uses are to Subscribe/Publish/Unsubscribe (pubsub methods) to a device's subtopic and to present the device's current Config and Id. Understand that the pubsub methods will automatically prepend device's topic prefix (ex. openchirp/device/<device_id>/) to the specified subtopic.

Additionally, you should note that the Pubsub methods do not return errors and do not ask you to provide message handler functions. This shifts the responsibility of error handling and message passing to the Managed Service client.

func (*DeviceControl) Config Uses

func (c *DeviceControl) Config() map[string]string

Config returns this device's current config

func (*DeviceControl) Id Uses

func (c *DeviceControl) Id() string

Id returns this device's id

func (*DeviceControl) Publish Uses

func (c *DeviceControl) Publish(subtopic string, payload interface{})

Publish publishes payload to this device's subtopic

func (*DeviceControl) Subscribe Uses

func (c *DeviceControl) Subscribe(subtopic string, key interface{})

Subscribe to a device's subtopic and associate with key.

When receiving a message for this subtopic, the Device's ProcessMessage handler will be invoked with the message and the this key. See

func (*DeviceControl) Unsubscribe Uses

func (c *DeviceControl) Unsubscribe(subtopics ...string)

Unsubscribe unsubscribes from the specified device's subtopics

func (*DeviceControl) UnsubscribeAll Uses

func (c *DeviceControl) UnsubscribeAll()

UnsubscribeAll unsubscribes from all of this device's subtopics

type DeviceUpdate Uses

type DeviceUpdate struct {
    Type   DeviceUpdateType
    Id     string
    Topic  string
    Config map[string]string
}

DeviceUpdate represents a pending service config change for a device

func (DeviceUpdate) Error Uses

func (du DeviceUpdate) Error() string

func (DeviceUpdate) String Uses

func (du DeviceUpdate) String() string

String provides a human parsable string for DeviceUpdates

type DeviceUpdateType Uses

type DeviceUpdateType int

DeviceUpdateType represents enumeration of DeviceUpdate types

const (
    // DeviceUpdateAdd indicates that a new device linked in this service
    DeviceUpdateTypeAdd DeviceUpdateType = iota
    // DeviceUpdateRem indicates a device has unlinked this service
    DeviceUpdateTypeRem
    // DeviceUpdateUpd indicates that a device this service's config
    DeviceUpdateTypeUpd
    // DeviceUpdateTypeErr indicates an error was encountered while receiving
    // a device update event. The error message can be fetched from
    // DeviceUpdate.Error()
    DeviceUpdateTypeErr
)

func (DeviceUpdateType) String Uses

func (dut DeviceUpdateType) String() (s string)

String associates a pretty name with the DeviceUpdateTypes

type Message Uses

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

Message holds a received pubsub payload and topic along with the provided subscription key

func (Message) Key Uses

func (t Message) Key() interface{}

Key returns the provided subscription key for this message

func (Message) Payload Uses

func (t Message) Payload() []byte

Payload returns the pubsub payload of this message

func (Message) String Uses

func (t Message) String() string

String shows all parts of the message as a human readable string

func (Message) Topic Uses

func (t Message) Topic() string

Topic returns the pubsub subtopic which received this message

type ServiceClient Uses

type ServiceClient struct {
    Client
    // contains filtered or unexported fields
}

ServiceClient hold a single ses.Publish(s.)rvice context

func StartServiceClient Uses

func StartServiceClient(frameworkURI, brokerURI, id, token string) (*ServiceClient, error)

StartServiceClient starts the service management layer

func StartServiceClientManaged Uses

func StartServiceClientManaged(
    frameworkURI,
    brokerURI,
    id,
    token,
    statusmsg string,
    newdevice func() Device,
) (*ServiceClient, error)

StartServiceClientManaged starts the service client layer using the fully managed mode

Code:

package main

import (
    "fmt"
    "log"
    "os"
    "os/signal"
    "syscall"

    "github.com/openchirp/framework"
)

const (
    // The subscription key used to identify a messages types
    rawRxKey = 0
    rawTxKey = 1
)

// CDevice holds any data you want to keep around for a specific
// device that has linked your service.
//
// In this example, we will keep track of the rawrx and rawtx message counts
type CDevice struct {
    rawRxCount int
    rawTxCount int
}

// NewCDevice is called by the framework when a new device has been linked.
func NewCDevice() framework.Device {
    d := new(CDevice)
    // The following initialization is redundant in Go
    d.rawRxCount = 0
    d.rawTxCount = 0
    // Change type to the Device interface
    return framework.Device(d)
}

// ProcessLink is called once, during the initial setup of a
// device, and is provided the service config for the linking device.
func (d *CDevice) ProcessLink(ctrl *framework.DeviceControl) string {
    // Subscribe to subtopic "rawrx"
    ctrl.Subscribe("rawrx", rawRxKey)
    // Subscribe to subtopic "rawtx"
    ctrl.Subscribe("rawtx", rawTxKey)

    // This message is sent to the service status for the linking device
    return "Success"
}

// ProcessUnlink is called once, when the service has been unlinked from
// the device.
func (d *CDevice) ProcessUnlink(ctrl *framework.DeviceControl) {
    // The framework already handles unsubscribing from all
    // Device associted subtopics, so we don't need to call
    // ctrl.Unsubscribe.
}

// ProcessConfigChange is intended to handle a service config updates.
// If your program does not need to handle incremental config changes,
// simply return false, to indicate the config update was unhandled.
// The framework will then automatically issue a ProcessUnlink and then a
// ProcessLink, instead. Note, NewCDevice is not called.
//
// For more information about this or other Device interface functions,
// please see https://godoc.org/github.com/OpenChirp/framework#Device .
func (d *CDevice) ProcessConfigChange(ctrl *framework.DeviceControl, cchanges, coriginal map[string]string) (string, bool) {
    return "", false

    // If we have processed this config change, we should return the
    // new service status message and true.
    //
    //return "Sucessfully updated", true
}

// ProcessMessage is called upon receiving a pubsub message destined for
// this CDevice.
// Along with the standard DeviceControl object, the handler is provided
// a Message object, which contains the received message's payload,
// subtopic, and the provided Subscribe key.
func (d *CDevice) ProcessMessage(ctrl *framework.DeviceControl, msg framework.Message) {

    if msg.Key().(int) == rawRxKey {
        d.rawRxCount++
        subtopic := "rawrxcount"
        ctrl.Publish(subtopic, fmt.Sprint(d.rawRxCount))
    } else if msg.Key().(int) == rawTxKey {
        d.rawTxCount++
        subtopic := "rawtxcount"
        ctrl.Publish(subtopic, fmt.Sprint(d.rawTxCount))
    } else {
        log.Fatalln("Received unassociated message")
    }
}

func main() {
    // Parse parameters from command line or environment variables
    frameworkServer := "http://localhost:7000"
    mqttServer := "localhost:1883"
    serviceId := "5a1ea73df76abe01c57abfb8"
    serviceToken := "DJpHxwmExGbcYwsEHgQezDVeKS4N"

    c, err := framework.StartServiceClientManaged(
        frameworkServer,
        mqttServer,
        serviceId,
        serviceToken,
        "Unexpected disconnect!",
        NewCDevice)
    if err != nil {
        log.Fatalln("Failed to StartServiceClient: ", err)
    }
    defer c.StopClient()
    log.Println("Started service")

    /* Post service's global status */
    err = c.SetStatus("Started")
    if err != nil {
        log.Fatalln("Failed to publish service status: ", err)
        return
    }
    log.Println("Published Service Status")

    /* Setup signal channel */
    signals := make(chan os.Signal, 1)
    signal.Notify(signals, os.Interrupt, syscall.SIGTERM)

    /* Wait on a signal */
    <-signals
    log.Println("Shutting down")

    /* Post service's global status */
    err = c.SetStatus("Shutting down")
    if err != nil {
        log.Fatalln("Failed to publish service status: ", err)
        return
    }
    log.Println("Published Service Status")
}

ExampleStartServiceClientManaged_minimal demonstates the minimal configuration to use StartServiceClientManaged

Code:

package main

import (
    "log"

    "github.com/openchirp/framework"
)

type Device struct {
}

func NewDevice() framework.Device {
    d := new(Device)
    return framework.Device(d)
}
func (d *Device) ProcessLink(ctrl *framework.DeviceControl) string {
    return "Success"
}
func (d *Device) ProcessUnlink(ctrl *framework.DeviceControl) {
}
func (d *Device) ProcessConfigChange(ctrl *framework.DeviceControl, cchanges, coriginal map[string]string) (string, bool) {
    return "", false
}
func (d *Device) ProcessMessage(ctrl *framework.DeviceControl, msg framework.Message) {
}

// ExampleStartServiceClientManaged_minimal demonstates the minimal configuration
// to use StartServiceClientManaged
func main() {
    // Parse parameters from command line or environment variables
    frameworkServer := "http://localhost:7000"
    mqttServer := "localhost:1883"
    serviceId := "5a1ea73df76abe01c57abfb8"
    serviceToken := "DJpHxwmExGbcYwsEHgQezDVeKS4N"

    c, err := framework.StartServiceClientManaged(
        frameworkServer,
        mqttServer,
        serviceId,
        serviceToken,
        "Unexpected disconnect!",
        NewDevice)
    if err != nil {
        log.Fatalln("Failed to StartServiceClient: ", err)
    }
    defer c.StopClient()
    log.Println("Started service")

    /* Post service's global status */
    err = c.SetStatus("Started")
    if err != nil {
        log.Fatalln("Failed to publish service status: ", err)
        return
    }
    log.Println("Published Service Status")
}

func StartServiceClientStatus Uses

func StartServiceClientStatus(frameworkURI, brokerURI, id, token, statusmsg string) (*ServiceClient, error)

StartServiceClientStatus starts the service management layer with a optional statusmsg if the service disconnects improperly

func (*ServiceClient) FetchDeviceConfigs Uses

func (c *ServiceClient) FetchDeviceConfigs() ([]rest.ServiceDeviceListItem, error)

FetchDeviceConfigs requests all device configs for the current service

func (*ServiceClient) FetchDeviceConfigsAsUpdates Uses

func (c *ServiceClient) FetchDeviceConfigsAsUpdates() ([]DeviceUpdate, error)

FetchDeviceConfigsAsUpdates requests all device configs for the current service and converts them into DeviceUpdate with DeviceUpdateTypeAdd as the type

func (*ServiceClient) GetProperties Uses

func (c *ServiceClient) GetProperties() map[string]string

GetProperties returns the full service properties key/value mapping

func (*ServiceClient) GetProperty Uses

func (c *ServiceClient) GetProperty(key string) string

GetProperty fetches the service property associated with key. If it does not exist the blank string is returned.

func (*ServiceClient) Publish Uses

func (c *ServiceClient) Publish(topic string, payload interface{}) error

Publish publishes a payload to a given mqtt topic

func (*ServiceClient) SetDeviceStatus Uses

func (c *ServiceClient) SetDeviceStatus(id string, msgs ...interface{}) error

SetDeviceStatus publishes a device's linked service status message

func (*ServiceClient) SetStatus Uses

func (c *ServiceClient) SetStatus(msgs ...interface{}) error

SetStatus publishes the service status message

func (*ServiceClient) StartDeviceUpdates Uses

func (c *ServiceClient) StartDeviceUpdates() (<-chan DeviceUpdate, error)

StartDeviceUpdates subscribes to the live service events topic and opens a channel to read the updates from. This does not inject the initial configurations into the channel at start like StartDeviceUpdatesSimple.

func (*ServiceClient) StartDeviceUpdatesSimple Uses

func (c *ServiceClient) StartDeviceUpdatesSimple() (<-chan DeviceUpdate, error)

StartDeviceUpdatesSimple subscribes to the live mqtt service news topic and opens a channel to read the updates from. It will automatically fetch the initial configuration and send those as DeviceUpdateTypeAdd updates first. Due to the time between subscribing to live events and requesting the static configuration, there may be redundant DeviceUpdateTypeAdd updates. Your program should account for this.

func (*ServiceClient) StopClient Uses

func (c *ServiceClient) StopClient()

StopClient shuts down a started service

func (*ServiceClient) StopDeviceUpdates Uses

func (c *ServiceClient) StopDeviceUpdates()

StopDeviceUpdates unsubscribes from service news topic and closes the news channel

func (*ServiceClient) Subscribe Uses

func (c *ServiceClient) Subscribe(topic string, callback func(topic string, payload []byte)) error

Subscribe registers a callback for a receiving a given mqtt topic payload

func (*ServiceClient) SubscribeWithClient Uses

func (c *ServiceClient) SubscribeWithClient(topic string, callback ServiceTopicHandler) error

SubscribeWithClient registers a callback for a receiving a given mqtt topic payload and provides the client object

func (*ServiceClient) Unsubscribe Uses

func (c *ServiceClient) Unsubscribe(topics ...string) error

Unsubscribe deregisters a callback for a given mqtt topic

func (*ServiceClient) UpdateConfigParameters Uses

func (c *ServiceClient) UpdateConfigParameters(configParams []rest.ServiceConfigParameter) error

UpdateConfigParameters updates the service's device config template

type ServiceTopicHandler Uses

type ServiceTopicHandler func(client *ServiceClient, topic string, payload []byte)

ServiceTopicHandler is a function prototype for a subscribed topic callback

type UserClient Uses

type UserClient struct {
    Client
}

UserClient represents the context for a single user client session

func StartUserClient Uses

func StartUserClient(frameworkuri, brokeruri, id, token string) (*UserClient, error)

StartUserClient starts the user client management layer

func (*UserClient) Publish Uses

func (c *UserClient) Publish(topic string, payload interface{}) error

Publish publishes a payload to a given mqtt topic

func (*UserClient) StopClient Uses

func (c *UserClient) StopClient()

StopClient shuts down a started user client

func (*UserClient) Subscribe Uses

func (c *UserClient) Subscribe(topic string, callback UserClientTopicHandler) error

Subscribe registers a callback for a receiving a given mqtt topic payload

func (*UserClient) Unsubscribe Uses

func (c *UserClient) Unsubscribe(topics ...string) error

Unsubscribe deregisters a callback for a given mqtt topics

type UserClientTopicHandler Uses

type UserClientTopicHandler func(client *UserClient, topic string, payload []byte)

UserClientTopicHandler is a function prototype for a subscribed topic callback

Directories

PathSynopsis
pubsubPackage pubsub hold the interfaces and utilities to work with the PubSub side of the OpenChirp framework
restPackage rest provides the data structures and primitive mechanisms for representing and communicating framework constructs with the RESTful server.
utilsPackage utils holds common data structures and functions useful for working with OpenChirp.

Package framework imports 9 packages (graph) and is imported by 8 packages. Updated 2019-03-07. Refresh now. Tools for package owners.