Hulp nodig bij DSMRlogger API van Aandewiel

Hallo Allemaal,

Ik zoek iemand die mij zou kunnen helpen om het een en ander toe te voegen in een bestaand slimme meter project.
Ik loop gewoon vast omdat ik daar gewoon te weinig kaas van heb gegeten en dit voor mij een behoorlijk complexe code is.

Ik heb deze logger draaien op een ESP8266 om mijn slimme meter uit te lezen.
http://https://github.com/mrWheel/DSMRloggerAPI

Wat ik zou willen toevoegen is een bepaalde actie bij een verbruik van 10 KWh.
Ik krijg het nu niet eens voor elkaar om iets in de loop op mijn serial monitor te printen omdat die code behoorlijk complex is.

Ik hoop dat iemand mij zou kunnen en willen helpen!

Dennis

/*
***************************************************************************
**  Program  : DSMRloggerAPI (restAPI)
*/
#define _FW_VERSION "v3.0.1 (15-06-2021)"
/*
**  Copyright (c) 2020, 2021 Willem Aandewiel
**
**  TERMS OF USE: MIT License. See bottom of file.
***************************************************************************

  Arduino-IDE settings for DSMR-logger Version 4 (ESP-12):

    - Board: "Generic ESP8266 Module"
    - Builtin Led: "2"  // GPIO02 for Wemos and ESP-12
    - Flash mode: "DOUT" | "DIO"    // changes only after power-off and on again!
    - Flash size: "4MB (FS: 2MB OAT:~1019KB)"  << LET OP! 2MB FSYS
    - DebugT port: "Disabled"
    - DebugT Level: "None"
    - IwIP Variant: "v2 Lower Memory"
    - Reset Method: "none"   // but will depend on the programmer!
    - Crystal Frequency: "26 MHz"
    - VTables: "Flash"
    - Flash Frequency: "40MHz"
    - CPU Frequency: "80 MHz" (or 160MHz)
    - Upload Speed: "115200"
    - Erase Flash: "Only Sketch"
    - Port: <select correct port>
*/
/*
**  You can find more info in the following links (all in Dutch):
**   https://willem.aandewiel.nl/index.php/2020/02/28/restapis-zijn-hip-nieuwe-firmware-voor-de-dsmr-logger/
**   https://mrwheel-docs.gitbook.io/dsmrloggerapi/
**   https://mrwheel.github.io/DSMRloggerWS/
*/
/******************** compiler options  ********************************************/
#define USE_LITTLEFS              // if not #defined: use SPIFFS
#define USE_UPDATE_SERVER         // define if there is enough memory and updateServer to be used
#define USE_MQTT                  // define if you want to use MQTT (configure through webinterface)
#define USE_MINDERGAS             // define if you want to update mindergas (configure through webinterface)
//  #define USE_SYSLOGGER             // define if you want to use the sysLog library for debugging
//  #define SHOW_PASSWRDS             // well .. show the PSK key and MQTT password, what else?
//  #define HAS_NO_SLIMMEMETER        // define for testing only!
/******************** don't change anything below this comment **********************/

#include "DSMRloggerAPI.h"

struct showValues {
  template<typename Item>
  void apply(Item &i) {
    if (i.present())
    {
      DebugT(Item::name);
      Debug(F(": "));
      Debug(i.val());
      Debug(Item::unit());
    }
    Debugln();
  }
};


//===========================================================================================
void displayStatus()
{
  if (settingOledType > 0)
  {
    switch (msgMode) {
      case 1:   snprintf(cMsg, sizeof(cMsg), "Up:%-15.15s", upTime().c_str());
        break;
      case 2:   snprintf(cMsg, sizeof(cMsg), "WiFi RSSI:%4d dBm", WiFi.RSSI());
        break;
      case 3:   snprintf(cMsg, sizeof(cMsg), "Heap:%7d Bytes", ESP.getFreeHeap());
        break;
      case 4:   if (WiFi.status() != WL_CONNECTED)
          snprintf(cMsg, sizeof(cMsg), "**** NO  WIFI ****");
        else  snprintf(cMsg, sizeof(cMsg), "IP %s", WiFi.localIP().toString().c_str());
        break;
      default:  snprintf(cMsg, sizeof(cMsg), "Telgrms:%6d/%3d", telegramCount, telegramErrors);
        break;
    }

    oled_Print_Msg(3, cMsg, 0);
    msgMode = (msgMode + 1) % 5; //modular 5 = number of message displayed (hence it cycles thru the messages
  }
} // displayStatus()


