×

INDI Library v2.0.7 is Released (01 Apr 2024)

Bi-monthly release with minor bug fixes and improvements

Driver OnStep (LX200 like) for INDI

  • Posts: 48
  • Thank you received: 7
@GENE, @Alain,
Thank you for your suggestion.
I thought the same as you at first.
I checked with the following debug code.
 
    LOGF_DEBUG("### OnStep ltm.tm_isdst: %i", ltm.tm_isdst);
 
    double offset = 0;
    if (getUTFOffset(&offset))
    {
        char utcStr[8] = {0};
        snprintf(utcStr, 8, "%.2f", offset);
        IUSaveText(&TimeT[1], utcStr);
    }
    else
    {
        LOG_WARN("Could not obtain UTC offset from mount!");
        return false;
    }
 
    if (getLocalTime(ctime) == false)
    {
        LOG_WARN("Could not obtain local time from mount!");
        return false;
    }
 
    if (getLocalDate(cdate) == false)
    {
        LOG_WARN("Could not obtain local date from mount!");
        return false;
    }
 
    // To ISO 8601 format in LOCAL TIME!
    char datetime[MAXINDINAME] = {0};
    snprintf(datetime, MAXINDINAME, "%sT%s", cdate, ctime);
 
    LOGF_DEBUG("### OnStep Local DateTime: %s", datetime);
 
    // Now that date+time are combined, let's get tm representation of it.
    if (strptime(datetime, "%FT%T", &ltm) == nullptr)
    {
        LOGF_WARN("Could not process mount date and time: %s", datetime);
        return false;
    }
 
    LOGF_DEBUG("### OnStep after strptime ltm date: %i-%i-%i", ltm.tm_year, ltm.tm_mon, ltm.tm_mday);
    LOGF_DEBUG("### OnStep after strptime ltm time: %i:%i:%i", ltm.tm_hour, ltm.tm_min, ltm.tm_sec);
    LOGF_DEBUG("### OnStep after strptime ltm.tm_isdst: %i", ltm.tm_isdst);
 
    // Get local time epoch in UNIX seconds
    time_epoch = mktime(&ltm);
 
    LOGF_DEBUG("OnStep Local DateTime time_epoch: %i", time_epoch);
 
    // LOCAL to UTC by subtracting offset.
    time_epoch -= static_cast<int>(offset * 3600.0);
 


The log when ltm is not initialized is as follows.
 LX200 OnStep : "[DEBUG] ### OnStep ltm.tm_isdst: 1074791425 "  <<<< wrong value
 LX200 OnStep : "[SCOPE] CMD <:GG#> "
 LX200 OnStep : "[SCOPE] RES <+09> "
 LX200 OnStep : "[SCOPE] VAL [9] "
 LX200 OnStep : "[SCOPE] CMD <:GL#> "
 LX200 OnStep : "[SCOPE] RES <04:08:07> "
 LX200 OnStep : "[SCOPE] VAL [4.13528] "
 LX200 OnStep : "[SCOPE] <getCalendarDate> "
 LX200 OnStep : "[SCOPE] CMD <:GC#> "
 LX200 OnStep : "[SCOPE] RES <03/23/22> "
 LX200 OnStep : "[DEBUG] ### OnStep Local DateTime: 2022-03-23T04:08:07 "   <<<< OnStep Local
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm date: 122-2-23 "     <<<< OK
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm time: 4:8:7 "        <<<< OK
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm.tm_isdst: 1074791425 "     <<<< wrong value
 LX200 OnStep : "[DEBUG] OnStep Local DateTime time_epoch: -1 "       <<<< Error
 LX200 OnStep : "[DEBUG] Mount controller UTC Time: 1970-01-01T17:59:59 "    <<<< failed
 LX200 OnStep : "[DEBUG] Mount controller UTC Offset: -9.00 "
 Setting UTC time from device: "LX200 OnStep" "木 11 17:59:59 1970 GMT"    <<<< failed
->>>>>> snprintf(datetime, MAXINDINAME, "%sT%s", cdate, ctime);
 
 LX200 OnStep : "[DEBUG] ### OnStep Local DateTime: 2022-03-23T04:08:07 "   <<<< OnStep Local

