mysensors-controller

1.2.0 • Public • Published

mysensors-controller

A partial implementation of the MySensors serial protocol as a node.js module. Built against version 1.5 of the MySensors Serial API, and supports both Serial and Ethernet gateways.

Installation

npm install mysensors-controller

Usage

var mysensors = require("mysensors-controller");
var controller = mysensors.usingSerialGateway("/dev/serial.path"); // or "COMx" for Windows mates
// or
var controller = mysensors.usingEthernetGateway("host or ip", port); // Should also work with the ESP8266 gateway

.nodes

A JS object containing the nodes and sensors in the network. This object is updated with presentation and sensor data as available from the network.

> controller.nodes
[
  {
    "id": 1,
    "sensors": [
      {
        "id": 0,
        "value": 47,
        "type": 23,
        "updateTime": 1456390408709
      }
    ],
    "protocol": "1.5.4",
    "sketchName": "Light Sensor",
    "sketchVersion": "1.0"
  }
]

The object above reflects that the network has has one node (ID: 1), which has one one sensor (ID: 0), which is of type 23 (controller.types.lightLevel). Other keys should be obvious.

This object should be considered as the source of truth, and so is saved to disk automatically for future internal use. See docs about persistence below. This object is updated whenever any of the following events fire:

Events

controller.on(eventName, function(...) {
  // ...
});
eventName Notes
newNode Emitted when a new node has been added to the system. Callback function receives the newly added node. Note that the new node's data might not be fully populated yet. The update event should give more details. This event is only fired during presentation, if the node wasn't previously known. It isn't fired if it isn't a case of presentation.
update Emitted when a node has been updated. Callback function receives the updated node, and the property that was updated (can be the strings protocol, batteryLevel, sketchName, sketchVersion, or sensor).
sensorUpdate Emitted when new sensor data has become available. Callback function receives the affected node and sensor objects. This is where the fun stuff happens, isn't it?
message Emitted when an incoming message has been received. Callback function receives a parsed message object (keys are sender, sensor, command, ack, type and payload). Ideally, the previous events should help you enough, so this event shouldn't be too useful, except maybe for logging. The .nodes object isn't updated before firing this event.

Except for the message event, the .nodes object is always updated before any of the events are fired, so .nodes always reflects the latest known state. .sendMessage(message)

Sends a message to the network. Example:

controller.sendMessage({
  destination: 3,
  sensor: 0,
  command: controller.commands.set,
  type: controller.types.dimmer,
  payload: 50
});

The code above tells sensor 0 connected to node 3 to set it's dimmer level to 50%. Set sensor to 255 if you don't want to target the command to the node, and not a specific sensor.

.debug

Set this to true or false for verbose logging of every message across the network to stdout. Default: false.

Stuff that's already handled

This library is a thin layer on top of the MySensors API, and all changes are exposed as events and as updates to the .nodes object. That said, the following things are handled automatically for you:

  • Setting the sensor config to M for metric. Because I couldn't figure out how to expose this cleanly, so I had to pick one, and metric is clearly the better system.
  • Sending the current time to nodes, if requested.
  • Assigning IDs to new nodes, if they don't have hardcoded IDs already, during inclusion. This isn't foolproof. If any node with id=255 has been discovered on the network, node assignment subsequently fails (somewhat silently - there's a debug message printed to stdout if .debug = true). There's no way to know which IDs have already been used up in the network without complete historical data, so I'm not sure this is fixable easily.
  • Broadcasting the current time every 5 minutes. I've just copied the behaviour from the official NodeJsController.js. I'm not sure if it serves any purpose, since there's no apparent way to retreive the time on the node without making a request again. Also, nodes at the edges of the network might be sleeping anyway when the time is broadcast.

Enums

.commands and .types refer the to available options for, well, commands and types. So, controller.commands.set is used for C_SET commands, and controller.types.temp refers to the V_TEMP type, for example. You'll need to refer to the MySensors Serial API docs for details about the available options. While you can use the types in the docs (for eg. controller.types.V_TEMP is perfectly valid), there's the more JS friendly controller.types.temp available as well. For the sake of looking good in JS-land, the prefix and underscores are removed, and is converted to camelCase.

Persistence

Since presentation data is only sent when the sensor node is reset or power-cycled, it becomes necessary to store presentation data for when your node.js app restarts. Otherwise you'd need to power-cycle all sensor nodes after you start the node app. This module stores the presentation data in a nodes.json file on the file system, and uses it at startup if available to populate the collection.nodes object above. This way, if presentation data was captured in the past, it will still be available even if your node.js app restarts. All of this is managed automatically, but you should be aware of the FS operations here. All data is flushed to disk every 5 seconds, if there was a change.

It appears that v2.0 of the protocol has a way to request for presentation data. Whenever that lands, on-disk persistence can be removed completely, and all presentation details can be figured out via the protocol itself.

License

MIT

Readme

Keywords

Package Sidebar

Install

npm i mysensors-controller

Weekly Downloads

3

Version

1.2.0

License

ISC

Last publish

Collaborators

  • rakeshpai