#ifdef USE_SYSLOGGER
//===========================================================================================
void openSysLog(bool empty)
{
  if (sysLog.begin(500, 100, empty))  // 500 lines use existing sysLog file
  {
    DebugTln("Succes opening sysLog!");
    if (settingOledType > 0)
    {
      oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
      oled_Print_Msg(3, "Syslog OK!", 500);
    }
  }
  else
  {
    DebugTln("Error opening sysLog!");
    if (settingOledType > 0)
    {
      oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
      oled_Print_Msg(3, "Error Syslog", 1500);
    }
  }

  sysLog.setDebugLvl(1);
  sysLog.setOutput(&TelnetStream);
  sysLog.status();
  sysLog.write("\r\n");
  for (int q = 0; q < 3; q++)
  {
    sysLog.write("******************************************************************************************************");
  }
  writeToSysLog("Last Reset Reason [%s]", ESP.getResetReason().c_str());
  writeToSysLog("actTimestamp[%s], nrReboots[%u], Errors[%u]", actTimestamp
                , nrReboots
                , slotErrors);

  sysLog.write(" ");

} // openSysLog()
#endif

//===========================================================================================



#define LED 13 //connect LED to digital pin13
#define LED2 4 //connect LED to digital pin5


//===========================================================================================



void setup()
{
  Serial.begin(115200, SERIAL_8N1); // for now. Look at end of setup()
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(FLASH_BUTTON, INPUT);
  pinMode(DTR_ENABLE, OUTPUT);

  //===========================================================================================

  pinMode(LED, OUTPUT);
  //===========================================================================================

  //--- setup randomseed the right way
  //--- This is 8266 HWRNG used to seed the Random PRNG
  //--- Read more: https://config9.com/arduino/getting-a-truly-random-number-in-arduino/
  randomSeed(RANDOM_REG32);
  snprintf(settingHostname, sizeof(settingHostname), "%s", _DEFAULT_HOSTNAME);
  Serial.printf("\n\nBooting....[%s]\r\n\r\n", String(_FW_VERSION).c_str());

  if (settingOledType > 0)
  {
    oled_Init();
    oled_Clear();  // clear the screen so we can paint the menu.
    oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
    int8_t sPos = String(_FW_VERSION).indexOf(' ');
    snprintf(cMsg, sizeof(cMsg), "(c)2020 [%s]", String(_FW_VERSION).substring(0, sPos).c_str());
    oled_Print_Msg(1, cMsg, 0);
    oled_Print_Msg(2, " Dennis Hendriks", 0);
    oled_Print_Msg(3, " >> Have fun!! <<", 1000);
    yield();
  }
  else  // don't blink if oled-screen attatched
  {
    for (int I = 0; I < 8; I++)
    {
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
      delay(500);
    }
  }
  digitalWrite(LED_BUILTIN, LED_OFF);  // HIGH is OFF
  lastReset     = ESP.getResetReason();

  startTelnet();
  if (settingOledType > 0)
  {
    oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
    oled_Print_Msg(3, "telnet (poort 23)", 2500);
  }

  //================ FSYS ===========================================
#if defined( USE_LITTLEFS )
  LittleFSConfig cfg;
#else
  SPIFFSConfig cfg;
#endif
  cfg.setAutoFormat(false);
  FSYS.setConfig(cfg);

  if (FSYS.begin())
  {
#if defined( USE_LITTLEFS )
    DebugTln(F("LittleFS Mount succesfull\r"));
#else
    DebugTln(F("SPIFFS Mount succesfull\r"));
#endif
    File nF = FSYS.open("/!doNotFormat", "w");
    nF.close();
    FSYSmounted = true;
    if (settingOledType > 0)
    {
      oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
      oled_Print_Msg(3, "FSYS mounted", 1500);
    }
  } else {
#if defined( USE_LITTLEFS )
    DebugTln(F("LittleFS Mount failed\r")); // Serious problem with LittleFS
#else
    DebugTln(F("SPIFFS Mount failed\r"));   // Serious problem with SPIFFS
#endif
    FSYSmounted = false;
    if (settingOledType > 0)
    {
      oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
      oled_Print_Msg(3, "FSYS FAILED!", 2000);
    }
  }

  //------ read status file for last Timestamp --------------------
  strcpy(actTimestamp, "040302010101X");
  //==========================================================//
  // writeLastStatus();  // only for firsttime initialization //
  //==========================================================//
  readLastStatus(); // place it in actTimestamp
  // set the time to actTimestamp!
  actT = epoch(actTimestamp, strlen(actTimestamp), true);
  DebugTf("===> actTimestamp[%s]-> nrReboots[%u] - Errors[%u]\r\n\n", actTimestamp
          , nrReboots++
          , slotErrors);
  readSettings(true);
  oled_Init();

  //=============start Networkstuff==================================
  if (settingOledType > 0)
  {
    if (settingOledFlip)  oled_Init();  // only if true restart(init) oled screen
    oled_Clear();                       // clear the screen
    oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
    oled_Print_Msg(1, "Verbinden met WiFi", 500);
  }
  digitalWrite(LED_BUILTIN, LED_ON);

  startWiFi(settingHostname, 240);  // timeout 4 minuten

  if (settingOledType > 0)
  {
    oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
    oled_Print_Msg(1, WiFi.SSID(), 0);
    snprintf(cMsg, sizeof(cMsg), "IP %s", WiFi.localIP().toString().c_str());
    oled_Print_Msg(2, cMsg, 1500);
  }
  digitalWrite(LED_BUILTIN, LED_OFF);

  Debugln();
  Debug (F("Connected to " )); Debugln (WiFi.SSID());
  Debug (F("IP address: " ));  Debugln (WiFi.localIP());
  Debug (F("IP gateway: " ));  Debugln (WiFi.gatewayIP());
  Debugln();

  for (int L = 0; L < 10; L++) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

    delay(200);
  }
  digitalWrite(LED_BUILTIN, LED_OFF);


  //-----------------------------------------------------------------
