Receive queued mensajes after sleep



  • Hi forum,

    I´m trying to build a plant watering system with arduino and Openhab as a controller. I have read and learned a lot on the forum, but now I am running into some issues I can't resolve by myself.

    The openhab installation is located on a Raspberry Pi + NRF24L01 radio, along with the Mysensor MQTT Gateway. I´m also using the embedded MQTT broker of Openhab. I already build the first version with an Arduino UNO connected to a relay, an Ultrasonic sensor, and a nrf24l01 radio.

    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    
    // Enable repeater functionality for this node
    #define MY_REPEATER_FEATURE
    
    #include <MySensors.h>
    //#include <Ultrasonic.h>
    
    // Enable and config Relay
    #define RELAY_PIN 4  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    // Enable and config ultrasonic
    #define CHILD_ID_DEP 0
    Ultrasonic ultrasonic(8);
    float distance;
    boolean metric = true;
    MyMessage msgDistance(CHILD_ID_DEP, V_LEVEL);
    
    void before()
    {
    //Enable Relay  
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
        }
    }
    
    void setup()
    {
    
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Bomba ROBOTDYN UNO", "3.1");
    
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_BINARY);
        }
         // Sensor ultrasonido
    //         present(CHILD_ID_DEP, V_LEVEL);
    }
    
    void loop()
    {
    }
    
    void receive(const MyMessage &message)
    {
        //Mensajes RELAYS
        if (message.type==V_STATUS) {
            // Change relay state
            digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
    
            // Mensajes uSon
        if (message.type==V_STATUS) {
            distance = ultrasonic.distanceRead();
             Serial.print("Distance in CM: ");
              Serial.println(distance);
             send(msgDistance.set(distance, 1));
            
        }
    }
    

    The sensor works pretty well. I have a rule in Openhab which periodically checks the humidity value from another sensor. If the value is lower than a threshold the watering process is started. First it asks for the water level :

    mosquitto_pub -m "on" -t "mysensors-in/105/0/1/1/2"
    

    The sensor returns the distance to the water level

    mysensors-out/105/0/1/0/37 XX
    

    Which then is converted on Openhab in Litres remaining on the water reservoir.
    If there is enough water, the relay connected to the arduino, which controls a 12V pump, is activated for 10 minutes.

    mosquitto_pub -m 1 -t  mysensors-in/105/1/1/1/2
    

    (10 min timer on Openhab)

    mosquitto_pub -m 0 -t  mysensors-in/105/1/1/1/2
    

    The sensor works very well. It is powered by a USB charger plugged to the wall, so there is no need for energy savings.

    But now I want to build another sensor to water some plants which are outdoor, so I´m going to power it with a 3W solar panel + Lipo Rider + 2000 mAh battery. For this, I want to implement some energy reduction methods, but I a bit lost.

    I want the arduino to sleep for a period (i.e. 10 minutes), wake up periodically, and check if there is any queued message for "measure water level" or "activate Relay" (because the Openhab send its messages without knowing the state of the arduino). I understand I have to activate some kind of persistence of the MQTT broker to retain the message send by the controller until the sensor is awake.

    I added "cleansession false" and "perisitence true" to /etc/mosquitto/mosquitto.conf

    pid_file /var/run/mosquitto.pid
    persistence true
    persistence_location /var/lib/mosquitto/
    log_dest file /var/log/mosquitto/mosquitto.log
    include_dir /etc/mosquitto/conf.d
    password_file /etc/mosquitto/passfile
    allow_anonymous true
    Cleansession false
    
    

    But it doesn´t work. If I send a MQTT message when the arduino is offline and connect it afterward, nothing happens. What I am missing? To be fair, I only tried physically plugging off and on the arduino to check if the mqtt messages are retained (I think is enough for testing), but I plan to implement some kind of sleep mode.

    I´m not really sure if mqtt is properly configured. But anyway I suspect I need to do some more configuration on the Mysensor Gateway side, because when the GW is online, all sensors appear also online, so the MQTT broker doesn´t realize that the sensors are "online" or "offline" (that´s my assumption)

    So,

    1. How do I configure everything in order to store the mqtt messajes and make the arduino "check" for them at waking?.
    2. According to what I have read, there is no way to wake up the arduino when a radio message is received, so thats why I´m trying this "wake and check" method. Anyway, which would be the best sleep mode approach?
    3. Another unrelated issue, when I activate the relay, the Ultrasonic sensor also makes a read, I suspect because both listens to V_STATUS message types. It is not a big issue, but how can I prevent this?

    Thanks!



  • I never used openhab, but your description makes me think about the way your sensor sleeps.
    Are you using sleep or smart sleep?
    If you want to achieve what you described you should use the second one, which informs the controller that the node is awake.



    1. You're not sleeping at all now. After sleep, you can request the current value of the sensor with request(). It depends on the controller if the request function is available.
    2. You can use sleep(600000); see also https://www.mysensors.org/download/sensor_api_20#sleeping.
    3. You are not distinguishing to which child you receive the V_STATUS in receive(). So you should check message.sensor in your if statement also

 

180
Online

8.9k
Users

9.6k
Topics

100.8k
Posts