Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Bug Reports
  3. sendBatteryLevel is not published to MQTT

sendBatteryLevel is not published to MQTT

Scheduled Pinned Locked Moved Bug Reports
7 Posts 3 Posters 1.2k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Michał Kozak
    wrote on last edited by
    #1

    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.

    rozpruwaczR mfalkviddM 2 Replies Last reply
    0
    • M Michał Kozak

      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.

      rozpruwaczR Offline
      rozpruwaczR Offline
      rozpruwacz
      wrote on last edited by
      #2

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

      1 Reply Last reply
      0
      • M Michał Kozak

        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.

        mfalkviddM Offline
        mfalkviddM Offline
        mfalkvidd
        Mod
        wrote on last edited by
        #3

        @michał-kozak could you post your sketch?

        1 Reply Last reply
        0
        • M Offline
          M Offline
          Michał Kozak
          wrote on last edited by
          #4

          @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);
          }
          
          1 Reply Last reply
          0
          • M Offline
            M Offline
            Michał Kozak
            wrote on last edited by
            #5

            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.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              Michał Kozak
              wrote on last edited by
              #6

              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?

              mfalkviddM 1 Reply Last reply
              1
              • M Michał Kozak

                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?

                mfalkviddM Offline
                mfalkviddM Offline
                mfalkvidd
                Mod
                wrote on last edited by
                #7

                @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.

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                20

                Online

                11.7k

                Users

                11.2k

                Topics

                113.1k

                Posts


                Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • MySensors
                • OpenHardware.io
                • Categories
                • Recent
                • Tags
                • Popular