#ifdef USE_SYSLOGGER
  openSysLog(false);
  snprintf(cMsg, sizeof(cMsg), "SSID:[%s],  IP:[%s], Gateway:[%s]", WiFi.SSID().c_str()
           , WiFi.localIP().toString().c_str()
           , WiFi.gatewayIP().toString().c_str());
  writeToSysLog("%s", cMsg);

#endif

  startMDNS(settingHostname);
  if (settingOledType > 0)
  {
    oled_Print_Msg(3, "mDNS gestart", 1500);
  }

  //=============end Networkstuff======================================

  //================ startNTP =========================================
  if (settingOledType > 0)
  {
    oled_Print_Msg(3, "setup NTP server", 100);
  }

  if (!startNTP())
  {
    DebugTln(F("ERROR!!! No NTP server reached!\r\n\r"));
    if (settingOledType > 0)
    {
      oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
      oled_Print_Msg(2, "geen reactie van", 100);
      oled_Print_Msg(2, "NTP server's", 100);
      oled_Print_Msg(3, "Reboot DSMR-logger", 2000);
    }
    delay(2000);
    ESP.restart();
    delay(3000);
  }

  setSyncProvider(getNtpTime);
  snprintf(cMsg, sizeof(cMsg), "%02d-%02d-%02d %02d:%02d:%02d (%s)"
           , year(ntpTime), month(ntpTime), day(ntpTime)
           , hour(ntpTime), minute(ntpTime), second(ntpTime)
           , DSTactive ? "CEST" : "CET");
  DebugTf("NTP time is [%s]\r\n", cMsg);

  if (settingOledType > 0)
  {
    oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
    oled_Print_Msg(3, "NTP gestart", 1500);
  }
  prevNtpHour = hour();

  //================ end NTP =========================================

  snprintf(cMsg, sizeof(cMsg), "Last reset reason: [%s]\r", ESP.getResetReason().c_str());
  DebugTln(cMsg);

  Serial.print("\nGebruik 'telnet ");
  Serial.print (WiFi.localIP());
  Serial.println("' voor verdere debugging\r\n");

  //=============now test if FS is correct populated!============
  if (DSMRfileExist(settingIndexPage, false) )
  {
    if (strcmp(settingIndexPage, "DSMRindex.html") != 0)
    {
      if (settingIndexPage[0] != '/')
      {
        char tempPage[50] = "/";
        strConcat(tempPage, 49, settingIndexPage);
        strCopy(settingIndexPage, sizeof(settingIndexPage), tempPage);
      }
      hasAlternativeIndex        = true;
    }
    else  hasAlternativeIndex    = false;
  }
  if (!hasAlternativeIndex && !DSMRfileExist("/DSMRindex.html", false) )
  {
    FSYSnotPopulated = true;
  }
  if (!hasAlternativeIndex)    //--- there's no alternative index.html
  {
    DSMRfileExist("/DSMRindex.js",    false);
    DSMRfileExist("/DSMRindex.css",   false);
    DSMRfileExist("/DSMRgraphics.js", false);
  }
  if (!DSMRfileExist("/FSmanager.html", true))
  {
    FSYSnotPopulated = true;
  }
  if (!DSMRfileExist("/FSmanager.css", true))
  {
    FSYSnotPopulated = true;
  }
  //=============end FSYS =========================================
