×

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

Bi-monthly release with minor bug fixes and improvements

EQMod snoop "Site Management" from a GPS Driver

  • Posts: 72
  • Thank you received: 21
I’m working to add snoop function on EQMOD driver to update local position and local time from another drivers whose get these information from a GPS via an Arduino module. Like the Astroberry project done on indi_rpi driver Thanks to rkaczorek for the idea.

Today it build to work with my own specific driver.

I think it could nice if this function is going to be integrated in the original EQMod driver. For that and to do a clean job, I think create a kind of “generic” function and publish the definition of the XML items required to send data to EQMod driver.

Sure I’ve to ask if the EQMod maintainer if he would include in the driver itself.

I would like to open the discussion for vector name, elements name, format of value/text and other idea about this topic.
Till now I use these information in my draft:
- Longitude In sexagesimal
- Longitude in sexagesimal
- Elevation in meter
- Date as yyyy-mm-dd
- Time as hh:mm
- IPState to know if the GPS is valid

First think I will change is to use two vectors for GPS Data. One for position data, and second one for Date/Time.

It looks that I program it correctly to have change done in the EQMod driver, but I’m not so familiar with the relations between LST, Julian date, EQ. Coordinates, UTC Time and scope location yet to be sure all changes are implemented.
Any help and support would be welcome.

As I’m not experimented programmers, I hope writing a correct and good usable code..

Here you are my code proposal:

bool EQMod::ISSnoopDevice (XMLEle *root)
/* This function expect that all datas from the GPS are in the same Text Vector
* We expect that the setting of time or position could be selected separatly by the user
* In usual the time is provide quite faster by the GPS than the localisation
* Philippe Besson
* V0.1 - 20th of August 2015
*/

