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
- func CreateTopic(thingID string, topicMessageType string) string
- func SplitTopic(topic string) (thingID string, topicType string, subject string)
- type ConnectionStatus
- type ConsumedThing
- func (cThing *ConsumedThing) GetThingDescription() *thing.ThingDescription
- func (cThing *ConsumedThing) HandleEvent(eventName string, message []byte)
- func (cThing *ConsumedThing) HandlePropertyChange(propName string, message []byte)
- func (cThing *ConsumedThing) InvokeAction(actionName string, data interface{}) error
- func (cThing *ConsumedThing) ObserveProperty(name string, listener func(name string, data *thing.InteractionOutput)) error
- func (cThing *ConsumedThing) ReadAllProperties() map[string]*thing.InteractionOutput
- func (cThing *ConsumedThing) ReadMultipleProperties(names []string) map[string]*thing.InteractionOutput
- func (cThing *ConsumedThing) ReadProperty(name string) (*thing.InteractionOutput, error)
- func (cThing *ConsumedThing) Stop()
- func (cThing *ConsumedThing) SubscribeEvent(eventName string, ...) error
- func (cThing *ConsumedThing) WriteMultipleProperties(properties map[string]interface{}) error
- func (cThing *ConsumedThing) WriteProperty(propName string, value interface{}) error
- type ConsumedThingFactory
- func (ctFactory *ConsumedThingFactory) Authenticate(password string) error
- func (ctFactory *ConsumedThingFactory) Connect(password string) error
- func (ctFactory *ConsumedThingFactory) ConnectWithCert(clientCert *tls.Certificate) error
- func (ctFactory *ConsumedThingFactory) Consume(td *thing.ThingDescription) *ConsumedThing
- func (ctFactory *ConsumedThingFactory) Destroy(cThing *ConsumedThing)
- func (ctFactory *ConsumedThingFactory) Disconnect()
- func (ctFactory *ConsumedThingFactory) GetThingStore() *thing.ThingStore
- type ConsumedThingProtocolBinding
- func (binding *ConsumedThingProtocolBinding) InvokeAction(actionName string, data interface{}) error
- func (binding *ConsumedThingProtocolBinding) Start(authClient *tlsclient.TLSClient, dirClient *tlsclient.TLSClient, ...)
- func (binding *ConsumedThingProtocolBinding) Stop()
- func (binding *ConsumedThingProtocolBinding) WriteProperty(propName string, propValue any) error
- type Subscription
Constants ¶
const ( SubscriptionTypeAction = "action" SubscriptionTypeEvent = "event" SubscriptionTypeProperty = "property" )
const TopicEmitEvent = "things/{thingID}/event/"
const TopicInvokeAction = "things/{thingID}/action/"
Variables ¶
This section is empty.
Functions ¶
func CreateTopic ¶
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
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:
- no JS 'Promises'
- 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:
- Subscribes to events over MQTT events and updates Consumed Thing values
- Handles requests to read properties from the directory service.
- 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