#ifdef USE_SYSLOGGER
  if (FSYSnotPopulated)
  {
    sysLog.write("FSYS is not correct populated (files are missing)");
  }
#endif

  //=============now test if "convertPRD" file exists================

  if (FSYS.exists("/!PRDconvert") )
  {
    convertPRD2RING();
  }

  //=================================================================

  time_t t = now(); // store the current time in time variable t
  check4DST(t);
  snprintf(cMsg, sizeof(cMsg), "%02d%02d%02d%02d%02d%02d\0\0"                      //USE_NTP
           , (year(t) - 2000), month(t), day(t) //USE_NTP
           , hour(t), minute(t), second(t));    //USE_NTP
  if (DSTactive)  strConcat(cMsg, 15, "S");
  else            strConcat(cMsg, 15, "W");
  pTimestamp = cMsg;                                                                //USE_NTP
  DebugTf("Time is set to [%s] from NTP\r\n", cMsg);                                //USE_NTP

  if (settingOledType > 0)
  {
    snprintf(cMsg, sizeof(cMsg), "DT: %02d%02d%02d%02d0101x", thisYear
             , thisMonth, thisDay, thisHour);
    oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
    oled_Print_Msg(3, cMsg, 1500);
  }

  //================ Start MQTT  ======================================

#ifdef USE_MQTT                                                 //USE_MQTT
  connectMQTT();                                                //USE_MQTT
  if (settingOledType > 0)                                      //USE_MQTT
  { //USE_MQTT
    oled_Print_Msg(0, " <DSMRloggerAPI>", 0);                    //USE_MQTT
    oled_Print_Msg(3, "MQTT server set!", 1500);                //USE_MQTT
  }                                                             //USE_MQTT