{
time_t t0;
struct tm st={0}, lt={0};
int rc;
double dGpsLon, dGpsLat, dGpsElev;
char year[5], month[3], day [3], hour[3], min[3], sec[3];

// Wich device send the message
//TODO Could be used to do a self registration as subsrider to sent acknwoledgement back!
const char *propDevice = findXMLAttValu(root, "device");
DEBUGF(INDI::Logger::DBG_WARNING, "Received a snoop message from device : %s", propDevice);

/* XML Tag received by the GPS driver
2015-08-17T18:01:02: Date
2015-08-17T18:01:02: Heure GMT
2015-08-17T18:01:02: Altitude (m)
2015-08-17T18:01:02: Latitude
2015-08-17T18:01:02: Longitude
2015-08-17T18:01:02: Satellites
2015-08-17T18:01:02: Antenne
*/

const char *propState = findXMLAttValu(root, "state");

// GPS Value OK? Defined IPS_OK state of vector as GPSFix
if (!strcmp(propState, "Idle")) gpsdata.state = IPS_IDLE;
else if (!strcmp(propState, "Ok")) gpsdata.state = IPS_OK;
else if (!strcmp(propState, "Busy")) gpsdata.state = IPS_BUSY;
else if (!strcmp(propState, "Alert")) gpsdata.state = IPS_ALERT;

DEBUGF(INDI::Logger::DBG_DEBUG, "GPS State received : %s", propState);
DEBUGF(INDI::Logger::DBG_DEBUG, "GPS State received value : %d", gpsdata.state);

const char *propName = findXMLAttValu(root, "name");

if (!strcmp(propName, "GPS-SYNC"))
{
DEBUGF(INDI::Logger::DBG_DEBUG, "%s", "GPS-SYNC Message received !");
// Identified the GPS data as valid
if (gpsdata.state == IPS_OK)
{
XMLEle *ep=NULL;
for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
{
const char *elemName = findXMLAttValu(ep, "name");
DEBUGF(INDI::Logger::DBG_DEBUG, "Snooping property received %s", (char *)elemName);

if ((!strcmp(elemName, "GPSPOS")) && (!strcmp(pcdataXMLEle(ep), "On")))
// Mannage Local position value
// Convert Gps data coord to double value
{
if (f_scansexa(gpsdata.Lon, &dGpsLon) != 0)
{
DEBUGF(INDI::Logger::DBG_DEBUG, "Convertion error from sexagesimal to double for longitude from GPS %s", gpsdata.Lon);
return 0;
}
if (f_scansexa(gpsdata.Lat, &dGpsLat) != 0)
{
DEBUGF(INDI::Logger::DBG_DEBUG, "Convertion error from sexagesimal to double for latitude from GPS %s", gpsdata.Lat);
return 0;
}
dGpsElev = atof(gpsdata.Elev);

DEBUGF(INDI::Logger::DBG_DEBUG, "LONG %f", dGpsLon);
DEBUGF(INDI::Logger::DBG_DEBUG, "LAT %f", dGpsLat);

//strncpy(gpsdata.Lat, pcdataXMLEle(ep), sizeof(gpsdata.Lat));
// Here we set the new site postion from the GPS
if (updateLocation(dGpsLat, dGpsLon, dGpsElev))
{
LocationN[LOCATION_LATITUDE].value = dGpsLat;
LocationN[LOCATION_LONGITUDE].value = dGpsLon;
LocationN[LOCATION_ELEVATION].value = dGpsElev;
LocationNP.s=IPS_OK;

// Update client display
IDSetNumber(&LocationNP,NULL);
}
else
{
LocationNP.s=IPS_ALERT;
// Update client display
IDSetNumber(&LocationNP,NULL);
}
}

else if ((!strcmp(elemName, "GPSTIME")) && (!strcmp(pcdataXMLEle(ep), "On")))
// Mannage Time snoop value
{
// Here we set the new time from the GPS
//We are looking for time offset and time zone; GPS provide UTC time
t0 = time(NULL);
localtime_r(&t0, &lt);

DEBUGF(INDI::Logger::DBG_DEBUG, "Offset to GMT is %d", lt.tm_gmtoff);
DEBUGF(INDI::Logger::DBG_DEBUG, "The time zone is %s", lt.tm_zone);

/* initialize time from snopped device*/

DEBUGF(INDI::Logger::DBG_SESSION, "TIME = %s, DATE = %s", gpsdata.Time, gpsdata.Date);

rc = sscanf(gpsdata.Date, "%[^-]-%[^-]-%[^\n]", year, month, day);
DEBUGF(INDI::Logger::DBG_DEBUG, "rc DATE : %d", rc);
if (rc == 3)
{
rc = sscanf(gpsdata.Time, "%[^:]:%[^:]:%[^\n]", hour, min, sec);
DEBUGF(INDI::Logger::DBG_DEBUG, "rc TIME : %d", rc);
if (rc == 3)
{
// all extration data has been successfull (rc result OK)
// Reuse partially the init code for time initialisation
st.tm_year = atoi(year) - 1900;
st.tm_mon = atoi(month) -1;
st.tm_mday = atoi(day);
st.tm_hour = atoi(hour);
st.tm_min = atoi(min);
st.tm_sec = atoi(sec);
st.tm_isdst = 1; // Is DST on? 1 = yes, 0 = no, -1 = unknown

lasttimeupdate.tv_sec = mktime(&st) + lt.tm_gmtoff; // compensate with local time offset to UTC time
lasttimeupdate.tv_usec = lasttimeupdate.tv_sec * 1000;
// now gmtime give the UTC time from the GPS
gmtime_r(&lasttimeupdate.tv_sec, &utc);
lndate.seconds = utc.tm_sec; + ((double)lasttimeupdate.tv_usec / 1000000);
lndate.minutes = utc.tm_min;
lndate.hours = utc.tm_hour;
lndate.days = utc.tm_mday;
lndate.months = utc.tm_mon + 1;
lndate.years = utc.tm_year + 1900;
// Set the new value of the lastclockupdate value
clock_gettime(CLOCK_MONOTONIC, &lastclockupdate);
} //if (rc == 3)
} //if (rc == 3)
} //else if ((!strcmp(elemName, "GPSTIME")) && (!strcmp(pcdataXMLEle(ep), "On")))
} //for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
} //if (gpsdata.state == IPS_OK)
} //if (!strcmp(propName, "GPS-SYNC"))

if (!strcmp(propName, "GPS-INFO"))
// Getting GPS data throughtthe snoop of the text vector who's contain these
{
if (gpsdata.state == IPS_OK)
{
XMLEle *ep=NULL;
// Store values received by the GPS module on BoxControler
for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
{
const char *elemName = findXMLAttValu(ep, "name");
DEBUGF(INDI::Logger::DBG_DEBUG, "Snooping property received %s", (char *)elemName);

if (!strcmp(elemName, "Latitude"))
{
strncpy(gpsdata.Lat, pcdataXMLEle(ep), sizeof(gpsdata.Lat));
DEBUGF(INDI::Logger::DBG_DEBUG, "Latitude OK %s", gpsdata.Lat);
}
else if (!strcmp(elemName, "Longitude"))
{
strncpy(gpsdata.Lon, pcdataXMLEle(ep), sizeof(gpsdata.Lon));
DEBUGF(INDI::Logger::DBG_DEBUG, "Longitude OK %s", gpsdata.Lon);
}
else if (!strcmp(elemName, "Altitude (m)"))
{
strncpy(gpsdata.Elev, pcdataXMLEle(ep), sizeof(gpsdata.Elev));
DEBUGF(INDI::Logger::DBG_DEBUG, "Altitude OK %s", gpsdata.Elev);
}
else if (!strcmp(elemName, "Heure GMT"))
{
strncpy(gpsdata.Time, pcdataXMLEle(ep), sizeof(gpsdata.Time));
DEBUGF(INDI::Logger::DBG_DEBUG, "Heure GMT OK %s", gpsdata.Time);
}
else if (!strcmp(elemName, "Date"))
{
strncpy(gpsdata.Date, pcdataXMLEle(ep), sizeof(gpsdata.Date));
DEBUGF(INDI::Logger::DBG_DEBUG, "Date OK %s", gpsdata.Date);
}
} //for (ep = nextXMLEle(root, 1) ; ep != NULL ; ep = nextXMLEle(root, 0))
} //if (gpsdata.state == IPS_OK)
} //if (!strcmp(propName, "GPS-INFO"))

return true;
} //EQMod::ISSnoopDevice
Philippe Besson
Skywatcher HEQ5, Televue 101-IS, Takahashi FS-60CB
Focus Boss II with OptecInc TCF-S focuser and Starlight Instruments HSM20 handy stepper motor
Guiding camera ZWO ASI120MM
Filterwheel OptecInc IFW
Camera not set yet
Switzerland
The following user(s) said Thank You: dolguldur
8 years 8 months ago #4779

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

