#Sensor API Classes Used to create a pub/sub stream of sensor data between device and agent. The api supports subscriptions to data stream and event channels. Communication is based on channel names. These are unique strings used to identify each channel a user can subscribe to. In the example code I have used the name of the sensor instance underscore description of the data (ex - "nora_tempReadings"), however the string can be anything as long as no other channel name is the same.
##Dependencies
- Sensor Classes (ex. TMP1x2, LIS3MDL)
- Bullwinkle Class
- Bullwinkle_Session Class
#Agent Side API
###List of Functions
#configureChannel
#setBroadcastCallback
#getChannels
#updateReportingInterval
#updateReadingInterval
#updateEventParams
#activateChannel
#activateStream
#activateEvent
#activateAll
#deactivateChannel
#deactivateStream
#deactivateEvent
#deactivateAll
##Setup
####Initialize the Agent API Class
Parameter | Name | Type | Description |
---|---|---|---|
1st | Reading Interval | Integer | Time in seconds between readings |
2nd | Reporting Interval | Integer | Time in seconds between internet connection/data sends |
3rd | Bullwinkle | Meta | Instance of the Bullwinkle class |
######Code Example:
readingInterval <- 15;
reportingInterval <- 60;
bullwinkle <- Bullwinkle();
api <- AgentSideSensorAPI(readingInterval, reportingInterval, bullwinkle);
Configuring a channel is where you will define all the streams and events available to a channel. The information entered will need to match your device side code. The "command name" is a unique string and must match the key in the device's Agent/Device Communication table (in this example the table is called sensorSubscriptionFunctionsByCommand). Event Parameters should be a table and must match the code you have written on the device.
Parameter | Name | Type | Description |
---|---|---|---|
1st | Sensor Type | String | Description of sensor data type |
2nd (optional) | Streams | Array | Contains stream "command names" |
3rd (optional) | Events | Table | Keys are event "command names" : Values are the parameters for event |
######Code Example:
api.addSensor("temp", ["nora_tempReadings"], { "nora_tempThermostat" : {"low": 29, "high": 30} });
Use this function to handle the data coming from the device. This callback should parse the data, and pass it on to your database or webhook.
Parameter | Name | Type | Description |
---|---|---|---|
1st | callback | Function | A function that will run everytime the agent receives data from the device. |
######Code Example:
function printData(data) { server.log(data) };
api.setBroadcastCallback(printData);
returns
a json string containing the current settings.
######Code Example:
api.getChannels();
######Result
{ "agentID": "Yke-5UZ58oI1",
"readingInterval": 15,
"reportingInterval": 60,
"channels": [ { "channelID": 0,
"type": "temperature",
"active": true,
"activeStreams": [ "nora_tempReadings" ],
"activeEvents": { "nora_tempThermostat": { "high": 30, "low": 29 } },
"availableStreams": [ "nora_tempReadings" ],
"availableEvents": { "nora_tempThermostat": { "high": 30, "low": 29 } },
},
{ "channelID": 1,
"type": "magnitometer",
"active": false,
"activeStreams": [ ],
"activeEvents": { },
"availableStreams": [ "nora_magReadings" ],
"availableEvents": { }
} ]
}
##Updating
NOTE: This change will not go into effect until the device connects to the agent.
Parameter | Name | Type | Description |
---|---|---|---|
1st | New Reading Interval | Integer | The time in seconds between readings |
######Code Example:
api.updateReadingInterval(10);
NOTE: This change will not go into effect until the device connects to the agent.
Parameter | Name | Type | Description |
---|---|---|---|
1st | New Reporting Interval | Integer | The time in seconds between internet connection/data sends |
######Code Example:
api.updateReportingInterval(30);
Parameter | Name | Type | Description |
---|---|---|---|
1st | Channel ID | Integer | The ID of the channel. The ID is in the table returned by calling #getChannels |
2nd | Event | String | The command name for the event |
3rd | New Event Params | Table | New parameters for the event |
######Code Example:
api.updateEventParams(0, "nora_tempThermostat", {"low": 28})
##Activation
Parameter | Name | Type | Description |
---|---|---|---|
1st (optional) | Channel IDs | Array | If no parameter is passed in, will subscribe to all streams on all channels. If array given, will subscribe to all streams for each channel in the array. |
######Code Example:
api.activateStreams();
api.activateStreams([0]);
Parameter | Name | Type | Description |
---|---|---|---|
1st | Channel ID | Integer | The ID of the channel. The ID is in the table returned by calling #getChannels . |
2nd | Stream | String | The command name for the stream. |
######Code Example:
api.activateAStream(0, "nora_tempReadings");
Parameter | Name | Type | Description |
---|---|---|---|
1st | Channel ID | Ingeter | The ID of the channel. The ID is in the table returned by calling #getChannels . |
2nd | Event | The command name for the event. |
######Code Example:
api.activateEvent(0, "nora_tempThermostat");
Will activate all events and streams for all channels.
######Code Example:
api.activateAll();
Parameter | Name | Type | Description |
---|---|---|---|
1st (optional) | Channel IDs | Array | If no parameter is passed in, will unsubscribe from all streams on all channels. If array given, will unsubscribe from all streams for each channel in the array. |
######Code Example:
api.deactivateStreams();
api.deactivateStreams([0]);
Parameter | Name | Type | Description |
---|---|---|---|
1st | Channel ID | Integer | The ID of the channel. The ID is in the table returned by calling #getChannels . |
2nd | Stream | String | The command name for the stream. |
######Code Example:
api.deactivateAStream(0, "nora_tempReadings");
Parameter | Name | Type | Description |
---|---|---|---|
1st | Channel ID | Integer | The ID of the channel. The ID is in the table returned by calling #getChannels . |
2nd | Event | String | The command name for the event. |
######Code Example:
api.deactivateEvent(0, "nora_tempThermostat");
Will deactivate all events and streams for all channels.
######Code Example:
api.deactivateAll();
#Device Side API
##Setup
Setup will vary based on the sensors used. I'm going to include code examples for the setup of the temperature sensor on the nora.
###Basic configuration for Nora Sensor:
####Configure pins and i2c
######Code Example:
const TMP1x2_ADDR = 0x92;
hardware.pinA.configure(DIGITAL_IN);
hardware.pinB.configure(DIGITAL_IN);
hardware.pinC.configure(DIGITAL_IN);
hardware.pinD.configure(DIGITAL_IN);
hardware.pinE.configure(DIGITAL_IN);
hardware.pin1.configure(DIGITAL_IN_WAKEUP);
i2c <- hardware.i2c89;
i2c.configure(CLOCK_SPEED_400_KHZ);
####Setup Sensor Variables We only want to initialize the sensors we are acutally subscribed to. Note - on nora we needed to initialize the magnitometer for interupts to work.
######Code Example:
noraTemp <- null;
mag <- LIS3MDL(i2c);
####Custom functions for sensors I've written some functions so the sensors are initialized when I want and have the parameters the agent has programmed. Any behavior you want to define that is not in the class can customized in this step.
######Code Example:
//initialize nora temp sensor
function initializeTemp() {
if (!noraTemp) { noraTemp <- TMP1x2(i2c, TMP1x2_ADDR, hardware.pinE); }
}
//set event parameters
function setUpTempThermostat(params) {
initializeTemp();
if("low" in params) {noraTemp.setLowThreshold(params.low)};
if("high" in params) {noraTemp.setHighThreshold(params.high)};
}
//turn off event. currently this is not working, ideally the code here would stop event from firing.
function resetEvents() {
if(noraTemp) { noraTemp.reset(); }
}
###Agent/Device Communication table This table contains the functions that will be run when a user subscribes to a stream or event. Keys are the command name that matches those used when configuring channels. Values are the function to be run when a user subscribes to that stream or event. For streams this function should initialize the sensor and return the data you would like to stream. For an event this function should initialize and set the parameters for the event. NOTE: Events will need additional set up to configure what happens when an event is triggered. This setup happens after we initialize the DeviceAPI class. ######Code Example:
sensorSubscriptionFunctionsByCommand <- {
"nora_tempReadings" : function() { initializeTemp(); return noraTemp.readTempC(); },
"nora_tempThermostat" : function(params) { setUpTempThermostat(params); },
}
###Initialize Device API class
Parameter | Name | Type | Description |
---|---|---|---|
1st | Agent/Device Communication table | Table | Keys command name : values subscription function |
2nd | Bullwinkle | Meta | Instance of the Bullwinkle class |
3rd (optional) | Event Off function | Function | Function that deactivates all events |
######Code Example:
bullwinkle <- Bullwinkle();
api <- deviceSideSensorAPI(sensorSubscriptionFunctionsByCommand, bullwinkle, resetEvents);
For each event we need some additional set up. #setUpEvent
takes in the additional info for each event.
Parameter | Name | Type | Description |
---|---|---|---|
1st | Event | String | Command name for the event |
2nd | Pin | String | The interrupt pin for the event |
3rd | Polarity | Integer | Polarity of the interrupt pin when event is triggered |
4th | Event Triggered function | Function | Function that runs when event is triggered. Function should return data or message for the end user |
######Code Example:
api.setUpEvent("nora_tempThermostat", "pinE", 0, function(){ initializeTemp(); return noraTemp.readTempC(); });