Tm value to hour minute and seconds, HOW?

Time after time (no pun intended) I have trouble understanding the time related stuff with the arduino. I really tried hard and I spent (wasted) uncountable hours trying to get it.

Question:

[{"tm":1668701337,"net": 100014.077,"pwr": 515,"ts0":1668699585,"cs0": 172.986,"ps0": 0}]

Above Json output is from my Youless device which gets for example the power used in our house, power generated by our solar array and totals.

As you can see, also a TIME variable 'tm' is being sent and all I want to do is to get the HOUR/MIN/SEC value from the parsed tm value to reset a counter a midnight so I can display the solar array generated power for that day.

The only darn thing I need is the time extracted from the mysterious tm value.

THANK YOU for any help!

Not needed but here's a raw sketch:

#include <Arduino.h>

#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include "Credentials.h"
// display library
#include <LedControl.h>
// time
#include <time.h>

// Youless readout refresh delay in SECONDS
#define REFRESH_DELAY 2

//----------------------------------------------------------------------------
// display stuff
/*
 PIN connections for LedControl
 Maxim 7221 DataIn > Wemos D1 pin D7 (MOSI)
 Maxim 7221 CLK    > Wemos D1 pin D5 (CLK)
 Maxim 7221 CS/LOAD> Wemos D1 pin D0 (CS)
 */
// DataIn, CLK, LOAD, nr of displays
#define Maxim_DATA D7
#define Maxim_CLK D5
#define Maxim_CS D0
#define Maxim_NR_OF_DISPLAYS 1

LedControl lc = LedControl(Maxim_DATA, Maxim_CLK, Maxim_CS, Maxim_NR_OF_DISPLAYS);

/* we always wait a bit between updates of the display */
unsigned long delaytime = 250;
//----------------------------------------------------------------------------

// Your access point SSID
const char *ssid = WIFI_SSID;
// Your access point password
const char *password = WIFI_PASSWORD;
// Your Youless IP
String serverName = "http://192.168.178.109";

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
unsigned long timerDelay = REFRESH_DELAY * 1000;

void setup()
{
  Serial.begin(115200);
  //---display stuff-----------------------------------------------------------
  // display stuff
  //
  // The MAX72XX is in power-saving mode on startup, so do a wakeup call
  lc.shutdown(0, false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0, 2);
  /* and clear the display */
  lc.clearDisplay(0);
  //---------------------------------------------------------------------------

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());

  Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}