#endif                                                          //USE_MQTT

  //================ End of Start MQTT  ===============================


  //================ Start HTTP Server ================================

  if (!FSYSnotPopulated) {
    DebugTln(F("FSYS correct populated -> normal operation!\r"));
    if (settingOledType > 0)
    {
      oled_Print_Msg(0, " <DSMRloggerAPI>", 0);
      oled_Print_Msg(1, "OK, FSYS correct", 0);
      oled_Print_Msg(2, "Verder met normale", 0);
      oled_Print_Msg(3, "Verwerking ;-)", 2500);
    }
    if (hasAlternativeIndex)
    {
      httpServer.serveStatic("/",                 FSYS, settingIndexPage);
      httpServer.serveStatic("/index",            FSYS, settingIndexPage);
      httpServer.serveStatic("/index.html",       FSYS, settingIndexPage);
      httpServer.serveStatic("/DSMRindex.html",   FSYS, settingIndexPage);
    }
    else
    {
      httpServer.serveStatic("/",                 FSYS, "/DSMRindex.html");
      httpServer.serveStatic("/DSMRindex.html",   FSYS, "/DSMRindex.html");
      httpServer.serveStatic("/index",            FSYS, "/DSMRindex.html");
      httpServer.serveStatic("/index.html",       FSYS, "/DSMRindex.html");
      httpServer.serveStatic("/DSMRindex.css",    FSYS, "/DSMRindex.css");
      httpServer.serveStatic("/DSMRindex.js",     FSYS, "/DSMRindex.js");
      httpServer.serveStatic("/DSMRgraphics.js",  FSYS, "/DSMRgraphics.js");

    }
  } else {
    DebugTln(F("Oeps! not all files found on FSYS -> Start FSmanager!\r"));
    FSYSnotPopulated = true;
    if (settingOledType > 0)
    {
      oled_Print_Msg(0, "!OEPS! niet alle", 0);
      oled_Print_Msg(1, "files op FSYS", 0);
      oled_Print_Msg(2, "gevonden! (fout!)", 0);
      oled_Print_Msg(3, "Start FSmanager", 2000);
    }
  }

  setupFsManager();
  //httpServer.serveStatic("/FSexplorer.png",   FSYS, "/FSexplorer.png");

  httpServer.on("/api", HTTP_GET, processAPI);
  // all other api calls are catched in FSmanager onNotFounD!

  httpServer.begin();
  DebugTln( "HTTP server gestart\r" );
  if (settingOledType > 0)                                  //HAS_OLED
  { //HAS_OLED
    oled_Clear();                                           //HAS_OLED
    oled_Print_Msg(0, " <DSMRloggerAPI>", 0);                //HAS_OLED
    oled_Print_Msg(2, "HTTP server ..", 0);                 //HAS_OLED
    oled_Print_Msg(3, "gestart (poort 80)", 0);             //HAS_OLED
  }                                                         //HAS_OLED

  for (int i = 0; i < 10; i++)
  {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    delay(250);
  }
  //================ Start HTTP Server ================================

  //test(); monthTabel

#ifdef USE_MINDERGAS
  handleMindergas();
#endif

  DebugTf("Startup complete! actTimestamp[%s]\r\n", actTimestamp);
  writeToSysLog("Startup complete! actTimestamp[%s]", actTimestamp);

  //================ End of Slimmer Meter ============================


  //================ The final part of the Setup =====================

  snprintf(cMsg, sizeof(cMsg), "Last reset reason: [%s]\r", ESP.getResetReason().c_str());
  DebugTln(cMsg);

  if (settingOledType > 0)
  {
    oled_Print_Msg(0, "<DSMRloggerAPI>", 0);
    oled_Print_Msg(1, "Startup complete", 0);
    oled_Print_Msg(2, "Wait for first", 0);
    oled_Print_Msg(3, "telegram .....", 500);
  }

  //================ Start Slimme Meter ===============================

  DebugTln(F("Enable slimmeMeter..\r"));

#if !defined( HAS_NO_SLIMMEMETER )
  DebugTf("Swapping serial port to Smart Meter, debug output will continue on telnet\r\n");
  DebugFlush();
  if (settingPreDSMR40 == 0)
  {
    DebugTln("Serial will be set to 115200 baud / 7N1");
    DebugFlush();
    Serial.end();
    delay(100);
    Serial.begin(115200, SERIAL_8N1);
    slimmeMeter.doChecksum(true);
  }
  else
  { //PRE40
    DebugTln("Serial will be set to 9600 baud / 7N1");
    DebugFlush();
    Serial.end();
    delay(100);
    Serial.begin(9600, SERIAL_7E1);
    slimmeMeter.doChecksum(false);
  }
  Serial.swap();

#endif // HAS_NO_SLIMME_METER

  delay(100);
  slimmeMeter.enable(true);

} // setup()


//===[ no-blocking delay with running background tasks in ms ]============================
DECLARE_TIMER_MS(timer_delay_ms, 1);
void delayms(unsigned long delay_ms)
{
  CHANGE_INTERVAL_MS(timer_delay_ms, delay_ms);
  RESTART_TIMER(timer_delay_ms);
  while (!DUE(timer_delay_ms))
  {
    doSystemTasks();
  }

} // delayms()

//========================================================================================

//==[ Do Telegram Processing ]===============================================================
void doTaskTelegram()
{

  if (Verbose1) DebugTln("doTaskTelegram");
#if defined(HAS_NO_SLIMMEMETER)
  handleTestdata();
#else
  //-- enable DTR to read a telegram from the Slimme Meter
  slimmeMeter.enable(true);
  slimmeMeter.loop();
  handleSlimmemeter();
#endif
  if (WiFi.status() != WL_CONNECTED)
  {
    for (int b = 0; b < 10; b++) {
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

      delay(75);
    }

  }
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

}

