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 Screen Shot 2015-03-24 at 12.12.04 PM.png

    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.


  • Admin

    No much MySensors here @kunall


  • Hero Member

    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. šŸ™‚


 

369
Online

8.2k
Users

9.0k
Topics

95.9k
Posts