I think we could add ACTIVE_DEVICES to INDI::Telescope and define a new class ACTIVE_GPS for GPS device, and define a new standard property for GPS data, but I think it should be the same as the current date/time and location format. Many drivers also use a lot of functions that are dependent on system time, as the date/time in the site management is usually just forwarded to the mount and not usually used for anything else.
8 years 8 months ago #4780

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

  • Posts: 983
  • Thank you received: 375
Guys, isn't it the case that Location and Time should be configured on INDI::Telescope layer instead of specific scope driver layer?
In astroberry gps I snoop these values with EQMod driver. And the only reason is that I cannot figure out how to do it on generic INDI::Telescope property.
Having said that I must admit that snooping time from astroberry gps does not work at all because it competes with KStars & EKOS, which overwrites the snooped value just after it is submitted to the telescope. So the question is what is the proper way to send location and time from gps driver to ANY telescope.

BTW. in the latest version of astroberry gps driver (available in svn repo veryy soon) I added Local Sidereal Time and Polaris Hour Angle for easy polar alignement.
8 years 8 months ago #4787

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


Exactly, which is why I suggested we add ACTIVE_DEVICES property to INDI::Telescope.

You can do 2 things:

1. Disable sending time and location from KStars, just go to INDI options in KStars options; OR
2. Change source from "Computer" to "Device" in INDI options. This will not only make KStars stop sending time/location to the the drivers, but it expects them from the driver and syncs KStars with it.
8 years 8 months ago #4790

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

  • Posts: 983
  • Thank you received: 375
Right, option #1 might work. For some reason I did not realize that I can disable updating location and time from KStars. I will try it soon and let you know.
I need to take a closer look to option #2 because using Device as a source is my regular approach and still I face the problem. Unless OR should be AND :) which I'm going to try very soon.
8 years 8 months ago #4801

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

  • Posts: 72
  • Thank you received: 21
Dear all.
Thanks for all of your comments. Few of them are going in my direction.
- Implement the ACTIVE_DEVICE for GPS and have a new clas for GPS_DEVICE could be great for the future as this is more and more commun to have GPS module on Arduino, RPI or USB to computer.
- It think too it would be better to go in low level in class to implement such funtion on INDI::TELESCOPE to provide it to all children.
- I could confirm that use device time data to update Kstars works fine, but unfortunattely not the locallisation data At least with EQMod); or I've done a big mistakes somewhere in my configuration. (This device to Kstar communication was the based of the idea to do this setting from the GPS.
- I Use GPS via an Arduino board as I get other info from it to my personnal Indi driver, like meteo data, power values of the Battery, 12V and 5V for the hub. This is why I don't use the Astroberry gsprpi drivers.
And my idea to have a standart for GPS is comming from that point. Different drivers with easy way to implementd localistion and time setting
@Jasem. I not sure to really understand what you mean when you wrote "I think it should be the same as the current date/time and location format" t is a positive or negative remarks.

Very best regards
Philippe Besson
Skywatcher HEQ5, Televue 101-IS, Takahashi FS-60CB
Focus Boss II with OptecInc TCF-S focuser and Starlight Instruments HSM20 handy stepper motor
Guiding camera ZWO ASI120MM
Filterwheel OptecInc IFW
Camera not set yet
Switzerland
8 years 8 months ago #4803

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