//===[ Do System tasks ]=============================================================
void doSystemTasks()
{

#ifndef HAS_NO_SLIMMEMETER
  slimmeMeter.loop();
#endif
#ifdef USE_MQTT
  MQTTclient.loop();
#endif
  httpServer.handleClient();
  MDNS.update();
  handleKeyInput();
  if (settingOledType > 0)
  {
    checkFlashButton();
  }

  yield();

} // doSystemTasks()


void loop ()
{

  //--- do the tasks that has to be done
  //--- as often as possible
  doSystemTasks();

  loopCount++;

  //--- verwerk volgend telegram
  if DUE(nextTelegram)
  {
    doTaskTelegram();
  }

  //--- update upTime counter
  if DUE(updateSeconds)
  {
    upTimeSeconds++;
  }

  //--- if an OLED screen attached, display the status
  if (settingOledType > 0)
  {
    if DUE(updateDisplay)
    {
      displayStatus();
    }
  }

  //--- if mindergas then check
#ifdef USE_MINDERGAS
  if ( DUE(minderGasTimer) )
  {
    handleMindergas();
  }
#endif

  //--- if connection lost, try to reconnect to WiFi
  if ( DUE(reconnectWiFi) && (WiFi.status() != WL_CONNECTED) )
  {
    writeToSysLog("Restart wifi with [%s]...", settingHostname);
    startWiFi(settingHostname, 10);
    if (WiFi.status() != WL_CONNECTED)
      writeToSysLog("%s", "Wifi still not connected!");
    else {
      snprintf(cMsg, sizeof(cMsg), "IP:[%s], Gateway:[%s]", WiFi.localIP().toString().c_str()
               , WiFi.gatewayIP().toString().c_str());
      writeToSysLog("%s", cMsg);
    }
  }

  //--- see if NTP needs synchronizing
  if DUE(synchrNTP)
  {
    setSyncProvider(getNtpTime);
    setSyncInterval(600);
    check4DST(ntpTime);
  }
  yield();

} // loop()



/***************************************************************************

  Permission is hereby granted, free of charge, to any person obtaining a
  copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to permit
  persons to whom the Software is furnished to do so, subject to the
  following conditions:

  The above copyright notice and this permission notice shall be included
  in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
  OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
  THE USE OR OTHER DEALINGS IN THE SOFTWARE.

***************************************************************************/
Stijnos

Golden Member

Ik ken dit project niet, maar als ik zo op github kijk wordt de slimme meter seriële data in een struct DSMRdata geparsed.
Dus je gaat in die struct velden vinden voor het actuele verbuik per fase, maar ook energy_delivered_tariff1 en energy_delivered_tariff2

Met deze waarden kun je dus een startpunt van verbruikt vast leggen in een variabele en dan blijft je die vergelijken met de huidige waarde. als dat groter is van 10kWh (of een configureerbare warde), doe je iets.

Je wilt dit device zelf iets actief laten doen? (in de zin van een pinnetje hoog of laag maken, of een seriële string sturen?)
Lijkt me redelijk haalbaar.

Op 9 december 2021 14:32:48 schreef Stijnos:
Ik ken dit project niet, maar als ik zo op github kijk wordt de slimme meter seriële data in een struct DSMRdata geparsed.
Dus je gaat in die struct velden vinden voor het actuele verbuik per fase, maar ook energy_delivered_tariff1 en energy_delivered_tariff2

Met deze waarden kun je dus een startpunt van verbruikt vast leggen in een variabele en dan blijft je die vergelijken met de huidige waarde. als dat groter is van 10kWh (of een configureerbare warde), doe je iets.

Je wilt dit device zelf iets actief laten doen? (in de zin van een pinnetje hoog of laag maken, of een seriële string sturen?)
Lijkt me redelijk haalbaar.

Hallo Stijnos,

Ja daar heb ik zelf al geen verstand van. Ik kan prima iets maken in de setup en de loop maar zo'n code als dit met zoveel tbbladen gaat me te ver, Wel heb ik hem draaiend gekregen en ben er erg tevreden mee.

