Need help with Turning a LED On/Off with OpenHab and MQTT.
-
How to Turn On/Off a LED light on Arduino using OpenHAB and MQTT?
I'm fairly new to this and can not seem to understand how to send a command from MQTT to Arduino and make it to Turn ON and OFF a LED.
I'm able to read sensor data on OpenHab via MQTT. Following is my .items file:
Number Node01Temperature "Temperature [%.1f F]" <temperature> (GF_Living) { mqtt="<[mymosquitto:home/temperature:state:default]" } Number Node01Humidity "Humidity [%.1f %%]" <bath> (GF_Living) { mqtt="<[mymosquitto:home/humidity:state:default]" } Number Node01Light "Light [%d %%]" <sun> (GF_Living) { mqtt="<[mymosquitto:home/light:state:default]" } Number Node01Motion "Motion [MAP(motion.map):%s]" <shield> (GF_Living) { mqtt="<[mymosquitto:home/motion:state:default]" } Number Node01Door "Door [MAP(door.map):%s]" <lock> { mqtt="<[mymosquitto:home/door:state:default]" } Switch Node01LED "LED [%s]" <switch> (GF_Living) { mqtt=โ>[mymosquitto:home/led:command:ON:1],>[mymosquitto:home/led:command:OFF:0โ]
The problem is, I'm not able to figure out how to receive this On / Off command on an Arduino sensor node?
Here is my Arduino sensor node sketch: I'm using RF24 library from Tmrh20.
#include <RF24Network.h> #include <RF24.h> #include <SPI.h> #include <DHT.h> // The DHT data line is connected to pin 2 on the Arduino #define DHTPIN 2 // Leave as is if you're using the DHT22. Change if not. //#define DHTTYPE DHT11 // DHT 11 #define DHTTYPE DHT22 // DHT 22 (AM2302) //#define DHTTYPE DHT21 // DHT 21 (AM2301) DHT dht(DHTPIN, DHTTYPE); // PIR variables byte pirPin = 9; int pirCalibrationTime = 30; // Photocell variable byte photocellPin = A3; // Magnetic Door Sensor variable byte switchPin = 12; // Radio with CE & CSN connected to pins 7 & 8 RF24 radio(7, 8); RF24Network network(radio); // Constants that identify this node and the node to send data to const uint16_t this_node = 1; const uint16_t parent_node = 0; // Time between packets (in ms) const unsigned long interval = 1000; // every sec // Structure of our message struct message_1 { float temperature; float humidity; byte light; bool motion; bool dooropen; }; message_1 message; // The network header initialized for this node RF24NetworkHeader header(parent_node); void setup(void) { // Set up the Serial Monitor Serial.begin(9600); // Initialize all radio related modules SPI.begin(); radio.begin(); delay(5); network.begin(90, this_node); // Initialize the DHT library dht.begin(); // Activate the internal Pull-Up resistor for the door sensor pinMode(switchPin, INPUT_PULLUP); // Sensor Type 1 header.type = '1'; // Calibrate PIR pinMode(pirPin, INPUT); digitalWrite(pirPin, LOW); Serial.print("Calibrating PIR "); for(int i = 0; i < pirCalibrationTime; i++) { Serial.print("."); delay(1000); } Serial.println(" done"); Serial.println("PIR ACTIVE"); delay(50); } void loop() { // Update network data network.update(); // Read humidity (percent) float h = dht.readHumidity(); // Read temperature as Celsius float t = dht.readTemperature(); // Read temperature as Fahrenheit float f = dht.readTemperature(true); // Read photocell int p = analogRead(photocellPin); // Testing revealed this value never goes below 50 or above 1000, // so we're constraining it to that range and then mapping that range // to 0-100 so it's like a percentage p = constrain(p, 50, 1000); p = map(p, 50, 1000, 0, 100); // Read door sensor: HIGH means door is open (the magnet is far enough from the switch) bool d = (digitalRead(switchPin) == HIGH); // Read motion: HIGH means motion is detected bool m = (digitalRead(pirPin) == HIGH); // Only send values if any of them are different enough from the last time we sent: // 0.5 degree temp difference, 1% humdity or light difference, or different motion state if (abs(f - message.temperature) > 0.5 || abs(h - message.humidity) > 1.0 || abs(p - message.light) > 1.0 || m != message.motion || d != message.dooropen) { // Construct the message we'll send message = (message_1){ f, h, p, m, d }; // Writing the message to the network means sending it if (network.write(header, &message, sizeof(message))) { Serial.print("Message sent\n"); } else { Serial.print("Could not send message\n"); } } // Wait a bit before we start over again delay(interval); }
I'm using Raspberry Pi 2 as my Gateway: Here is the sketch for RPi Gateway
#include <RF24/RF24.h> #include <RF24Network/RF24Network.h> #include <iostream> #include <ctime> #include <stdio.h> #include <stdlib.h> #include <time.h> /** * g++ -L/usr/lib main.cc -I/usr/include -o main -lrrd **/ // CE Pin, CSN Pin, SPI Speed RF24 radio(RPI_BPLUS_GPIO_J8_15,RPI_BPLUS_GPIO_J8_24, BCM2835_SPI_SPEED_8MHZ); RF24Network network(radio); // Constants that identifies this node const uint16_t pi_node = 0; // Time between checking for packets (in ms) const unsigned long interval = 2000; // Structure of our message struct message_t { float temperature; float humidity; unsigned char light; bool motion; bool dooropen; }; int main(int argc, char** argv) { // Initialize all radio related modules radio.begin(); delay(5); network.begin(90, pi_node); // Print some radio details (for debug purposes) radio.printDetails(); printf("Ready to receive...\n"); // Now do this forever (until cancelled by user) while(1) { // Get the latest network info network.update(); printf(".\n"); // Enter this loop if there is data available to be read, // and continue it as long as there is more data to read while ( network.available() ) { RF24NetworkHeader header; message_t message; // Have a peek at the data to see the header type network.peek(header); // We can only handle type 1 sensor nodes for now if (header.type == '1') { // Read the message network.read(header, &message, sizeof(message)); // Print it out in case someone's watching printf("Data received from node %i: Temp = %f, Hum = %f, Light = %i, Motion = %i, Door Open = %i \n", header.from_node, message.temperature, message.humidity, message.light, message.motion ? 1 : 0, message.dooropen ? 1 : 0); // "sprintf" is a way to format a text string and then write he result to char array // (an array of characters is virtually the same as a string) // The string we're making is a command to push the temperature data on a mosquitto channel // And "system" is how you execute a shell command from a C program char buffer [50]; sprintf (buffer, "mosquitto_pub -t home/temperature -m \"%f\"", message.temperature); system(buffer); sprintf (buffer, "mosquitto_pub -t home/humidity -m \"%f\"", message.humidity); system(buffer); sprintf (buffer, "mosquitto_pub -t home/light -m \"%i\"", message.light); system(buffer); sprintf (buffer, "mosquitto_pub -t home/motion -m \"%i\"", message.motion ? 1 : 0); system(buffer); sprintf (buffer, "mosquitto_pub -t home/door -m \"%i\"", message.dooropen ? 1 : 0); system(buffer); } else { // This is not a type we recognize network.read(header, &message, sizeof(message)); printf("Unknown message received from node %i\n", header.from_node); } } // Wait a bit before we start over again delay(2000); } // last thing we do before we end things return 0; }
This is how my Openhab looks like
Please ignore temperature reading, It should be in Celsius. I will fix it later.
I really need help to implement the OpenHab On/OFF Led switch --> to MQTT mosquito --> Arduino.
I would really appreciate your help.
Thank You.
-
No much MySensors here @kunall
-
I don't see code, that processes incoming messages.
You will need something like "incomingMessage()":
http://www.mysensors.org/build/relay
-
I just finished something similar. I used a Ws2812B LED so it can change colors.
Arduino Sketch Code Bender Sketch
And Openhab items
Switch Light "On/OFF" (gKR) {mqtt=">[mysensors:/MyMQTT/20/2/V_LIGHT:command:ON:1],>[mysensors:/MyMQTT/20/2/V_LIGHT:command:OFF:0]"} String KidLight (All) {mqtt=">[mysensors:/MyMQTT/20/1/V_VAR1:command:*:default"} Color RGBKidLight "Kid Light" (All,gKR)
and openhab.rule
import org.openhab.core.library.types.* import org.openhab.model.script.actions.* rule "Set RGB value RGBKidLight" when Item RGBKidLight changed then val hsbValue = RGBKidLight.state as HSBType val brightness = hsbValue.brightness.intValue val redValue = ((((hsbValue.red.intValue * 255) / 100) * brightness) / 100).toString val greenValue = ((((hsbValue.green.intValue * 255) / 100) * brightness) / 100).toString val blueValue = ((((hsbValue.blue.intValue *255) / 100) * brightness) / 100).toString val color = redValue + "," + greenValue + "," + blueValue sendCommand( KidLight, color ) end
-
Hey there @Chaotic ! This is Fay from codebender.cc Thank you for using codebender! I just wanted to let you know that one of the sketches you are using in this comment has been deleted and so it is not available for users to view it. Let me know if you have any question.