snprintf returns the correct value "2022-03-23T04: 08: 07".

->>>>>> if (strptime(datetime, "%FT%T", &ltm) == nullptr) 
 
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm date: 122-2-23 "     <<<< OK
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm time: 4:8:7 "        <<<< OK
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm.tm_isdst: 1074791425 "     <<<< wrong value
 LX200 OnStep : "[DEBUG] OnStep Local DateTime time_epoch: -1 "       <<<< Error

The date and time split by strptime is also done correctly, but time_epoch is an error (-1).
strptime doesn't seem to recalculate ltm.tm_isdst.
tm_isdst remains an uninitialized wrong value, and processing result of mktime returns an error.


When ltm is initialized, it is as follows.
 LX200 OnStep : "[DEBUG] ### OnStep ltm.tm_isdst: 0 "  <<<< initialized value
 LX200 OnStep : "[SCOPE] CMD <:GG#> "
 LX200 OnStep : "[SCOPE] RES <+09> "
 LX200 OnStep : "[SCOPE] VAL [9] "
 LX200 OnStep : "[SCOPE] CMD <:GL#> "
 LX200 OnStep : "[SCOPE] RES <04:11:37> "
 LX200 OnStep : "[SCOPE] VAL [4.19361] "
 LX200 OnStep : "[SCOPE] <getCalendarDate> "
 LX200 OnStep : "[SCOPE] CMD <:GC#> "
 LX200 OnStep : "[SCOPE] RES <03/23/22> "
 LX200 OnStep : "[DEBUG] ### OnStep Local DateTime: 2022-03-23T04:11:37 "   <<<< OnStep Local
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm date: 122-2-23 "     <<<< OK
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm time: 4:11:37 "      <<<< OK
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm.tm_isdst: 0 "  <<<< initialized value
 LX200 OnStep : "[DEBUG] OnStep Local DateTime time_epoch: 1647976297 "       <<<< OK
 LX200 OnStep : "[DEBUG] Mount controller UTC Time: 2022-03-23T13:11:37 "    <<<< OK
 LX200 OnStep : "[DEBUG] Mount controller UTC Offset: -9.00 "
 Setting UTC time from device: "LX200 OnStep" "水 323 13:11:37 2022 GMT"    <<<< OK

->>>>>> snprintf(datetime, MAXINDINAME, "%sT%s", cdate, ctime);
 
 LX200 OnStep : "[DEBUG] ### OnStep Local DateTime: 2022-03-23T04:11:37 "   <<<< OnStep Local

snprintf returns the correct value "2022-03-23T04:11:37".

->>>>>> if (strptime(datetime, "%FT%T", &ltm) == nullptr) 
 
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm date: 122-2-23 "     <<<< OK
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm time: 4:11:37 "      <<<< OK
 LX200 OnStep : "[DEBUG] ### OnStep after strptime ltm.tm_isdst: 0 "  <<<< initialized value
 LX200 OnStep : "[DEBUG] OnStep Local DateTime time_epoch: 1647976297 "       <<<< OK
 LX200 OnStep : "[DEBUG] Mount controller UTC Time: 2022-03-23T13:11:37 "    <<<< OK

The date and time decomposition by strptime is also done correctly, and time_epoch is the correct value.

I think how mktime handles wrong tm_isdst depends on the implementation system (H / W, OS, lib, etc).
strptime manpage NOTES also describes the initialization of the tm structure.
man7.org/linux/man-pages/man3/strptime.3.html
Because of these, I think that ltm should be initialized.
You can try set the wrong value in ltm.tm_isdst.
Is there any other way to check?
The following user(s) said Thank You: Alain Zwingelstein
Last edit: 2 years 1 month ago by norikyu.
2 years 1 month ago #81657

Please Log in or Create an account to join the conversation.

  • Posts: 48
  • Thank you received: 7
sorry, my system is

INDI Server:
Raspberry Pi 4
Linux ubuntu 5.4.0-1055-raspi
indiserver 1.9.5

OnStep 4.24q

KStars 3.5.8 Stable
2 years 1 month ago #81658

Please Log in or Create an account to join the conversation.

  • Posts: 276
  • Thank you received: 52
@NORIKYU

Detective work!

