sendBatteryLevel is not published to MQTT



  • This is my setup:

    • mysgw (2.3.0 release) connecting to mosquitto MQTT
    • one node with 3 sensors (node compiled using 2.3.0 Arduino lib)

    Node uses sendBatteryLevel function to send current battery level. I can see that when node when starts, then "prenests" itself to gateway battery level is published to MQTT. Then node goes to sleep for 10min, then wakes up and sends battery level again (amoung other sensor values). Each sensor value is published to MQTT but battery level not.



  • @michał-kozak Do you see incomming battery level message in mysgw logs ?


  • Mod

    @michał-kozak could you post your sketch?



  • @rozpruwacz I haven't checked that.
    @mfalkvidd here it is my complete sketch. Battery level should be published to MQTT together with battery voltage. I can see battery voltage in MQTT but not battery level.

    //#define MY_DEBUG
    #define MY_RADIO_NRF24
    #define MY_NODE_ID 3
    #define MY_RF24_PA_LEVEL RF24_PA_MAX
    
    #include <MySensors.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    typedef struct BatteryStatus {
      float voltage;
      int level;
    } BatteryStatus;
    
    typedef struct Temperatures {
      float top;
      float bottom;
    } Temperatures;
    
    const byte TOP_SENSOR_ID = 1;
    const byte BOTTOM_SENSOR_ID = 2;
    const byte BATTERY_VOLTAGE_SENSOR_ID = 3;
    const uint32_t SLEEP_TIME = 600000UL;
    const bool DEBUG = false;
    const bool DO_SEARCH_DEVICES = false;
    const float VBAT_FULL = 2.8;
    const float VBAT_EMPTY = 2.0;
    
    BatteryStatus batteryStatus;
    BatteryStatus currentBatteryStatus;
    Temperatures temperatures;
    Temperatures currentTemperatures;
    
    // define oneWire communication  
    OneWire oneWire(3);
    DallasTemperature sensors(&oneWire); 
    DeviceAddress topThermometer = {0x28,0xFF,0xF8,0x5,0x1A,0x4,0x0,0x4A};
    DeviceAddress bottomThermometer = {0x28,0xFF,0x71,0xF,0x12,0x4,0x0,0x4C};
    
    // define mysensors messages
    MyMessage tempTopMsg(TOP_SENSOR_ID, V_TEMP);
    MyMessage tempBottomMsg(BOTTOM_SENSOR_ID, V_TEMP);
    MyMessage vbatMsg(BATTERY_VOLTAGE_SENSOR_ID, V_VOLTAGE);
    
    void getBatteryStatus(BatteryStatus *batteryStatus) {
      int val = analogRead(A0);
      float voltage  = val * 0.00325458871;
      int level;
      if (voltage > VBAT_FULL) {
        level = 100;
      } else if (voltage < VBAT_EMPTY) {
        level = 0;
      } else {
        level = (int) ((voltage - VBAT_EMPTY) * 100.0 / (VBAT_FULL - VBAT_EMPTY));
      }
      if (DEBUG) {
        Serial.print("getBatteryStatus: ");
        Serial.print("val=");
        Serial.print(val);
        Serial.print(", level=");
        Serial.print(level);
        Serial.print("%, ");
        Serial.print("voltage=");
        Serial.print(voltage);
        Serial.print("V");
        Serial.println();
      }
      batteryStatus->voltage = voltage;
      batteryStatus->level = level;
    }
    
    void sendBatteryStatus(BatteryStatus *batteryStatus) {
      sendBatteryLevel(batteryStatus->level);
      vbatMsg.set(batteryStatus->voltage, 2);
      send(vbatMsg);
    }
    
    bool isTemperatureValid(float temp) {
      return temp != -127.00 && temp != 85.00;
    }
    
    bool getTemperatures(Temperatures *temperatures) {
      sensors.requestTemperatures();
      int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
      sleep(conversionTime);
    
      temperatures->top = sensors.getTempC(topThermometer);
      temperatures->bottom = sensors.getTempC(bottomThermometer);
    
      if (DEBUG) {
        Serial.print("getTemperatures: ");
        Serial.print("top=");
        Serial.print(temperatures->top);
        Serial.print(", bottom=");
        Serial.print(temperatures->bottom);
        Serial.println();
      }
    
      return isTemperatureValid(temperatures->top) && isTemperatureValid(temperatures->bottom);
    }
    
    void sendTemperatures(Temperatures *temperatures) {
      tempTopMsg.set(temperatures->top, 1);
      tempBottomMsg.set(temperatures->bottom, 1);
      send(tempTopMsg);
      send(tempBottomMsg);
    }
    
    void searchDevices() {
      Serial.print("Locating devices...");
      int deviceCount = sensors.getDeviceCount();
      Serial.print("found ");
      Serial.print(deviceCount, DEC);
      Serial.println(" devices.");
      for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) {
        DeviceAddress addr;
        if (sensors.getAddress(addr, deviceIndex)) {
          Serial.print("Device ");
          Serial.print(deviceIndex, DEC);
          Serial.print(" = {");
          for (uint8_t i = 0; i < 8; i++)
          {
              Serial.print("0x");
              Serial.print(addr[i], HEX);
              if (i + 1 < 8) {
                Serial.print(",");
              }
          }
          Serial.print("}");
          Serial.println();
        } else {
          Serial.print("Unable to find address for Device ");
          Serial.println(deviceIndex, DEC);
        }
      }
    }
    
    void before() {
      sensors.begin();
    
      if (DO_SEARCH_DEVICES) {
        searchDevices();
      }
    }
    
    void setup() {
      // configure analog pin and do the first read
      // looks like first read always returns MAX value,
      // subsequent reads seems to be accurate
    	analogReference(INTERNAL);
      analogRead(A0);
      
      batteryStatus.level = 0;
      batteryStatus.voltage = 0;
      temperatures.top = -127.00;
      temperatures.bottom = -127.00;
    
      // configure temperature readings to not block current thread
      sensors.setWaitForConversion(false);
    }
    
    void presentation() {
    	sendSketchInfo("CWU", "1.2");
      present(TOP_SENSOR_ID, S_TEMP, "Top temp");
      present(BOTTOM_SENSOR_ID, S_TEMP, "Bottom temp");
      present(BATTERY_VOLTAGE_SENSOR_ID, S_MULTIMETER, "Vbat");
    }
    
    void loop() {
      if (DEBUG) {
        Serial.print("batteryStatus.level=");
        Serial.print(batteryStatus.level);
        Serial.print("%, batteryStatus.voltage=");
        Serial.print(batteryStatus.voltage);
        Serial.println("V");
        Serial.print("temperatures.top=");
        Serial.print(temperatures.top);
        Serial.print(", temperatures.bottom=");
        Serial.print(temperatures.bottom);
        Serial.println();
      }
    
      getBatteryStatus(&currentBatteryStatus);
      if (batteryStatus.level != currentBatteryStatus.level || batteryStatus.voltage != currentBatteryStatus.voltage) {
        if (DEBUG) {
          Serial.println("Sending battery status");
        }
        batteryStatus = currentBatteryStatus;
        sendBatteryStatus(&batteryStatus);
      }
      
      if (getTemperatures(&currentTemperatures)) {
        if (temperatures.top != currentTemperatures.top || temperatures.bottom != currentTemperatures.bottom) {
          if (DEBUG) {
            Serial.println("Sending temperatures");
          }
          temperatures = currentTemperatures;
          sendTemperatures(&temperatures);
        }
      }
    
      sleep(SLEEP_TIME);
    }
    


  • Example massages published to MQTT

    mysensors-out/3/3/1/0/38 2.65
    mysensors-out/3/1/1/0/0 37.9
    mysensors-out/3/2/1/0/0 29.2
    

    As you can see voltage is published (mysensors-out/3/3/1/0/38 2.65) so looking into my sketch I would expect that battery level also is published because I send battery level and voltage in sendBatteryStatus function.



  • I'm still investigating my problem 🙂

    I checked logs from gateway and I can't see received messages with battery level, so looks like message is not reaching a gateway at all.

    Situation improved a bit when I started using sendBatteryLevel with ACK, but it is still not perfect :).

    I suspect that because sendBatteryLevel is a first message send after arduino wakes up maybe it could be that transport layer is not initilized yet? Maybe I should wait few sec after wake up before I start sending messages? What do you think?


  • Mod

    @michał-kozak well done. I think you are correct that the first message is affected. See https://forum.mysensors.org/topic/9655/delay-after-tsf-tri-tsb/14 for a solution.


Log in to reply
 

Suggested Topics

11
Online

11.4k
Users

11.1k
Topics

112.7k
Posts