Ik wil inderdaad een pin een seconden hoog hebben als er iets gebeurd.

Dit gaat me echt te ver vandaag de vraag of iemand mij zou kunnen helpen.

Stijnos

Golden Member

volgens mij is het bij arduino zo dat de scope van alle ino files gewoon hetzelfde is, maar dat weet nik niet zeker meer. Ben niet zo'n arduino gebruiker.
Het zou heel goed kunnen dat die DSMRdata gewoon in de loop functie beschikbaar is.
Je kan dan daar die info gebruiken en een klein rekensommetje doen, waar je op basis van die som een pin zet.

Ik heb helaas net een pcb order de deur uit gedaan, anders had ik dit printje even mee besteld, ook wel leuk voor thuis inderdaad.

Op 9 december 2021 15:46:30 schreef Stijnos:
volgens mij is het bij arduino zo dat de scope van alle ino files gewoon hetzelfde is, maar dat weet nik niet zeker meer. Ben niet zo'n arduino gebruiker.
Het zou heel goed kunnen dat die DSMRdata gewoon in de loop functie beschikbaar is.
Je kan dan daar die info gebruiken en een klein rekensommetje doen, waar je op basis van die som een pin zet.

Ik heb helaas net een pcb order de deur uit gedaan, anders had ik dit printje even mee besteld, ook wel leuk voor thuis inderdaad.

Ja dat weet ik dus echt niet. En hoe ik die DSMRdata daarin zou moeten krijgen al helemaal niet.
Ik gebruik nu een lolin bordje, ik heb genoeg van dat spul liggen gelukkig.

Ik zou om te beginnen dit invoegen op regel 49 van processTelegram.ino


if (minute(actT) != minute(newT)) {
    writeToSysLog("we have a new minute:%02d", minute(newT));
    writeToSysLog("we have used:%d", DSMRdata.energy_delivered_tariff1 + DSMRdata.energy_delivered_tariff2);

    if ( ( DSMRdata.energy_delivered_tariff1 +
           DSMRdata.energy_delivered_tariff2 ) % 10000 < 133 ) {
       writeToSysLog("we had 10kWh");
    }
}

% 10000 < 133 is een snelle hack.
Van xx0000 tot xx0133 Wh is dit geldig dus je krijgt bij 50Watt gebruik 2 uur lang "We had 10kWh" en bij meer dan 8000watt kan je de 10000 missen omdat dit alleen op de minuut loopt.

Dit kan je later oplossen door bijvoorbeeld de bovenste if statement weg te halen. Een pin output toevoegen is de volgende stap.

Op 10 december 2021 23:47:05 schreef K7Jz:
Ik zou om te beginnen dit invoegen op regel 49 van processTelegram.ino


if (minute(actT) != minute(newT)) {
    writeToSysLog("we have a new minute:%02d", minute(newT));
    writeToSysLog("we have used:%d", DSMRdata.energy_delivered_tariff1 + DSMRdata.energy_delivered_tariff2);

    if ( ( DSMRdata.energy_delivered_tariff1 +
           DSMRdata.energy_delivered_tariff2 ) % 10000 < 133 ) {
       writeToSysLog("we had 10kWh");
    }
}

% 10000 < 133 is een snelle hack.
Van xx0000 tot xx0133 Wh is dit geldig dus je krijgt bij 50Watt gebruik 2 uur lang "We had 10kWh" en bij meer dan 8000watt kan je de 10000 missen omdat dit alleen op de minuut loopt.

Dit kan je later oplossen door bijvoorbeeld de bovenste if statement weg te halen. Een pin output toevoegen is de volgende stap.

Bedankt dat je mee wilt kijken!

Als ik die daar invoeg krijg ik deze melding: invalid operands of types 'float' and 'int' to binary 'operators%'

Sorry ik draai dit uit mijn hoofd en niet door een compiler
Les 1 bij debuggen: strippen. Strip mijn regels tot het wel werkt. Al krijg krijg je er slechts writeToSysLog("hoi"); aan de praat. En dan weer opbouwen.

Probeer eens:


