consumedthing

package
v0.0.0-...-2920ad6 Latest Latest
Warning

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

Go to latest
Published: Jan 1, 2023 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package consumedthing that implements the ConsumedThing API Consumed Things are remote representations of Things used by consumers.

Package consumedthing with Subscription definitions for consumed thing users

Package consumedthing with messaging topics for the MQTT protocol binding

Index

Constants

View Source
const (
	SubscriptionTypeAction   = "action"
	SubscriptionTypeEvent    = "event"
	SubscriptionTypeProperty = "property"
)
View Source
const TopicEmitEvent = "things/{thingID}/event/"
View Source
const TopicInvokeAction = "things/{thingID}/action/"

Variables

This section is empty.

Functions

func CreateTopic

func CreateTopic(thingID string, topicMessageType string) string

CreateTopic creates a new topic for publishing or subscribing to a message of type td, action, event, property thingID to listen on. "" or "+" for any thingID

func SplitTopic

func SplitTopic(topic string) (thingID string, topicType string, subject string)

SplitTopic breaks a MQTT topic into thingID, topic type (td, event, action, property value) and optionally a subject like for example 'properties' in 'things/event/properties'

Types

type ConnectionStatus

type ConnectionStatus struct {

	// AccessToken to authenticate with
	AccessToken string

	// Authenticated indicates the access token is valid
	Authenticated bool

	// AuthStatus with a text description of authentication result
	AuthStatus string

	// Connected indicates that a message bus is connected
	Connected bool

	// DirectoryRead indicates the TDs are obtained from the directory
	DirectoryRead bool

	// StatusMessage with a human description of the connection status
	StatusMessage string
}

ConnectionStatus contains the status of protocol bindings used in the factory

type ConsumedThing

type ConsumedThing struct {

	/** Hook to invoke action via the protocol binding.
	 * This can be set to a protocol binding by the protocol factory
	 * By default this throws an error
	 *
	 * @param cThing of the thing whose action to invoke
	 * @param name of the action to invoke
	 * @param params containing the data of the action as defined in the action affordance schema
	 * @returns an error or nil
	 */
	InvokeActionHook func(name string, params interface{}) error

	/** Hook to write properties via the protocol binding
	 * This can be set to a protocol binding by the protocol factory.
	 * By default this throws an error.
	 *
	 * @param cThing of the thing to write to
	 * @param props containing the name-value pair where value is the text representation to write.
	 * @returns a promise that resolves when the request to write properties has been sent
	 */
	WritePropertyHook func(propName string, propValue any) error

	// Internal slot with Thing Description document this consumed thing consumes
	TD *thing.ThingDescription
	// contains filtered or unexported fields
}