Besson, I meant that the GPS driver should use the same properties used currently for TIME_UTC and GEOGRAPHIC_COORD. They shall be read only. Another critical part is the GPS driver must also be able to update the system time of the device it is running on, otherwise, it is not very useful.
8 years 8 months ago #4808

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

  • Posts: 72
  • Thank you received: 21
Dear Jasem.
I fully agree, and I've to move my code is this way, to remove conversion from the Telescope for Time and Coord.First I should myke changes in my personnal driver. From that point I've few questions for communition inter drivers process.
The snoop function send the content of the vectors. If I want to display coord. in Sexagesimal format, and send it in degree how to proceed? Idem for time if I display two eay readable field one for time and one for date.
Could we hide a vector to not display it in any tabs and then work with these? Or Is there some functions to create the XML message and send to snoop to other device without using local vectors?
As the Time is update on the EQMod this way seems already good but what about INDI:TELESCOPE? and I appreciate personnaly a lot to be able to update KStars with this time setting, and I hope someone will find why the coord location doesn't do it!
Regards
Philippe Besson
Skywatcher HEQ5, Televue 101-IS, Takahashi FS-60CB
Focus Boss II with OptecInc TCF-S focuser and Starlight Instruments HSM20 handy stepper motor
Guiding camera ZWO ASI120MM
Filterwheel OptecInc IFW
Camera not set yet
Switzerland
8 years 8 months ago #4812

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

Ok, so here are some updates:

1. KStars now correctly update both time and location. There was an issue updating location which is now fixed. Next kstars-bleeding update should fix all these issues.
2. I created INDI::GPS which is the parent class for simple GPS devices. It's a very simple class with only 3 properties, GEOGRAPHIC_COORD, TIME_UTC, and GPS_REFRESH. A sample implementation is "GPS Simulator" which is now available under auxiliary drivers.
3. INDI::Telescope was updated to snoop on GEOGRAPHIC_COORD and TIME_UTC and call regular functions to update time and location values. There is no need at all to change any telescope driver code as the changes are handled on the INDI::Telescope side.

So Besson, please take a look the INDI::GPS class and "GPS Simulator" and see if you can adapt your driver to use that. It should be fairly straight forward. And no, we can't hide any vectors, everything that is sent gets displayed. For now, the "GPS Simulator" driver updates both the Telescope and KStars, so it shouldn't pose any issues. Please test and let me know if there are any issues I might have overlooked.
The following user(s) said Thank You: Radek Kaczorek, Philippe
8 years 8 months ago #4815

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

  • Posts: 983
  • Thank you received: 375
This is very good news! I'm going to look at it this week. These would resolve my issues with astroberry gps driver and utc time snooping.
I will post an update as soon as I reengineer the code to include the latest changes.
8 years 8 months ago #4824

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

  • Posts: 983
  • Thank you received: 375
As to share some experience... I spend some time on analysis of available options for getting time and location on Raspberry Pi from various gps modules and my final conclusions found their ways to astroberry gps driver architecture. It relies on two interconnected services: gpsd (for standardized gps data handling and device sharing) and ntpd (for system time synchronization with available network servers AND gps through memory shared with gpsd). Thanks to such an approach all gps data are handled by system wide service, the same for time. This would be good idea to stick to this to avoid any conflicts while accessing gps serial interface.
8 years 8 months ago #4844

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

  • Posts: 72
  • Thank you received: 21
INDI::GPS Works fine, and it quite easy to use.
The last remark from Kaczorek relative to GPS time or/and Network time is quite interresting.
Another point I've to involve about the implementation of snoop in INDI::Telescope. Maybe it would be good to add a check before update date received in the XML message. In my point of view the "state" value of the vector should be check to have "ok" on it. If not processLocationInfo nor processTimeInfo should be call as invalid data!

We could imaging to use different states for different information like:
- ok = Time and Localisation good
- busy = Only time is valid
- alert = Nothing valid
- idle = Don't know
but I agree this not the original meaning of the color! and could make some confusion!
That would give more control on GPS side to update telescope data (and KStars) only with valide values.

@Jasem: Did you never thing to extend the nombre of condition to 7 and use Rainbow colors, with some IPS_EXTRA1..3 to be more flexible (I've already thougt about it for my box controler).

Regards
Philippe Besson
Skywatcher HEQ5, Televue 101-IS, Takahashi FS-60CB
Focus Boss II with OptecInc TCF-S focuser and Starlight Instruments HSM20 handy stepper motor
Guiding camera ZWO ASI120MM
Filterwheel OptecInc IFW
Camera not set yet
Switzerland
8 years 8 months ago #4849

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

Time to create page: 0.808 seconds