Skip to content

Services

inhies edited this page Dec 15, 2016 · 2 revisions

Introduction

Services are plugins designed to extend the functionality of Casa. Almost everything Casa does is run as a service to enable flexibility for the user.

Interface

A Casa service need only implement the following three functions:

Start(config *viper.Viper) error
UseLogger(logger Logger)
Stop() error
  • Start(config *viper.Viper) error: This is the main part of the service, where it is configured and then started. config is an in-memory representation of the section of configuration file for the service. For example the Services.Logger portion of the config file is passed to the logger service when Start() is called. An error is returned if there is any problem starting the service.

  • UseLogger(logger Logger): This specifies the logger to be used for debugging output. It allows the use of a single logger throughout the entire program.

  • Stop() error: This stops the service and returns an error if there were any issues in doing so.

Details

Services are responsible for creating their own MQTT client and connecting to the MessageBus. By default, services can connect to tcp://127.0.0.1:1883 with no SSL or other authentication. If the user were to specify one or more username/password combinations for outside devices to connect to the MessageBus, then a random username/password combination will be generated and passed to the service when Start() is called. They will be available in config as MQTT.User and MQTT.Pass.

Endpoints

When a service is started it will advertise itself and its endpoints to the New/<service name>/# topic. For example, the hue service will send a message to New/Hue/<bridge identifier/Light/<light identifier>/Color Name with a payload of name string : Sets the light to the predefined color.

This allows all other services to subscribe to the New/# topic and be notified of new devices and endpoints when they are discovered. The payload specifies the parameter(s) to send to the topic in order to affect it. The payload formatting is <variable name> <variable type> : <description> just like you would use in a Go function prototype. It can be simple such as delay int : Number of seconds to wait or more complex like name string, brightness,saturation int : Sets the name of the light, as well as the brightness and saturation levels. NOTE: This could/should change? I'm unsure of what the best format for this would be and am open to suggestions).

For example, to change the color of a Hue light, you would send Red to the topic Hue/<bridge identifier/Light/<light identifier>/Color Name/Set. Note the /Set suffix that was added, telling the Hue service we want to change this value. When the Hue service receives this message it will perform the action, and if successful will now publish Red to Hue/<bridge identifier/Light/<light identifier>/Color Name indicating the color has been changed.

Generally speaking, all messages published by a service should be retained. This allows a new service or client that just came online to subscribe and get the current values for whatever it wants, instead of having to query for them. /Set messages should not be retained. Also note that a message with an empty payload can not be retained, as sending an empty payload with the retain flag set is how you remove a retained message.

Clone this wiki locally