But not convinced is root cause, see the code snippet below, the results I get are:
RAW ISDST = 66428
SEC = 7
MIN = 8
HR = 4
DAY = 23
MON = 2
YR = 122
DWK = 3
DYR = 81
DST = 66428
ISDST after strptime = 66428
ISDST after clobber >0 1074791425
Got MKTIME = 1648022887
ISDST after clobber =0 = 0
Got MKTIME = 1648026487 (Notice is 3600 seconds ahead of first)
ISDST after clobber < 0 -1074791425
Got MKTIME = 1648026487 (Notice is 3600 seconds ahead of first)

isdst has three states, <0, 0, >0

Could you try the below on your system?

========== code snippet =================
#include <stdio.h>
#include <time.h>
int main(void)
{
struct tm ltm;
char daybuf[20];
//char *mytime = "2022-03-23T04:11:37";
char *mytime = "2022-03-23T04:08:07";
printf("RAW ISDST = %d\n",ltm.tm_isdst);
strptime(mytime, "%FT%T", &ltm);
printf("SEC = %d\n",ltm.tm_sec); /* Seconds. [0-60] (1 leap second) */
printf("MIN = %d\n",ltm.tm_min); /* Minutes. [0-59] */
printf("HR = %d\n",ltm.tm_hour); /* Hours. [0-23] */
printf("DAY = %d\n",ltm.tm_mday); /* Day. [1-31] */
printf("MON = %d\n",ltm.tm_mon); /* Month. [0-11] */
printf("YR = %d\n",ltm.tm_year); /* Year - 1900. */
printf("DWK = %d\n",ltm.tm_wday); /* Day of week. [0-6] */
printf("DYR = %d\n",ltm.tm_yday); /* Days in year.[0-365] */
printf("DST = %d\n",ltm.tm_isdst); /* DST. [-1/0/1]*/

printf("ISDST after strptime = %d\n",ltm.tm_isdst);
//clobber isdst
ltm.tm_isdst = 1074791425;
printf("ISDST after clobber >0 %d\n",ltm.tm_isdst);
printf("Got MKTIME = %d\n",mktime(&ltm));
ltm.tm_isdst = 0;
printf("ISDST after clobber =0 = %d\n",ltm.tm_isdst);
printf("Got MKTIME = %d\n",mktime(&ltm));
ltm.tm_isdst = -1074791425;
printf("ISDST after clobber < 0 %d\n",ltm.tm_isdst);
printf("Got MKTIME = %d\n",mktime(&ltm));
}

======================================
2 years 1 month ago #81663

Please Log in or Create an account to join the conversation.

  • Posts: 48
  • Thank you received: 7
@GENE
Thank you for your advice.
I have tried your code.
RAW ISDST = -1309029128
SEC = 7
MIN = 8
HR = 4
DAY = 23
MON = 2
YR = 122
DWK = 3
DYR = 81
DST = -1309029128
ISDST after strptime = -1309029128
ISDST after clobber >0 1074791425
Got MKTIME = -1
ISDST after clobber =0 = 0
Got MKTIME = 1647976087
ISDST after clobber < 0 -1074791425
Got MKTIME = 1647976087
The time zone is Asia/Tokyo. There is no daylight saving time.
# timedatectl
               Local time: 木 2022-03-24 08:43:06 JST
           Universal time: 水 2022-03-23 23:43:06 UTC
                 RTC time: n/a
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
When tm_isdst is> 0, the result is different from yours, so I changed the time zone and tried it.
Change the time zone to US/Central, which is daylight saving time.
# sudo timedatectl set-timezone US/Central
               Local time: 水 2022-03-23 18:56:44 CDT
           Universal time: 水 2022-03-23 23:56:44 UTC
                 RTC time: n/a
                Time zone: US/Central (CDT, -0500)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
RAW ISDST = -1615921928
SEC = 7
MIN = 8
HR = 4
DAY = 23
MON = 2
YR = 122
DWK = 3
DYR = 81
DST = -1615921928
ISDST after strptime = -1615921928
ISDST after clobber >0 1074791425
Got MKTIME = 1648026487
ISDST after clobber =0 = 0
Got MKTIME = 1648030087
ISDST after clobber < 0 -1074791425
Got MKTIME = 1648030087

