One of the e-mails I've been pending to work on for (gasp!) a year now is from Karanbir; we discussed a simple, cloudless, and inexpensive solution to driving a few lights for monitoring purposes, and I think I've found a solution which fits the bill, even if this can probably be done less expensively.

The Particle Photon I wrote about recently, can be hooked up to a strip of LEDs. I chose to use an Adafruit Dotstar digital LED strip which has 30 RGB LEDs on it.

monitoring strip

Instead of using the Particle cloud functions, I decided to drive the LEDs using MQTT, which makes things easy in my environment. The code on the Photon sets up the dotstar strip and expects an MQTT payload with the LED number (0 through 29) and the state (0 == OK, etc.).

/*
 * warner.ino (C) December 2015 by Jan-Piet Mens <jpmens@gmail.com>
 * Subscribe to an MQTT topic and read a string with two integers from
 * each message. The first integer specifies an LED to set (0 -- NUMPIXELS)
 * on a Dotstar strip, whereas the second integer is a Nagios-type 
 * number from Unknown (-1) through ERROR (2).
 *
 * To set LED 7 to OK:      mosquitto_pub -t led -m "7 0"
 * To set LED 9 to WARNING: mosquitto_pub -t led -m "9 1"
 *
 *
 * The Dotstar is Adafruit's https://www.adafruit.com/products/2238
 *
 *                            +-----+
 *                 +----------| USB |----------+
 *                 |          +-----+       *  |
 *                 | [ ] VIN           3V3 [ ] |
 *                 | [ ] GND           RST [ ] |
 *                 | [ ] TX           VBAT [ ] |
 *                 | [ ] RX  [S]   [R] GND [ ] |
 *                 | [ ] WKP            D7 [ ] |
 *                 | [ ] DAC +-------+  D6 [ ] |
 * Dotstar CLCK -->| [*] A5  |   *   |  D5 [ ] |
 *                 | [ ] A4  |Photon |  D4 [ ] |
 * Dotstar DATA -->| [*] A3  |       |  D3 [ ] |
 *                 | [ ] A2  +-------+  D2 [ ] |
 *                 | [ ] A1             D1 [ ] |
 *                 | [ ] A0             D0 [ ] |
 *                 |                           |
 *                  \    []         [______]  /
 *                   \_______________________/
 *
 *
 */
 
#include "MQTT/MQTT.h"
#include "dotstar/dotstar.h"
#include <stdlib.h>


#define NUMPIXELS   30 // Number of LEDs in strip
#define SUBTOPIC    "led"
#define PUBTOPIC    "led/status"

//-------------------------------------------------------------------
// Here's how to control the LEDs from any two pins (Software SPI):
//-------------------------------------------------------------------
// #define DATAPIN   D4
// #define CLOCKPIN  D5
// Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, DATAPIN, CLOCKPIN /* JPM */, DOTSTAR_GBR);

// Hardware SPI
Adafruit_DotStar strip = Adafruit_DotStar(NUMPIXELS, A5, A3); 

// char *host = "mqtt.example.org"
byte host[] = { 192, 168, 1, 130 };
MQTT client(host, 1888, callback);

static int colors[] = { 0x000000,   // Off    Unknown (-1)
                        0x00000B,   // Green  OK (0)
                        0x040004,   // Yello  WARNING (1)
                        0x0B0000 }; // Red    ERROR (2)

void ledon(int led, int status) {
    char payload[128];
    
    if (status >= -1 && status <= 2) {
        if (led >= 0 && led <= NUMPIXELS) {
            strip.setPixelColor(led, colors[status + 1]);
            strip.show();
            
            snprintf(payload, sizeof(payload), "LED %d set to %d at %ld", led, status, Time.now());
            client.publish(PUBTOPIC, payload);
        }
    }
}

void callback(char* topic, byte* payload, unsigned int length) {
    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = 0;
    int led, status;
    
    if (sscanf(p, "%d %d", &led, &status) == 2) {
        ledon(led, status);
    } else {
        client.publish(PUBTOPIC, "can't parse two integers from payload");
    }
}

void mqtt_connect() {

    client.connect("photon-warner", PUBTOPIC, MQTT::QOS2, 0, "Oops: warner going down!");

    if (client.isConnected()) {
        client.publish(PUBTOPIC, "online");
        client.subscribe(SUBTOPIC);
    }
}

void setup() {
    strip.begin(); // Initialize pins for output
    strip.show();  // Turn all LEDs off ASAP
  
    mqtt_connect();
}

void loop() {
    if (client.isConnected()) {
        client.loop();
    } else {
        client.disconnect();
        mqtt_connect();
    }
}

For EUR 40.00 and a bit of LEGO which my Assistant In Charge Of LEGO Enclosures provided, I have a blinkenlights thing which shows me the state of 30 services. Add a few labels to the LEDs, and Bob's your uncle.

Flattr this
monitoring, blinkenlights, and photon :: 02 Jan 2016 :: e-mail

Comments

blog comments powered by Disqus