I'm using DLMS.c and I loaded the clock object from the meter. In this object, the time attribute has the local time of the meter but I want to get the UTC Unix time value.
The time zone and daylight saving deviation are present in the clock object but they are not loaded into the time object.
My solution to this was to create the function clock_getTime that fills a time object with the time and deviation from the clock object:
int clock_getTime(gxClock* object, gxtime* value)
{
*value = object->time;
value->deviation = 0;
value->status = 0;
if (object->timeZone != 0 && object->timeZone != -32768) //-32768 = 0x8000
{
value->deviation = object->timeZone;
}
//If DST is enabled for the meter
if ((object->status & DLMS_CLOCK_STATUS_DAYLIGHT_SAVE_ACTIVE) != 0)
{
#ifdef DLMS_USE_UTC_TIME_ZONE
value->deviation += object->deviation;
#else
value->deviation -= object->deviation;
#endif //DLMS_USE_UTC_TIME_ZONE
value->status |= DLMS_CLOCK_STATUS_DAYLIGHT_SAVE_ACTIVE;
}
return 0;
}
With this function I just need to call the following code to get the UTC Unix time:
gxClock clock;
// Read meter clock
gxtime time;
clock_getTime(&clock, &time);
time_toUTC(&time);
utcUnix = time_toUnixTime2(&time);
The deviation is saved for date-time value so you don't need the clock object for that.
You can convert gxtime to Unix time with time_toUnixTime2 -method.
gxtime is saving timezone, so the client and the meter don't need to be at the same time zone.
Have you tried to use time_toString2 to print the date-time?
Define DLMS_USE_EPOCH_TIME and time is saved to uint32_t value instead of struct tm.
Can you paste hex trace from meter time so I can check it?
This is the print of the clock object:
Index: 2 Value: 01/11/2022 14:35:41
Index: 3 Value: 0
Index: 4 Value: 0
Index: 5 Value: 03/LASTDAY/* 01:00:00
Index: 6 Value: 10/LASTDAY/* 02:00:00
Index: 7 Value: 60
Index: 8 Value: 1
Index: 9 Value: 1
and the RAW from clock: 09 0c 07 e6 01 0b 02 0e 23 29 00 80 00 00
If I change the time of the Meter to Daylight Saving I get:
Index: 2 Value: 04/11/2022 14:35:46
Index: 3 Value: 0
Index: 4 Value: 128
Index: 5 Value: 03/LASTDAY/* 01:00:00
Index: 6 Value: 10/LASTDAY/* 02:00:00
Index: 7 Value: 60
Index: 8 Value: 1
Index: 9 Value: 1
and the RAW from clock: 09 0c 07 e6 04 0b 01 0e 23 2e 00 80 00 80
The DST is added for deviation and because of that if the deviation is not used the DTS is not used.
I really understand your idea, but the general idea of why deviation should be on the date-time is because that date-time value is saved for the profile generic object. It's not a good thing to modify the date-time with clock value because someone might change the time-zone or deviation for the clock object after the date-time is added for the profile generic buffer. This will cause that date-time is not correct.
Hi,
Hi,
The deviation is saved for date-time value so you don't need the clock object for that.
You can convert gxtime to Unix time with time_toUnixTime2 -method.
BR,
Mikko
Hi,
Hi,
time_toUnixTime2 isn't working for me and I think I know why.
time_toUnixTime2 uses mktime, which takes local time and converts to unix epoch
https://www.cplusplus.com/reference/ctime/mktime/
"Returns the value of type time_t that represents the local time described by the tm structure"
This assumes that the client is in the same timezone as the meter and that the client timezone is configured.
In my case, the client timezone is not configured.
Hi,
Hi,
gxtime is saving timezone, so the client and the meter don't need to be at the same time zone.
Have you tried to use time_toString2 to print the date-time?
Define DLMS_USE_EPOCH_TIME and time is saved to uint32_t value instead of struct tm.
Can you paste hex trace from meter time so I can check it?
BR,
Mikko
Hi,
Hi,
I was not understanding why you said that "gxtime is saving timezone" but I see now that the date-time octect string has a deviation field.
This is the value of the attribute time from clock object
RAW: 09 0c 07 e6 01 0b 02 0b 14 0a 00 80 00 00
- year: 0x07e6 -> 2022
- month: 0x01 -> January
- day of month: 0x0b -> 11
- day of week: 0x02 -> Tuesday
- hour: 0x0b -> 11
- minute: 0x14 -> 20
- second: 0x0a -> 10
- hundredths of second: 0x00 -> 0
- deviation: 0x8000 -> not specified
- clock status: 0x00 -> OK
The problem is that the Meter is not sending the deviation on the time attribute
Hi,
Hi,
If the meter doesn't include deviation for the date-time it's usually not set for the clock object.
Note! All meters don't support deviation at all.
If the deviation is not set for the date-time, time_toString2 assumes that the meter is in the same time zone as the client.
In your case time_toString2 shows value:
01/11/2022 11:20:10
BR,
Mikko
This is the print of the
This is the print of the clock object:
Index: 2 Value: 01/11/2022 14:35:41
Index: 3 Value: 0
Index: 4 Value: 0
Index: 5 Value: 03/LASTDAY/* 01:00:00
Index: 6 Value: 10/LASTDAY/* 02:00:00
Index: 7 Value: 60
Index: 8 Value: 1
Index: 9 Value: 1
and the RAW from clock: 09 0c 07 e6 01 0b 02 0e 23 29 00 80 00 00
If I change the time of the Meter to Daylight Saving I get:
Index: 2 Value: 04/11/2022 14:35:46
Index: 3 Value: 0
Index: 4 Value: 128
Index: 5 Value: 03/LASTDAY/* 01:00:00
Index: 6 Value: 10/LASTDAY/* 02:00:00
Index: 7 Value: 60
Index: 8 Value: 1
Index: 9 Value: 1
and the RAW from clock: 09 0c 07 e6 04 0b 01 0e 23 2e 00 80 00 80
The Daylight Saving is working:
Before:
Index: 2 Value: 03/27/2022 00:59:26
Index: 3 Value: 0
Index: 4 Value: 0
Index: 5 Value: 03/LASTDAY/* 01:00:00
Index: 6 Value: 10/LASTDAY/* 02:00:00
Index: 7 Value: 60
Index: 8 Value: 1
Index: 9 Value: 1
and the RAW from clock: 09 0c 07 e6 03 1b 07 00 3b 39 00 80 00 00
After:
Index: 2 Value: 03/27/2022 02:00:06
Index: 3 Value: 0
Index: 4 Value: 128
Index: 5 Value: 03/LASTDAY/* 01:00:00
Index: 6 Value: 10/LASTDAY/* 02:00:00
Index: 7 Value: 60
Index: 8 Value: 1
Index: 9 Value: 1
and the RAW from clock: 09 0c 07 e6 03 1b 07 02 00 06 00 80 00 80
As you can see, the time from clock has the deviation not specified but the information is present on the clock object.
the clock_getTime could get the deviation from clock object if the deviation from clock.time is not specified
int clock_getTime(gxClock* object, gxtime* value)
{
*value = object->time;
if(value->deviation == -32768) //-32768 = 0x8000
{
value->deviation = 0;
value->status = 0;
if (object->timeZone != 0 && object->timeZone != -32768) //-32768 = 0x8000
{
value->deviation = object->timeZone;
}
//If DST is enabled for the meter
if ((object->status & DLMS_CLOCK_STATUS_DAYLIGHT_SAVE_ACTIVE) != 0)
{
#ifdef DLMS_USE_UTC_TIME_ZONE
value->deviation += object->deviation;
#else
value->deviation -= object->deviation;
#endif //DLMS_USE_UTC_TIME_ZONE
value->status |= DLMS_CLOCK_STATUS_DAYLIGHT_SAVE_ACTIVE;
}
}
return 0;
}
I don't know if this works for all Meters, have to be tested
Hi,
Hi,
The DST is added for deviation and because of that if the deviation is not used the DTS is not used.
I really understand your idea, but the general idea of why deviation should be on the date-time is because that date-time value is saved for the profile generic object. It's not a good thing to modify the date-time with clock value because someone might change the time-zone or deviation for the clock object after the date-time is added for the profile generic buffer. This will cause that date-time is not correct.
BR,
Mikko