Invalid conversion from const char* to 'time_t (aka long int)

Hi! :slight_smile:

Anyone know how to monitor a pre-determined MQTT topic and basically retransmit anything received on that topic using Particle Publish?

More Info

I already use MQTT on this Photon but it only searches the payload of the messages to check if the payload matches certain predefined values and takes different actions depending on the payload.

I want the Photon to continue to be able to do that but also monitor a specific additional topic and retransmit the payload out on Particle Publish

Why? Iā€™m sending out a Unix timestamp on the local network using MQTT and want to retransmit the timestamp to my Cores using this Photon to set accurate time. There seems to be a bug with the Particle cloud and Cores whereby the time sync isnā€™t at all accurate.

Thanks all!!

Of course thatā€™s possible.
You are already subscribing to the MQTT topics which will then trigger the callback, right?
Inside that callback you can check for the special topic and when found execute a Particle.publish() - not sure whatā€™s not clear about that :confused:

However, the latency for receiving the MQTT message, ā€œre-transmittingā€ and receiving it again will need taking into account whereby itā€™s somewhat non-deterministic.

Sorry Scruff it was the method to check the topic I was unclear over.

I think this does it.

if (!strcmp(topic, "myTopic")) {
        // do action
}
1 Like

wahooo! So Iā€™ve got a Particle Publish set up doing this


which Iā€™m really pleased with and a bit amazed

but Iā€™m struggling with taking that timestamp and using it on my Core to set the time.
This doesnā€™t work

Particle.subscribe("TIME", eventHandler1, MY_DEVICES);

void eventHandler1(const char * event,
    const char * data) {
    if (strcmp(event, "TIME") == 0) {
    Time.setTime(data);
    } 
}

Am I doing something daft?! Nearly there! It says

invalid conversion from const char* to 'time_t (aka long int)

The error message already provides the clue

So you need to convert the received const char* to long int.
There are multiple ways to do that (e.g. atol(), strtol(), sscanf(), ...) which have been used all over the place in this forum already :wink:

Once you converted that string into a number you can use it as needed.

2 Likes

thanks so much Scruff! I THINK Iā€™ve solved it like thisā€¦

void eventHandler1(const char * event, const char * data){
long val;   
val = atol(data);

{
    if (strcmp(event, "TIME") == 0) {
        Time.setTime(val);
	Particle.publish(DEVICE_NAME, Time.timeStr(), 60, PRIVATE);
    }
}
}
1 Like

Iā€™d actually only do the conversion when the event indicates that the data sent actually is a time.

OK, thanks, Iā€™ll do that - what I was observing was that my code was working but there was a consistent four second inaccuracy. OK, I thought, I know how to deal with this! So I did val = val + 4; but that hasnā€™t changed a thing, which I thought surprising. Still the same 4 second inaccuracy. Anyway four seconds I can live with!! haha

That's what I was aiming at with this

But irrespective of the root for the offset, you may want to look at what the Time.now() gives you after you tried to set it via Time.setTime().
This should give you some feeling what may be happening.

Firstly, at this point, this is purely ā€˜academicā€™ - Iā€™m more than happy with a few seconds of inaccuracy - thatā€™s fine.

That said, do Time.now() and Time.timeStr() use the same data/source? And do they perhaps only update once per loop or similar? Because Iā€™m doing this:

void eventHandler1(const char * event,
    const char * data) {
    {
        if (strcmp(event, "TIME") == 0) {
            long val;
            long val2;
            val = atol(data);
            val2 = val + 4;
            Time.setTime(val2);
            Particle.publish(DEVICE_NAME, Time.timeStr(), 60, PRIVATE);
        }
    }
}

and Iā€™m finding that the Particle Cloud even though itā€™s given a Unix timestamp, doesnā€™t seem to apply it properly - OR some kind of lag in the Core itself causes it to be applied but with the introduction of a couple of seconds delay.

Just to reiterate - this is academic and I am not bothered about improving the accuracy resolution of the time, just interested in understanding it.

time time2

Yes they do, but Time.timeStr() also takes Time.zone() into consideration, Time.now() does not. Time.local() would give you the same kind of data as Time.now() but also accounts for Time.zone().

The time is updated at the rate of the HW RTC. When you set the time you will place the new value in the RTC and it will then "accept" that value when it's safe to.

If you want to know what's going on with the RTC after you set the value it's no good to check in console as this will always add the extra latency you have no control over nor can exactly determine how big it actually is.
You need to go as close to the source as you can (e.g. Serial.print()) .

What you see in console can only be the time on the device when the event was sent off.
I'm not sure whether the "PUBLISHED AT" header in console is not misleading and should rather be "RECEIVED AT".

BTW, 1616754941 may be representing exactly 10:35:41 but being an int type you can never know whether the actual time was 1616754941.000000 or rather 1616754941.999999.

2 Likes

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