Adjust / change total energy (kwh) and water (liter) value of the controller or GW



  • I use the following script to log my energy and water meter. I have tried to change the total value to match the actual value on my energy & water meter by changing the pulseCount.

    Does anyone if this is possibleow to do it and h. Thanks

    ![alt text](0_1464972474986_upload-9c76a914-cceb-49b6-bc74-cbe6cf6d008e image url)

    /**
     * based on the pulsecounter sketches form www.mysensors.org
     * changed for S0 ports and working without interrupts which
     * make ghost pulsecounts disappear with the use of S0 ports
     *
     * Combined and changed by Mediacj september/okt/nov 2015
     *
     */
    
    #include <SPI.h>
    #include <MySensor.h>
    
    //water
    #define DIGITAL_INPUT_SENSORW 3  // The digital input for the S0 bus wire
    #define PULSE_FACTORW 1000       // Nummber of rotations per m3 of your meter
    #define CHILD_IDW 10             // Id of the sensor child
    
    //zonnepanelen
    #define DIGITAL_INPUT_SENSORZ 5  // The digital input for the S0 bus wire
    #define PULSE_FACTORZ 1000       // Nummber of blinks per KWH of your meter
    #define MAX_WATT 10000            // Max watt value to report. This filetrs outliers.
    #define CHILD_IDZ 11             // Id of the sensor child
    
    MySensor gw;
    //Water
    double ppwhW = ((double)PULSE_FACTORW) / 1000; // Pulses per watt hour
    boolean pcReceivedW = false;
    volatile unsigned long pulseCountW = 0;
    volatile double volume = 0;
    unsigned long oldPulseCountW = 0;
    double oldVolume;
    unsigned long lastSendW;
    unsigned long nulw;//tijd sinds de laatste 0 waarde
    
    //Zonnepanelen
    double ppwhZ = ((double)PULSE_FACTORZ) / 1000; // Pulses per watt hour
    boolean pcReceivedZ = false;
    volatile unsigned long pulseCountZ = 0;
    unsigned long oldPulseCountZ = 0;
    volatile unsigned long watt = 0;
    unsigned long oldWatt = 0;
    double kwh;
    double oldKwh = 0;
    unsigned long lastSendZ;
    unsigned long nulz;//tijd sinds de laatste 0 waarde
    
    //Water
    MyMessage volumeMsg(CHILD_IDW, V_VOLUME);
    MyMessage pcMsgw(CHILD_IDW, V_VAR1);
    volatile unsigned long pulseLengthW = 0;
    volatile unsigned long lastMillisW = 0;
    boolean timeReceivedW = false;
    boolean sensorIsOnW = false;
    
    //Zonnepanelen
    MyMessage wattMsg(CHILD_IDZ, V_WATT);
    MyMessage kwhMsg(CHILD_IDZ, V_KWH);
    MyMessage pcMsgz(CHILD_IDZ, V_VAR2);
    volatile unsigned long pulseLengthZ = 0;
    volatile unsigned long lastMillisZ = 0;
    boolean timeReceivedZ = false;
    boolean sensorIsOnZ = false;
    int tellerkwh = 0;
    
    void setup()
    {
      gw.begin(incomingMessage);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Water en Energie Meter", "10.0");
      delay(1000);
    
      // Register this device as watersensor
      gw.present(CHILD_IDW, S_WATER);
      // Register this device as power sensor
      delay(1000);
      gw.present(CHILD_IDZ, S_POWER);
    
      // Water Reset pulsecount
      pulseCountW = oldPulseCountW = 0;
    
      // Zonnepanelen Reset pulsecount
      pulseCountZ = oldPulseCountZ = 0;
    
      pinMode(DIGITAL_INPUT_SENSORW, INPUT_PULLUP);       // Enable internal pull-up resistor on pin 3
      pinMode(DIGITAL_INPUT_SENSORZ, INPUT_PULLUP);       // Enable internal pull-up resistor on pin 5
      lastSendW = millis();
      lastSendZ = millis();
    
      // Fetch last known pulses value from gw
      gw.request(CHILD_IDW, V_VAR1);
      gw.request(CHILD_IDZ, V_VAR2);
    
    }
    
    
    void loop()
    {
      gw.process();
      unsigned long now = millis();
    
      //Zonnepanelen#############################
      // read the digital input
      bool solarInput = digitalRead(DIGITAL_INPUT_SENSORZ);
      // rising edge?
      if(solarInput && sensorIsOnZ == false)
      {
        sensorIsOnZ = true;
      }
      // falling edge?
      if(!solarInput && sensorIsOnZ == true)
      {
        pulseLengthZ = micros() - lastMillisZ;
        //store the time for the next pulse
        lastMillisZ = micros();
        // update counters and send to gateway
        pulseCountZ++;
    
        //Last Pulsecount not yet received from controller, request it again
        if (!pcReceivedZ)
        {
          gw.request(CHILD_IDZ, V_VAR2);
          return;
        }
        gw.send(pcMsgz.set(pulseCountZ)); // Send zppulsecount value to gw in VAR2
        watt = (((3600000000.0 / pulseLengthZ) / ppwhZ)); //was 1.0118 personal multiply factor not necessary (1.0115)
        if(watt != oldWatt && watt < ((unsigned long)MAX_WATT))
        {
          Serial.println(watt);
          gw.send(wattMsg.set(watt));
        }; // Send watt value to gw
        oldWatt = watt;
        lastSendZ = now;
        sensorIsOnZ = false;
        tellerkwh++;
        if (tellerkwh == 2)
        {
          double kwh = ((double)pulseCountZ / ((double)PULSE_FACTORZ)); //was 1.0118 personal multiply factor not necessary
          oldKwh = kwh;
          tellerkwh  = 0;
          Serial.println(kwh);
          gw.send(kwhMsg.set(kwh, 4));// Send kwh value to gw. 4 mean 4 digits before the comma
        };
      }
    
    
      // Watermeter###########################
      // read the digital input
      bool waterInput = digitalRead(DIGITAL_INPUT_SENSORW);
      // rising edge?
      if(waterInput && sensorIsOnW == false)
      {
        sensorIsOnW = true;
      }
      // falling edge?
      if(!waterInput && sensorIsOnW == true)
      {
        //controle
        if ((micros() - lastMillisW) < 3000000L)
        {
          return;   //Sometimes we get interrupt on RISING, = 3 sek debounce
        }
        // store the time between the last two pulses
        pulseLengthW = micros() - lastMillisW;
        //store the time for the next pulse
        lastMillisW = micros();
        // update counters
        pulseCountW++;
        //Last Pulsecount not yet received from controller, request it again
        if (!pcReceivedW)
        {
          gw.request(CHILD_IDW, V_VAR1);
          return;
        }
        gw.send(pcMsgw.set(pulseCountW)); // Send waterpulsecount value to gw in VAR2
        sensorIsOnW = false;
        double volume = ((double)pulseCountW / ((double)PULSE_FACTORW));
        oldPulseCountW = pulseCountW;
        Serial.println(volume);
        gw.send(volumeMsg.set(volume, 3));  // Send volume value to gw. 3 mean 3 digits before the comma
        oldVolume = volume;
        lastSendW = now;
      }
    
      //Water na 10 minuten geen pulse laatste waarde herhalen
    //  if ((now - lastSendW) > 600000)
    //  {
    //    gw.send(volumeMsg.set(oldVolume, 3));
    //    
    //    lastSendW = now;
    //    nulw = millis();
    //  }
    //
    //  //Zonnepanelen na 12 minuten geen pulse 0 waarde sturen
    //  if ((now - lastSendZ) > 720000)
    //  {
    //    watt = 0;
    //    gw.send(wattMsg.set(watt));
    //    lastSendZ = now;
    //    nulz = millis();
    //    gw.send(kwhMsg.set(oldKwh, 4));
    //  }
    }
    
    void incomingMessage(const MyMessage &message)
    {
      if (message.type == V_VAR1)
      {
        unsigned long gwPulseCountW = message.getULong();
        pulseCountW += gwPulseCountW;
        volume = oldVolume = 0;
        Serial.print("Received last water pulse count from gw:");
        Serial.println(pulseCountW);
        pcReceivedW = true;
      }
    
      if (message.type == V_VAR2)
      {
        unsigned long gwPulseCountZ = message.getULong();
        pulseCountZ += gwPulseCountZ;
        kwh = oldKwh = 0;
        Serial.print("Received last zon pulse count from gw:");
        Serial.println(pulseCountZ);
        pcReceivedZ = true;
      }
    }
    

  • Mod



  • @mfalkvidd Thanks

    The idea of changing the pulseCount is correct. However I had set the value at the wrong place without realizing the pulseCount is reset at the Void setup() section.

     // Water Reset pulsecount
      pulseCountW = oldPulseCountW = 0;
    
      // Zonnepanelen Reset pulsecount
      pulseCountZ = oldPulseCountZ = 0;
    

    The solution is

    Change the 0 to : Value (meter) - Value (Controller)

    Upload the sketch. wait until the first pulse is sent to the gateway.

    If successed the controller (domoticz in my case) will show the total value matching the value on the physical meter.

    Now change the value in the sketch back to 0. (Otherwise each time you reset the sensor or the gateway the value wil be added to the total value.) Upload the sketch to the sensor.

    You are done. There is no need to Modify the Domoticz database with SQL tool.

    You will get the value you've just added to the total value in the day value log. If you find this ignoring you can delete this value the next day. This only applies to Energy meter. Do not apply this to the water meter as the result the total value of the water meter will be gone too.


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.