// mysensors.things
// https://github.com/tobof/openhab2-addons/wiki/Configuration
// "MyS-Node" // "mygateway1-out" data received from your gateway
// "MyS-2Node" // "mygateway1-in" send data to your sensors
// MY_MQTT_PUBLISH_TOPIC_PREFIX / FROM-NODE-ID / SENSOR-ID / CMD-TYPE / ACK-FLAG / SUB-TYPE
Thing mqtt:topic:MySBabylon_LED_1_th "MQTT-MyS Thing: Babylon LED" (mqtt:broker:MqttOpenHAB75) @ "MQTT OpenHAB"
{
Channels:
Type number : uptime "LED Stripe uptime" [ stateTopic="MyS-Node/5/255/3/0/22" ]
Type switch : lamp "LED Stripe power" [ stateTopic="MyS-Node/5/1/1/0/2", commandTopic="MyS-2Node/5/1/2/0/2" ]
Type number : dim "LED Stripe dim" [ stateTopic="MyS-Node/5/1/1/0/3", commandTopic="MyS-2Node/5/1/2/0/3" ]
Type number : fade "LED Stripe fade" [ stateTopic="MyS-Node/5/1/1/0/24", commandTopic="MyS-2Node/5/1/2/0/24" ]
}
Thing mqtt:topic:MySBabylon_DHT22_th "MQTT-OneWire Thing: Gateway" (mqtt:broker:MqttOpenHAB75) @ "MQTT OpenHAB"
{
Channels:
Type number : uptime "DHT22 uptime" [ stateTopic="MyS-Node/1/255/3/0/22" ]
Type number : hummidity "DHT22 hummidity" [ stateTopic="MyS-Node/1/3/1/0/1" ]
Type number : temperature "DHT22 temperature" [ stateTopic="MyS-Node/1/4/1/0/0" ]
Type string : info "DHT22 info" [ stateTopic="MyS-Node/1/0/1/0/47" ]
}
Thing mqtt:topic:OneWireGW_th "MQTT-OneWire Thing: Gateway" (mqtt:broker:MqttOpenHAB75) @ "MQTT OpenHAB"
{
Channels:
Type number : uptime "Gateway uptime" [ stateTopic="MyS-Node/0/255/3/0/22" ]
}
mysensors.items
// mysensors.items
// itemname ["labeltext"] [<iconname>] [(group1, group2, ...)] [{bindingconfig}]
// https://github.com/tobof/openhab2-addons/wiki/Configuration
/************************************************** Gruppen ********************************************/
Group gMYSensors // restore after power down
/************************************************** Items ********************************************/
// MY_MQTT_PUBLISH_TOPIC_PREFIX / FROM-NODE-ID/SENSOR-ID/CMD-TYPE/ACK-FLAG/SUB-TYPE
// "MyS-Node" // "mygateway1-out" data received from your gateway
// "MyS-2Node" // "mygateway1-in" send data to your sensors
Number Gateway_uptime "Gateway uptime: [%d]" <time> (gMYSensors) { channel="mqtt:topic:OneWireGW_th:uptime" }
Number MyS_DHT22_uptime "DHT22 uptime: [%d]" <time> (gMYSensors) { channel="mqtt:topic:MySBabylon_DHT22_th:uptime" }
Number MyS_DHT22_humidity "DHT22 humidity: [%.0f %%]" <humidity> (gMYSensors) { channel="mqtt:topic:MySBabylon_DHT22_th:hummidity" }
Number MyS_DHT22_temperature "DHT22 temperature: [%.1f °C] " <temperature> (gMYSensors) { channel="mqtt:topic:MySBabylon_DHT22_th:temperature" }
String MyS_DHT22_info "DHT22 info:" <error> (gMYSensors) { channel="mqtt:topic:MySBabylon_DHT22_th:info" }
Number Babylon_LED_uptime "Babylon LED uptime: [%d]" <time> (gMYSensors) { channel="mqtt:topic:MySBabylon_LED_1_th:uptime" }
Switch Babylon_LED_SWITCH "Babylon LED Switch" (gMYSensors) { channel="mqtt:topic:MySBabylon_LED_1_th:lamp" }
Number Babylon_LED_DIM "Babylon LED DIM" <settings> (gMYSensors) { channel="mqtt:topic:MySBabylon_LED_1_th:dim" }
Number Babylon_LED_FADE "Babylon LED FADE" <settings> (gMYSensors) { channel="mqtt:topic:MySBabylon_LED_1_th:fade" }
mysensors.sitemap
// mysensors.sitemap
// list of icons: https://github.com/eclipse/smarthome/tree/master/extensions/ui/iconset/org.eclipse.smarthome.ui.iconset.classic/icons
sitemap mysensors label="My Sensors" {
Frame label="MQTT Gateway" {
// Text item=Ardu1_433_Uptime label="433 uptime"
Text item=Gateway_uptime
} // end of Frame
Frame label="MQTT DHT22" {
Text item=MyS_DHT22_uptime
Text item=MyS_DHT22_humidity
Text item=MyS_DHT22_temperature
Text item=MyS_DHT22_info
} // end of Frame
Frame label="MQTT LED" {
Text item=Babylon_LED_uptime
Switch item=Babylon_LED_SWITCH
Slider item=Babylon_LED_DIM
Slider item=Babylon_LED_FADE
Colorpicker item=LEDStrip_1_Color
} // end of Frame
} // end of sitemap
/**
* MySensors Example
* https://www.mysensors.org/download/sensor_api_20
*/
// Enable debug prints to serial monitor
#define MY_DEBUG
#define MY_RADIO_NRF24 // define radio type to be used
#define MY_RF24_CHANNEL 76 // 76
#define MY_RF24_PA_LEVEL RF24_PA_LOW //RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
#define MY_RF24_DATARATE RF24_250KBPS
// #define MY_REPEATER_FEATURE // turn a node into a repeater - but Node must be awake all the time, no sleep
#define MY_NODE_ID 1 // Node id defaults to AUTO (tries to fetch id from controller).
// Specify a number (1-254) if you want to manually set your Node ID
#define SKETCH_NAME "DHT22 Babylon" // Change to a fancy name you like
#define SKETCH_VERSION "1.1"
#define CHILD_ID_TXT 0
#define CHILD_ID_HUM 3
#define CHILD_ID_TEMP 4
#include "Arduino.h"
#include <SPI.h> // DHT 22
#include <DHT.h> // DHT 22
#include <MySensors.h>
// // e.g. V_TEMP, V_HUM, V_LIGHT, V_DIMMER, V_PRESSURE, V_FORECAST, V_RAIN, ...
float lastTemp;
float lastHum;
uint8_t nNoUpdatesTemp;
uint8_t nNoUpdatesHum;
bool metric = true;
MyMessage msgHum (CHILD_ID_HUM, V_HUM);
MyMessage msgTemp (CHILD_ID_TEMP, V_TEMP);
MyMessage msgText (CHILD_ID_TXT, V_TEXT); // message for Sending Text to Controller
DHT dht;
#define LED_PIN1 7 // Arduino Digital I/O pin number for relay
#define DHT_DATA_PIN 2 // DHT 22
#define SENSOR_TEMP_OFFSET 0 // DHT22
// Sleep time between sensor updates (in milliseconds)
// Must be >1000ms for DHT22 and >2000ms for DHT11
static const uint64_t UPDATE_INTERVAL = 10000; // 60000;
// Force sending an update of the temperature after n sensor reads, so a controller showing the
// timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
// the value didn't change since;
// i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
static const uint8_t FORCE_UPDATE_N_READS = 10;
#define HEARTBEAT_TIME 10000
uint32_t last_heartbeat_time;
// ------------------------------------------------------------------------------------------------------
void before() //
{
pinMode (LED_PIN1, OUTPUT);
} // end of function
// ------------------------------------------------------------------------------------------------------
void presentation() // sensor must first present itself to the controller
{
sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
// Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_HUM, S_HUM);
present(CHILD_ID_TEMP, S_TEMP);
metric = getControllerConfig().isMetric;
} // end of function
// ------------------------------------------------------------------------------------------------------
void my_blink() {
digitalWrite(LED_PIN1, HIGH);
delay(200);
digitalWrite(LED_PIN1, LOW);
delay(200);
Serial.println("blink..");
} // end of function
// ------------------------------------------------------------------------------------------------------
void setup() {
my_blink();
my_blink();
dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor
if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
}
// Sleep for the time of the minimum sampling period to give the sensor time to power up
// (otherwise, timeout errors might occure for the first reading)
sleep(dht.getMinimumSamplingPeriod());
last_heartbeat_time = millis();
} // end of function
// ------------------------------------------------------------------------------------------------------
void timer_heartbeat()
{
if ((millis() - last_heartbeat_time) > HEARTBEAT_TIME) {
// If it exceeds the heartbeat time then send a heartbeat
sendHeartbeat();
last_heartbeat_time = millis();
#ifdef MY_DEBUG
Serial.println("-----> Sent heartbeat: Node " + (String)MY_NODE_ID + " is alive");
#endif
}
} // end of function
// ------------------------------------------------------------------------------------------------------
void read_DHT22_temperature()
{
// Force reading sensor, so it works also after sleep()
// dht.readSensor(true);
// Get temperature from DHT library
float temperature = dht.getTemperature();
if (isnan(temperature)) {
Serial.println("Failed reading temperature from DHT!");
send(msgText.set("ERROR DHT22")); // Send tripped value to gw
} else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
// Only send temperature if it changed since the last measurement or if we didn't send an update for n times
lastTemp = temperature;
// apply the offset before converting to something different than Celsius degrees
temperature += SENSOR_TEMP_OFFSET;
if (!metric) {
temperature = dht.toFahrenheit(temperature);
}
// Reset no updates counter
nNoUpdatesTemp = 0;
send(msgText.set("ok"));
send(msgTemp.set(temperature, 1));
#ifdef MY_DEBUG
Serial.print("CHILD ");
Serial.print(CHILD_ID_TEMP);
Serial.print("/ DHT22 Temp> ");
Serial.println(temperature);
#endif
} else {
// Increase no update counter if the temperature stayed the same
nNoUpdatesTemp++;
}
}// end of function
// ------------------------------------------------------------------------------------------------------
void read_DHT22_hummidity()
{
// Get humidity from DHT library
float humidity = dht.getHumidity();
if (isnan(humidity)) {
Serial.println("Failed reading humidity from DHT");
send(msgText.set("ERROR DHT22")); // Send tripped value to gw
} else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
// Only send humidity if it changed since the last measurement or if we didn't send an update for n times
lastHum = humidity;
// Reset no updates counter
nNoUpdatesHum = 0;
send(msgText.set("ok"));
send(msgHum.set(humidity, 1));
#ifdef MY_DEBUG
Serial.print("CHILD ");
Serial.print(CHILD_ID_HUM);
Serial.print(" / DHT22 Hum> ");
Serial.println(humidity);
#endif
} else {
// Increase no update counter if the humidity stayed the same
nNoUpdatesHum++;
}
}// end of function
// ------------------------------------------------------------------------------------------------------
void loop()
{
timer_heartbeat();
read_DHT22_temperature();
my_blink(); my_blink();
sleep(200);
read_DHT22_hummidity();
sleep(UPDATE_INTERVAL); // Sleep for a while to save energy
} // end of function
I also got in contact with the MySensor developers and they seem to be interested in mqtt conventions like Homie, so that auto discovery can maybe done in the future.