ConsumedThing is the implementation of an ConsumedThing interface This is modelled after the scripting definition of [WoT Consumed Thing](https://w3c.github.io/wot-scripting-api/#the-consumedthing-interface). It attempts to be as similar as possible but language differences will cause some differences. That said, the concepts and most of its usage will be similar.

Key differences:

  1. no JS 'Promises'
  2. consumed things cache their properties so readproperty will obtain immediate results

func CreateConsumedThing

func CreateConsumedThing(td *thing.ThingDescription) *ConsumedThing

CreateConsumedThing constructs a consumed thing from a TD.

A consumed Thing is a remote instance of a thing for the purpose of interaction with thing providers. This is intended for use by the ConsumedThingFactory only. The factory installs the hooks to connect to a protocol binding for read/write

Use factory.consume() to obtain a working instance. @param td is a Thing Description document of the Thing to consume.

func (*ConsumedThing) GetThingDescription

func (cThing *ConsumedThing) GetThingDescription() *thing.ThingDescription

GetThingDescription returns the TD document of this consumed Thing This returns the cached version of the TD

func (*ConsumedThing) HandleEvent

func (cThing *ConsumedThing) HandleEvent(eventName string, message []byte)

HandleEvent handles incoming events for the consumed thing.

This updates the cached event value and invokes the subscriber to the event, if any, or the default subscriber

address is the MQTT topic that the event is published on as: things/{thingID}/event/{eventName}
whereas message is the body of the event.

func (*ConsumedThing) HandlePropertyChange

func (cThing *ConsumedThing) HandlePropertyChange(propName string, message []byte)

HandlePropertyChange handles change of consumed thing property value.

This updates the cached property value and notifies the property observer, if any.

address is the MQTT topic that the event is published on as: things/{thingID}/event/{eventName}
whereas message is the body of the event.

func (*ConsumedThing) InvokeAction

func (cThing *ConsumedThing) InvokeAction(actionName string, data interface{}) error

InvokeAction makes a request for invoking an Action and returns once the request is submitted.

This will be posted on topic: "things/{thingID}/action/{actionName}" with data as payload

Takes as arguments actionName, optionally action data as defined in the TD. Returns nil if the action request was submitted successfully or an error if failed

func (*ConsumedThing) ObserveProperty

func (cThing *ConsumedThing) ObserveProperty(
	name string, listener func(name string, data *thing.InteractionOutput)) error

ObserveProperty makes a request for Property value change notifications. Takes as arguments propertyName and a handler.

returns an error if an active observation already exists

func (*ConsumedThing) ReadAllProperties

func (cThing *ConsumedThing) ReadAllProperties() map[string]*thing.InteractionOutput

ReadAllProperties reads all properties of the Thing with one request. Returns a PropertyMap object that maps keys from all Property names to InteractionOutput of the properties.

func (*ConsumedThing) ReadMultipleProperties

func (cThing *ConsumedThing) ReadMultipleProperties(names []string) map[string]*thing.InteractionOutput

ReadMultipleProperties reads multiple Property values with one request. propertyNames is an array with names of properties to return Returns a PropertyMap object that maps keys from propertyNames to InteractionOutput of that property.

func (*ConsumedThing) ReadProperty

func (cThing *ConsumedThing) ReadProperty(name string) (*thing.InteractionOutput, error)

ReadProperty reads a Property value from the local cache. Returns the last known property value or an error if the name is not a known property.

func (*ConsumedThing) Stop

func (cThing *ConsumedThing) Stop()

Stop delivering notifications for event subscriptions This is an internal method for use by the factory.

func (*ConsumedThing) SubscribeEvent

func (cThing *ConsumedThing) SubscribeEvent(
	eventName string, handler func(eventName string, data *thing.InteractionOutput)) error

SubscribeEvent makes a request for subscribing to events

Takes as arguments eventName, listener Returns nil if subscription is successful or NotAllowed error if a subscription already exists

func (*ConsumedThing) WriteMultipleProperties

func (cThing *ConsumedThing) WriteMultipleProperties(properties map[string]interface{}) error

WriteMultipleProperties writes multiple property values. Takes as arguments properties - as a map keys being Property names and values as Property values.

This will be posted as individual update requests

It returns an error if the action could not be sent and nil if the action is successfully

published. Final success is achieved if the property value will be updated through an event.

func (*ConsumedThing) WriteProperty

func (cThing *ConsumedThing) WriteProperty(propName string, value interface{}) error

WriteProperty submit a request to change a property value. Takes as arguments propertyName and value, and sends a property update to the exposedThing that in turn updates the actual device. This does not update the property immediately. It is up to the exposedThing to perform necessary validation and notify subscribers with an event after the change has been applied.

There is no error feedback in case the request cannot be handled. The requester will only receive a property change event when the request has completed successfully. Failure to complete the request can be caused by an invalid value or if the IoT device is not in a state to accept changes.

TBD: if there is a need to be notified of failure then a future update can add a write-property failed event.

This will be published on topic "things/{thingID}/action/{name}"

It returns an error if the property update could not be sent and nil if it is successfully

published. Final confirmation is obtained if an event is received with the updated property value.

type ConsumedThingFactory

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

ConsumedThingFactory for managing connected instances of consumed things. ConsumedThing's are created using the 'consume' method.

This factory is intended for consumers for creating client side 'Thing' instances, eg consumed things It will bind the instance to protocol bindings for receiving and updating TD, property and events.

func CreateConsumedThingFactory

func CreateConsumedThingFactory(
	appID string, account *accounts.AccountRecord, caCert *x509.Certificate) *ConsumedThingFactory

CreateConsumedThingFactory creates a factory instance for consumed things for the given account

If no CA certificate is provided there will be no protection against a man-in-the-middle attack. To obtain a CA, request it from the administrator, copy it from the Hub, copy it from the web browser or use the idprov service, depending on the circumstances.

appID unique ID of the application instance
account used to connect with
caCert previously obtained CA certificate used to validate the server

func (*ConsumedThingFactory) Authenticate

func (ctFactory *ConsumedThingFactory) Authenticate(password string) error

Authenticate or refresh the access token used by the authentication protocol.

This does nothing if authenticated using a client certificate.

If a password is provided then obtain a new access and refresh token pair using the account login ID. If no password is provided attempt to refresh the tokens.

func (*ConsumedThingFactory) Connect

func (ctFactory *ConsumedThingFactory) Connect(password string) error

Connect the factory to the Hub services and initialize the protocol binding connections.

This will attempt to refresh the existing JWT token pair. If connect fails then retry using a valid password for the account.

Call Disconnect before shutting down.

password to use when no valid refresh token is available

func (*ConsumedThingFactory) ConnectWithCert

func (ctFactory *ConsumedThingFactory) ConnectWithCert(clientCert *tls.Certificate) error

ConnectWithCert connects the factory to the Hub services using a client certificate for authentication.

Call Disconnect before shutting down.

clientCert with the certificate signed by the Hub CA

func (*ConsumedThingFactory) Consume

func (ctFactory *ConsumedThingFactory) Consume(td *thing.ThingDescription) *ConsumedThing

Consume returns a 'Consumed Thing' instance for interacting with a remote (exposed) thing and binds it to the relevant protocol bindings. This is the only method allowed to create consumed thing instances.

This attaches it to interaction protocol bindings: - directory binding to read properties and history - mqtt binding to subscribe and request updates

If a consumed thing already exists then simply return it.

@param td is the Thing TD whose interaction instance to create

func (*ConsumedThingFactory) Destroy

func (ctFactory *ConsumedThingFactory) Destroy(cThing *ConsumedThing)

Destroy stops and removes the consumed thing. This stops listening to external events

func (*ConsumedThingFactory) Disconnect

func (ctFactory *ConsumedThingFactory) Disconnect()

Disconnect the factory from the account

func (*ConsumedThingFactory) GetThingStore

func (ctFactory *ConsumedThingFactory) GetThingStore() *thing.ThingStore

GetThingStore returns the Thing store where the factory keeps its things

type ConsumedThingProtocolBinding

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

ConsumedThingProtocolBinding is the protocol binding for consumed things FIXME: use the new Hub APIs and don't rely on mqtt topic format

This:

  1. Subscribes to events over MQTT events and updates Consumed Thing values
  2. Handles requests to read properties from the directory service.
  3. Installs the action hook to submit actions to exposed things over MQTT.

func CreateConsumedThingProtocolBinding

func CreateConsumedThingProtocolBinding(cThing *ConsumedThing) *ConsumedThingProtocolBinding

CreateConsumedThingProtocolBinding creates the protocol binding for the consumed thing. Use 'Connect' to subscribe and Stop to unsubscribe.

func (*ConsumedThingProtocolBinding) InvokeAction

func (binding *ConsumedThingProtocolBinding) InvokeAction(actionName string, data interface{}) error

InvokeAction publishes the action request

@param cThing is the consumed thing invoking the action @param actionName name of the action to invoke as described in the TD actions section @param data parameters to pass to the action as defined in the TD schema Returns nil if the request is sent or an error if failed.

func (*ConsumedThingProtocolBinding) Start

func (binding *ConsumedThingProtocolBinding) Start(
	authClient *tlsclient.TLSClient,
	dirClient *tlsclient.TLSClient,
	mqttClient *mqttclient.MqttClient,
)

Start subscribes to Thing events

func (*ConsumedThingProtocolBinding) Stop

func (binding *ConsumedThingProtocolBinding) Stop()

Stop unsubscribes from all messages

func (*ConsumedThingProtocolBinding) WriteProperty

func (binding *ConsumedThingProtocolBinding) WriteProperty(propName string, propValue any) error

WriteProperty publishes a request to change a property value in the exposed thing This does not update the property immediately. It is up to the exposedThing to perform necessary validation and notify subscribers with an property update event after the change has been applied.

TODO: Currently if the message bus or the exposed thing refuses the request there is no reject message. The intent is to add support of a reject message when the MQTT broker rejects it, or when the exposed thing is offline or rejects the request due to an invalid payload.

@param propName with the name of the property to write as defined in the Thing's TD document @param propValue with the new value Returns nil if the request is sent or an error if failed.

type Subscription

type Subscription struct {
	SubType string // "property" | "event" | "action" | nil
	Name    string // property, event or action name, or "" for all properties, events or actions

	// not clear what the purpose of this is. Validation? tbd
	//form        ThingForm        // not clear what the purpose of this is. Validation? tbd
	Handler func(name string, message *thing.InteractionOutput)
	// contains filtered or unexported fields
}

Subscription describes the type of observed property, event or action

Jump to

Keyboard shortcuts

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