if (minute(actT) != minute(newT)) {
    writeToSysLog("we have a new minute:%02d", minute(newT));
    writeToSysLog("we have used:%d", DSMRdata.energy_delivered_tariff1 + DSMRdata.energy_delivered_tariff2);

    if ( (int)((DSMRdata.energy_delivered_tariff1 +
           DSMRdata.energy_delivered_tariff2)*1000 ) % 10000 < 133 ) {
       writeToSysLog("we had 10kWh");
    }
}

Of gewoon


if (minute(actT) != minute(newT)) {
    writeToSysLog("we have a new minute:%02d", minute(newT));
    writeToSysLog("we have used:%d", DSMRdata.energy_delivered_tariff1 + DSMRdata.energy_delivered_tariff2);

  
}

[Bericht gewijzigd door K7Jz op zaterdag 11 december 2021 20:44:23 (19%)

Stijnos

Golden Member

Misschien nog extra set haakjes t
Om die int cast en de module 10000?

Op 11 december 2021 20:43:01 schreef K7Jz:
Sorry ik draai dit uit mijn hoofd en niet door een compiler
Les 1 bij debuggen: strippen. Strip mijn regels tot het wel werkt. Al krijg krijg je er slechts writeToSysLog("hoi"); aan de praat. En dan weer opbouwen.

Probeer eens:


if (minute(actT) != minute(newT)) {
    writeToSysLog("we have a new minute:%02d", minute(newT));
    writeToSysLog("we have used:%d", DSMRdata.energy_delivered_tariff1 + DSMRdata.energy_delivered_tariff2);

    if ( (int)((DSMRdata.energy_delivered_tariff1 +
           DSMRdata.energy_delivered_tariff2)*1000 ) % 10000 < 133 ) {
       writeToSysLog("we had 10kWh");
    }
}

Of gewoon


if (minute(actT) != minute(newT)) {
    writeToSysLog("we have a new minute:%02d", minute(newT));
    writeToSysLog("we have used:%d", DSMRdata.energy_delivered_tariff1 + DSMRdata.energy_delivered_tariff2);

  
}

Deze compiled inderdaad, ik snap alleen je berekening niet.
Stel als ik bij 1kwh verbruik een pin hoog wil hebben?

10Kwh gaat wel even duren namelijk :)

En waar schrijf je de "we had 10KWh" naartoe? naar de serial?

Op 11 december 2021 21:21:19 schreef Stijnos:
Misschien nog extra set haakjes t
Om die int cast en de module 10000?

Hallo Stijnos,

Ik wil dit weer oppakken. zou jij nog mee willen kijken?

Stijnos

Golden Member

ja hoor, maar ik weet even niet meer waar het om ging, hoe ver je bent en wat momenteel het probleem nog is. Praat ons even bij. Geen zin om alles weer terug te gaan lezen :)

Ik heb deze logger draaien op een ESP8266 om mijn slimme meter uit te lezen.
http://https://github.com/mrWheel/DSMRloggerAPI

Dat uitlezen werkt allemaal perfect. Ik dus een actie gaan doen als er bv 1 kwh bijgekomen is qua verbruik. Al is het maar dat het in de serial komt te staan, dan kan ik dat wel weer vertalen naar een output die hoog gaat bijvoorbeeld.

In een ractie hierboven had je al een reactie gegeven om dit in de tab processTelegram.ino te doen.

Jij gaf dit aan als voorbeeld:

if (minute(actT) != minute(newT)) {
    writeToSysLog("we have a new minute:%02d", minute(newT));
    writeToSysLog("we have used:%d", DSMRdata.energy_delivered_tariff1 + DSMRdata.energy_delivered_tariff2);

    if ( (int)((DSMRdata.energy_delivered_tariff1 +
           DSMRdata.energy_delivered_tariff2)*1000 ) % 10000 < 133 ) {
       writeToSysLog("we had 10kWh");
    }
}
Of gewoon

c code:


if (minute(actT) != minute(newT)) {
    writeToSysLog("we have a new minute:%02d", minute(newT));
    writeToSysLog("we have used:%d", DSMRdata.energy_delivered_tariff1 + DSMRdata.energy_delivered_tariff2);

  
}

Deze wordt geschreven naar Syslog? Waar kan ik dat zien?

Stijnos

Golden Member

zoek die functie eens op.
ik denk dat hij het serieel print?
je kan de functies wellicht simpel vervangen door printf ?