void loop()
{
  // Send an HTTP POST request depending on timerDelay
  if ((millis() - lastTime) > timerDelay)
  {
    // Check WiFi connection status
    if (WiFi.status() == WL_CONNECTED)
    {
      WiFiClient client;
      HTTPClient http;

      String serverPath = serverName + "/e";

      // Your Domain name with URL path or IP address with path
      http.begin(client, serverPath.c_str());

      // If you need Node-RED/server authentication, insert user and password below
      // http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");

      // Send HTTP GET request
      int httpResponseCode = http.GET();

      if (httpResponseCode > 0)
      {
        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);
        String payload = http.getString();
        Serial.println(payload);

        //==============================================================================================================================
        // Stream& input;

        StaticJsonDocument<192> doc;

        DeserializationError error = deserializeJson(doc, payload);

        if (error)
        {
          Serial.print(F("deserializeJson() failed: "));
          Serial.println(error.f_str());
          return;
        }

        JsonObject root_0 = doc[0];
        long yl_tm = root_0["tm"];     // 1668621075
        double yl_net = root_0["net"]; // 100002.933
        int yl_pwr = root_0["pwr"];    // 388
        long yl_ts0 = root_0["ts0"];   // 1668612963
        float yl_cs0 = root_0["cs0"];  // 172.115
        int yl_ps0 = root_0["ps0"];    // 0

        // display PV
        // convert the numbers into digits
        int pvDigit3 = (yl_ps0 / 1000) % 10;
        int pvDigit2 = (yl_ps0 / 100) % 10;
        int pvDigit1 = (yl_ps0 / 10) % 10;
        int pvDigit0 = (yl_ps0 % 10);
        // remove leading zero's
        lc.setChar(0, 7, (yl_ps0 < 1000 ? ' ' : pvDigit3), false);
        lc.setChar(0, 6, (yl_ps0 < 100 ? ' ' : pvDigit2), false);
        lc.setChar(0, 5, (yl_ps0 < 10 ? ' ' : pvDigit1), false);
        lc.setChar(0, 4, pvDigit0, false);

        // display power
        // convert the numbers into digits
        int pwrDigit3 = (yl_pwr / 1000) % 10;
        int pwrDigit2 = (yl_pwr / 100) % 10;
        int pwrDigit1 = (yl_pwr / 10) % 10;
        int pwrDigit0 = (yl_pwr % 10);
        // remove leading zero's
        lc.setChar(0, 3, (yl_pwr < 1000 ? ' ' : pwrDigit3), false);
        lc.setChar(0, 2, (yl_pwr < 100 ? ' ' : pwrDigit2), false);
        lc.setChar(0, 1, (yl_pwr < 10 ? ' ' : pwrDigit1), false);
        lc.setChar(0, 0, pwrDigit0, false);


        //==============================================================================================================================
      }
      else
      {
        Serial.print("Error code: ");
        Serial.println(httpResponseCode);
      }
      // Free resources
      http.end();
    }
    else
    {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

/* 
time zones:
https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
 */

You seem to have it in....

I don't understand what "time extracted" means, can you describe your desired outcome? FWIW, yl_tm % 60 will give you remaining seconds.

1 Like

Thank you for your reply and sorry for my incomplete question...

My goal is to extract from the yl_tm variable (which represent the time stamp of the data gathered by the Youless device) the HOUR, MINUTE and SECOND

With that information I can reset a counter at midnight.

That part is actually Unix or Epoch time. I believe the time library will convert it for you. Converting 1668701337 to unix time I get Thu Nov 17 2022 11:08:57 UTC-0500 (Eastern Standard Time) the EST part is from the current time zone the computer is in. That time is to the second, much more accurate then you want but just drop the seconds if you do not use them.

To check your work you can use this link to convert: Unix time converter - Time.is

1 Like

you could convert your epoch to a tm and than use the data elements of tm


that is what I need but I don't know how to do that... I spent (again) the last hours to browse the forums and internet for an example but I cannot find a single one.

I used the example you deleted just now but that does not work:

   long yl_tm = 1679101337;
        time_t now; // epoch
        tm tm;      // a tm structure
        localtime_r(&now, &tm);

        Serial.print("year:");
        Serial.print(tm.tm_year + 1900); // years since 1900
        Serial.print("\tmonth:");
        Serial.print(tm.tm_mon + 1); // January = 0 (!)
        Serial.print("\tday:");
        Serial.print(tm.tm_mday); // day of month
        Serial.print("\thour:");
        Serial.print(tm.tm_hour); // hours since midnight  0-23
        Serial.print("\tmin:");
        Serial.print(tm.tm_min); // minutes after the hour  0-59
        Serial.print("\tsec:");
        Serial.print(tm.tm_sec); // seconds after the minute  0-61*

therefore I deleted it.

something messes up the year on an Arduino ... can't find it:


#include <time.h>

void doSomething()
{
  unsigned long yl_tm = 1668701337;
  time_t now = yl_tm; //epoch
  tm tm; // a tm structure
  //localtime_r(&now, &tm);
  gmtime_r(&now, &tm);

  Serial.print("year:");
  Serial.print(tm.tm_year + 1900);  // years since 1900
  Serial.print("\tmonth:");
  Serial.print(tm.tm_mon + 1);      // January = 0 (!)
  Serial.print("\tday:");
  Serial.print(tm.tm_mday);         // day of month
  Serial.print("\thour:");
  Serial.print(tm.tm_hour);         // hours since midnight  0-23
  Serial.print("\tmin:");
  Serial.print(tm.tm_min);          // minutes after the hour  0-59
  Serial.print("\tsec:");
  Serial.print(tm.tm_sec);          // seconds after the minute  0-61*


}
void setup() {
  Serial.begin(115200);
  doSomething();
}

void loop() {
}

year:2052 month:11 day:16 hour:16 min:8 sec:57

off by 30 years ...

1 Like

@noiasca
That did the trick, CAN'T THANK YOU ENOUGH!!

HTTP Response code: 200
[{"tm":1668708175,"net": 100015.723,"pwr": 1131,"ts0":1668699585,"cs0": 172.986,"ps0": 0}]                                                               
year:2022       month:11        day:17  hour:18 min:2   sec:55

modified code which tested succesfully

        JsonObject root_0 = doc[0];
        // long yl_tm = root_0["tm"];     // 1668621075
        unsigned long yl_tm = root_0["tm"];     // 1668621075
        double yl_net = root_0["net"]; // 100002.933
        int yl_pwr = root_0["pwr"];    // 388
        long yl_ts0 = root_0["ts0"];   // 1668612963
        float yl_cs0 = root_0["cs0"];  // 172.115
        int yl_ps0 = root_0["ps0"];    // 0

        //unsigned long yl_tm = 1668701337;
        time_t now = yl_tm; // epoch
        tm tm;              // a tm structure
        // localtime_r(&now, &tm);
        gmtime_r(&now, &tm);

        Serial.print("year:");
        Serial.print(tm.tm_year + 1900); // years since 1900
        Serial.print("\tmonth:");
        Serial.print(tm.tm_mon + 1); // January = 0 (!)
        Serial.print("\tday:");
        Serial.print(tm.tm_mday); // day of month
        Serial.print("\thour:");
        Serial.print(tm.tm_hour); // hours since midnight  0-23
        Serial.print("\tmin:");
        Serial.print(tm.tm_min); // minutes after the hour  0-59
        Serial.print("\tsec:");
        Serial.print(tm.tm_sec); // seconds after the minute  0-61*

so on a 32 bit controller it works ?

Well, I use a Wemos D1 R2 mini 8266... Yes I does! :smiley:

I have several laying around, want to use these before buying new ones...

ok.

P.S.: If you want to test another MAX7219 lib, you might try mine.

https://werner.rothschopf.net/201904_arduino_ledcontrol_max7219.htm

instead of

        int pvDigit3 = (yl_ps0 / 1000) % 10;
        int pvDigit2 = (yl_ps0 / 100) % 10;
        int pvDigit1 = (yl_ps0 / 10) % 10;
        int pvDigit0 = (yl_ps0 % 10);
        lc.setChar(0, 7, (yl_ps0 < 1000 ? ' ' : pvDigit3), false);
        lc.setChar(0, 6, (yl_ps0 < 100 ? ' ' : pvDigit2), false);
        lc.setChar(0, 5, (yl_ps0 < 10 ? ' ' : pvDigit1), false);

in one line:

        lc.print(yl_ps0);
1 Like

O wow, thank you, will do that!!

I love 7 segement displays, used them for my DCF77 Analyzer Clock

1 Like

https://werner.rothschopf.net/201904_arduino_ledcontrol_max7219.htm
https://werner.rothschopf.net/201909_arduino_ht16k33.htm
https://werner.rothschopf.net/202005_arduino_neopixel_display_en.htm

well, I think you get the point :wink:

2 Likes

saved your amazing website, many thanks!
Busy reading about your improved Ledcontrol lib... :clap:

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.