TuyaMCUBr: Handle "Get local time" requests from the MCU (#17750)

* handle get local time requests from the MCU.

from what i can tell from the tuya serial communication protocol
documentation, we only have to send the time if MCU requests it. this is
unlike how TUYA_SET_TIME is implementing in xdrv_16, where if
USE_TUYA_TIME is enabled it will send unsolicited time updates every
minute as well as in response to a request from the MCU.

i couldn't find an easy to check flag to see if tasmota was synced to a
real clock, so this blindly tells the MCU that our time is valid and
copies it over, the same as xdrv_16.

the tuya doco also describes a "Get system time in GMT" request and
response structure which would be mostly a copy of this code if i knew
if and where tasmota keeps track of UTC/GMT.

lastly, i'm not convinced RtcTime.day_of_week is right. it's friday
here which should be 6 if you start counting sunday as 1, but i read 2

* local time sync is implemented, but not gmtime
This commit is contained in:
David Gwynne 2023-01-20 19:07:42 +10:00 committed by GitHub
parent e2983f2835
commit 51866026d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 55 additions and 2 deletions

View File

@ -33,7 +33,7 @@
* - supporting the raw and string Dp types
* - restarting the tuya mcu state machine?
* - restarting the rx state machine when no bytes are rxed for a while
* - time sync
* - gmtime sync
*/
#define XDRV_65 65
@ -82,7 +82,8 @@ CTASSERT(sizeof(struct tuyamcubr_header) == 6);
#define TUYAMCUBR_CMD_QUERY_STATE 0x08
#define TUYAMCUBR_CMD_INIT_UPGRADE 0x0a
#define TUYAMCUBR_CMD_UPGRADE_PKG 0x0b
#define TUYAMCUBR_CMD_SET_TIME 0x1c
#define TUYAMCUBR_CMD_GMTIME 0x0c
#define TUYAMCUBR_CMD_TIME 0x1c
/* wifi state */
@ -94,6 +95,35 @@ CTASSERT(sizeof(struct tuyamcubr_header) == 6);
#define TUYAMCUBR_NETWORK_STATUS_6 0x05 /* low power mode */
#define TUYAMCUBR_NETWORK_STATUS_7 0x06 /* pairing in EZ+AP mode */
/* gmtime */
struct tuyamcubr_gmtime {
uint8_t valid;
uint8_t year; /* + 2000 */
uint8_t month; /* 1 to 12 */
uint8_t day; /* 1 to 31 */
uint8_t hour; /* 0 to 23 */
uint8_t minute; /* 0 to 59 */
uint8_t second; /* 0 to 59 */
};
CTASSERT(sizeof(struct tuyamcubr_gmtime) == 7);
/* time */
struct tuyamcubr_time {
uint8_t valid;
uint8_t year; /* 2000 + */
uint8_t month; /* 1 to 12 */
uint8_t day; /* 1 to 31 */
uint8_t hour; /* 0 to 23 */
uint8_t minute; /* 0 to 59 */
uint8_t second; /* 0 to 59 */
uint8_t weekday; /* 1 (monday) to 7 */
};
CTASSERT(sizeof(struct tuyamcubr_time) == 8);
/* set dp */
struct tuyamcubr_data_header {
@ -288,6 +318,8 @@ static void tuyamcubr_recv_net_status(struct tuyamcubr_softc *, uint8_t,
const uint8_t *, size_t);
static void tuyamcubr_recv_status(struct tuyamcubr_softc *, uint8_t,
const uint8_t *, size_t);
static void tuyamcubr_recv_time(struct tuyamcubr_softc *, uint8_t,
const uint8_t *, size_t);
static const struct tuyamcubr_recv_command tuyamcubr_recv_commands[] = {
{ TUYAMCUBR_CMD_HEARTBEAT, tuyamcubr_recv_heartbeat },
@ -295,6 +327,7 @@ static const struct tuyamcubr_recv_command tuyamcubr_recv_commands[] = {
{ TUYAMCUBR_CMD_MODE, tuyamcubr_recv_mode },
{ TUYAMCUBR_CMD_WIFI_STATE, tuyamcubr_recv_net_status },
{ TUYAMCUBR_CMD_STATE, tuyamcubr_recv_status },
{ TUYAMCUBR_CMD_TIME, tuyamcubr_recv_time },
};
static void
@ -778,6 +811,26 @@ tuyamcubr_recv_status(struct tuyamcubr_softc *sc, uint8_t v,
} while (datalen > 0);
}
static void
tuyamcubr_recv_time(struct tuyamcubr_softc *sc, uint8_t v,
const uint8_t *data, size_t datalen)
{
struct tuyamcubr_time tm;
/* check datalen? should be 0 */
tm.valid = 1; /* XXX check whether time is valid */
tm.year = RtcTime.year % 100;
tm.month = RtcTime.month;
tm.day = RtcTime.day_of_month;
tm.hour = RtcTime.hour;
tm.minute = RtcTime.minute;
tm.second = RtcTime.second;
tm.weekday = (RtcTime.day_of_week - 1) || 7;
tuyamcubr_send(sc, TUYAMCUBR_CMD_TIME, &tm, sizeof(tm));
}
static void
tuyamcubr_tick(struct tuyamcubr_softc *sc, unsigned int ms)
{