It seems to be related to time zone.
You can try setting the time zone to Asia/Tokyo.
Any ideas to fix this problem?

My test system is as follows.
Raspberry Pi 4
Linux ubuntu 5.4.0-1055-raspi
GLIBC 2.31-0ubuntu9.7
gcc (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0

Please tell me your time zone, OS, compiler, etc. you are using.
2 years 1 month ago #81672

Please Log in or Create an account to join the conversation.

  • Posts: 276
  • Thank you received: 52
@norikyu,

Yes, TZ is the key, Tokyo stopped DST in 1951 from what I can tell so passing in a positive value in tm_isdst should respond with a -1.
from man mktime
" The value specified in the tm_isdst field informs mktime() whether or not daylight
saving time (DST) is in effect for the time supplied in the tm structure: a positive value means DST
is in effect; zero means that DST is not in effect; and a negative value means that mktime() should
(use timezone information and system databases to) attempt to determine whether DST is in effect at
the specified time."

The question now may be, since this is time as read from the scope, is the scope handling the DST offset itself by way of getUTFOffset(&offset)
If yes, then isdst should be set 0 and the GMT offset used from the scope

The memset of 0 on tm does this nicely, slightly more efficient may be setting tm_isdst = 0 directly prior to calling mktime. :-)

Gene
2 years 1 month ago #81693

Please Log in or Create an account to join the conversation.

  • Posts: 48
  • Thank you received: 7
@GENE
Hi
I'm sorry I'm not good at English.
I know that Tokyo is not DST area, I live in.I think the current code is getting the wrong time on other TZ as well.

strptime, ctime and cdate are fine.
strptime function is described in the man page as "tm should be initialized before the call.".
I think that ltm should be initialized to avoid troubles.
And it suggests to set tm_isdst=0 before calling mktime.
is this all right?
2 years 1 month ago #81697

Please Log in or Create an account to join the conversation.

  • Posts: 276
  • Thank you received: 52
@NORIKYU

Yes on the setting of tm_isdst=0 !
Sorry for the long text in previous post!

Gene
2 years 1 month ago #81702

Please Log in or Create an account to join the conversation.

  • Posts: 452
  • Thank you received: 71
@Gene / @ Norikyu,

good to see you make progress on the topic.
May be we could also involve Jasem because he has the overview over the whole project as it impacts many drivers.

Thank you to you both
2 years 1 month ago #81757

Please Log in or Create an account to join the conversation.

  • Posts: 48
  • Thank you received: 7
@Alain
I'm sorry it took a long time.
I have attached a patch suggestion.
I tested lx200_OnStep, but no other drivers. (I don't have an other mount.)
I think the lx200 series patch is okay.
Other drivers need to be tested to see if they work fine.
Thank you.
The following user(s) said Thank You: Alain Zwingelstein
2 years 3 weeks ago #81930
Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 60
  • Thank you received: 2
So the Utc error in Ekos is gone?
2 years 3 weeks ago #81934

Please Log in or Create an account to join the conversation.

  • Posts: 452
  • Thank you received: 71
@Norikyu, @Michael,

Utc error in Ekos is not yet gone, Norikyu just proposed a patch and he tested it against OnStep.
To include the change into Indi Master a pull request must be issued.
Before doing this some additional steps need to be doen:
- change revision for each modified driver
- change drivers.xml for each modified driver
- check build and drivers functions
and then issue the pull request

so will take some time.

I propose to do it but if anybody volunteers, he is welcome!
2 years 3 weeks ago #81950

Please Log in or Create an account to join the conversation.

  • Posts: 452
  • Thank you received: 71
All fixes as per Norikyu pacth are included on github.com/azwing/indi
All test done as simulation except OnStep, pull request will be issued
impacted code:
drivers/telescope/ioptronHC8406.cpp
drivers/telescope/lx200_OnStep.cpp
drivers/telescope/lx200_TeenAstro.cpp
drivers/telescope/lx200pulsar2.cpp
drivers/telescope/lx200telescope.cpp
drivers/telescope/rainbow.cpp
tools/evalINDI.c
2 years 3 weeks ago #81952

Please Log in or Create an account to join the conversation.

Time to create page: 1.417 seconds