feat: Support all current timezones for GPS (#3406)
* Support all current timezones. * Fix function name and calculation for timezone offset. * Allow setting any time offset value from -12 to +14 in 15 minutes increments. * Alternate timezone editor in Companion (from elecpower). * Fix compiler warning. * chore: Add the T20
This commit is contained in:
@@ -855,7 +855,8 @@ PACK(struct RadioData {
|
||||
|
||||
// Real attributes
|
||||
NOBACKUP(uint8_t manuallyEdited:1);
|
||||
NOBACKUP(int8_t spare0:7 SKIP);
|
||||
int8_t timezoneMinutes:3; // -3 to +3 ==> (-45 to 45 minutes in 15 minute increments)
|
||||
NOBACKUP(int8_t spare0:4 SKIP);
|
||||
CUST_ATTR(semver,nullptr,w_semver);
|
||||
CUST_ATTR(board,nullptr,w_board);
|
||||
CalibData calib[MAX_CALIB_ANALOG_INPUTS] NO_IDX;
|
||||
|
||||
@@ -599,9 +599,18 @@ void menuRadioSetup(event_t event)
|
||||
|
||||
#if defined(GPS)
|
||||
case ITEM_RADIO_SETUP_TIMEZONE:
|
||||
lcdDrawTextAlignedLeft(y, STR_TIMEZONE);
|
||||
lcdDrawNumber(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.timezone, attr|LEFT);
|
||||
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.timezone, -12, 12);
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, STR_TIMEZONE);
|
||||
int tzIndex = timezoneIndex(g_eeGeneral.timezone, g_eeGeneral.timezoneMinutes);
|
||||
lcdDrawText(RADIO_SETUP_2ND_COLUMN, y, timezoneDisplay(tzIndex).c_str(), attr);
|
||||
if (attr) {
|
||||
tzIndex = checkIncDec(event, tzIndex, minTimezone(), maxTimezone(), EE_GENERAL);
|
||||
if (checkIncDec_Ret) {
|
||||
g_eeGeneral.timezone = timezoneHour(tzIndex);
|
||||
g_eeGeneral.timezoneMinutes = timezoneMinute(tzIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_RADIO_SETUP_ADJUST_RTC:
|
||||
|
||||
@@ -547,9 +547,18 @@ void menuRadioSetup(event_t event)
|
||||
break;
|
||||
|
||||
case ITEM_RADIO_SETUP_TIMEZONE:
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_TIMEZONE);
|
||||
lcdDrawNumber(RADIO_SETUP_2ND_COLUMN, y, g_eeGeneral.timezone, attr|LEFT);
|
||||
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.timezone, -12, 12);
|
||||
{
|
||||
lcdDrawText(INDENT_WIDTH, y, STR_TIMEZONE);
|
||||
int tzIndex = timezoneIndex(g_eeGeneral.timezone, g_eeGeneral.timezoneMinutes);
|
||||
lcdDrawText(RADIO_SETUP_2ND_COLUMN, y, timezoneDisplay(tzIndex).c_str(), attr);
|
||||
if (attr) {
|
||||
tzIndex = checkIncDec(event, tzIndex, minTimezone(), maxTimezone(), EE_GENERAL);
|
||||
if (checkIncDec_Ret) {
|
||||
g_eeGeneral.timezone = timezoneHour(tzIndex);
|
||||
g_eeGeneral.timezoneMinutes = timezoneMinute(tzIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_RADIO_SETUP_ADJUST_RTC:
|
||||
|
||||
@@ -556,10 +556,22 @@ class GpsPage : public SubPage {
|
||||
{
|
||||
FlexGridLayout grid(col_two_dsc, row_dsc, 4);
|
||||
|
||||
tzIndex = timezoneIndex(g_eeGeneral.timezone, g_eeGeneral.timezoneMinutes);
|
||||
|
||||
auto line = body.newLine(&grid);
|
||||
// Timezone
|
||||
new StaticText(line, rect_t{}, STR_TIMEZONE, 0, COLOR_THEME_PRIMARY1);
|
||||
new NumberEdit(line, rect_t{}, -12, 12, GET_SET_DEFAULT(g_eeGeneral.timezone));
|
||||
auto tz = new NumberEdit(line, rect_t{}, minTimezone(), maxTimezone(),
|
||||
GET_DEFAULT(tzIndex),
|
||||
[=](int newTz) {
|
||||
tzIndex = newTz;
|
||||
g_eeGeneral.timezone = timezoneHour(newTz);
|
||||
g_eeGeneral.timezoneMinutes = timezoneMinute(newTz);
|
||||
SET_DIRTY();
|
||||
});
|
||||
tz->setDisplayHandler([](int32_t tz) {
|
||||
return timezoneDisplay(tz);
|
||||
});
|
||||
line = body.newLine(&grid);
|
||||
|
||||
// Adjust RTC (from telemetry)
|
||||
@@ -572,6 +584,9 @@ class GpsPage : public SubPage {
|
||||
new Choice(line, rect_t{}, STR_GPSFORMAT, 0, 1, GET_SET_DEFAULT(g_eeGeneral.gpsFormat));
|
||||
line = body.newLine(&grid);
|
||||
}
|
||||
|
||||
protected:
|
||||
int tzIndex;
|
||||
};
|
||||
|
||||
class ViewOptionsPage : public Page
|
||||
|
||||
+1
-1
@@ -471,7 +471,7 @@ uint8_t rtcAdjust(uint16_t year, uint8_t mon, uint8_t day, uint8_t hour, uint8_t
|
||||
t.tm_hour = hour;
|
||||
t.tm_min = min;
|
||||
t.tm_sec = sec;
|
||||
gtime_t newTime = gmktime(&t) + g_eeGeneral.timezone * 3600;
|
||||
gtime_t newTime = gmktime(&t) + timezoneOffsetSeconds(g_eeGeneral.timezone, g_eeGeneral.timezoneMinutes);
|
||||
gtime_t diff = (g_rtcTime > newTime) ? (g_rtcTime - newTime) : (newTime - g_rtcTime);
|
||||
|
||||
#if defined(DEBUG) && defined (PCBTARANIS)
|
||||
|
||||
@@ -263,7 +263,8 @@ static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 12, struct_CalibData, NULL),
|
||||
|
||||
@@ -293,7 +293,8 @@ static const struct YamlNode struct_OpenTxTheme__PersistentData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 22, struct_CalibData, NULL),
|
||||
|
||||
@@ -263,7 +263,8 @@ static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 12, struct_CalibData, NULL),
|
||||
|
||||
@@ -263,7 +263,8 @@ static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 12, struct_CalibData, NULL),
|
||||
|
||||
@@ -301,7 +301,8 @@ static const struct YamlNode struct_OpenTxTheme__PersistentData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 22, struct_CalibData, NULL),
|
||||
|
||||
@@ -301,7 +301,8 @@ static const struct YamlNode struct_OpenTxTheme__PersistentData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 22, struct_CalibData, NULL),
|
||||
|
||||
@@ -263,7 +263,8 @@ static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 12, struct_CalibData, NULL),
|
||||
|
||||
@@ -263,7 +263,8 @@ static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 12, struct_CalibData, NULL),
|
||||
|
||||
@@ -263,7 +263,8 @@ static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 12, struct_CalibData, NULL),
|
||||
|
||||
@@ -265,7 +265,8 @@ static const struct YamlNode struct_CustomFunctionData[] = {
|
||||
};
|
||||
static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "manuallyEdited", 1 ),
|
||||
YAML_PADDING( 7 ),
|
||||
YAML_SIGNED( "timezoneMinutes", 3 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_CUSTOM("board",nullptr,w_board),
|
||||
YAML_ARRAY("calib", 48, 12, struct_CalibData, NULL),
|
||||
|
||||
@@ -1045,3 +1045,47 @@ char *strAppendDate(char *str, bool time)
|
||||
|
||||
#if !defined(BOOT)
|
||||
#endif
|
||||
|
||||
// Manage timezones
|
||||
// For backward compatibility timezone is stored as two separate values:
|
||||
// timezone = hour value
|
||||
// timezoneMinutes - minute value / 15
|
||||
|
||||
int8_t minTimezone()
|
||||
{
|
||||
return -12 * 4;
|
||||
}
|
||||
|
||||
int8_t maxTimezone()
|
||||
{
|
||||
return 14 * 4;
|
||||
}
|
||||
|
||||
std::string timezoneDisplay(int tz)
|
||||
{
|
||||
char s[16];
|
||||
int h = abs(tz / 4);
|
||||
int m = abs(tz % 4) * 15;
|
||||
sprintf(s,"%s%d:%02d", (tz < 0) ? "-" : "", h, m);
|
||||
return std::string(s);
|
||||
}
|
||||
|
||||
int timezoneIndex(int8_t tzHour, int8_t tzMinute)
|
||||
{
|
||||
return (tzHour * 4) + tzMinute;
|
||||
}
|
||||
|
||||
int8_t timezoneHour(int tz)
|
||||
{
|
||||
return tz / 4;
|
||||
}
|
||||
|
||||
int8_t timezoneMinute(int tz)
|
||||
{
|
||||
return tz % 4;
|
||||
}
|
||||
|
||||
int timezoneOffsetSeconds(int8_t tzHour, int8_t tzMinute)
|
||||
{
|
||||
return (tzHour * 3600) + (tzMinute * 15 * 60);
|
||||
}
|
||||
|
||||
@@ -174,4 +174,13 @@ int strncasecmp(char (&s1)[L1], const char *const s2)
|
||||
std::string getValueWithUnit(int val, uint8_t unit, LcdFlags flags);
|
||||
std::string getGVarValue(uint8_t gvar, gvar_t value, LcdFlags flags);
|
||||
|
||||
// Timezone handling
|
||||
extern int8_t minTimezone();
|
||||
extern int8_t maxTimezone();
|
||||
extern std::string timezoneDisplay(int tz);
|
||||
extern int timezoneIndex(int8_t tzHour, int8_t tzMinute);
|
||||
extern int8_t timezoneHour(int tz);
|
||||
extern int8_t timezoneMinute(int tz);
|
||||
extern int timezoneOffsetSeconds(int8_t tzHour, int8_t tzMinute);
|
||||
|
||||
#endif // _STRHELPERS_H_
|
||||
|
||||
@@ -934,7 +934,7 @@ static void adjustTimeFromUTC(uint8_t hour, uint8_t min, uint8_t sec,
|
||||
struct gtm *tp)
|
||||
{
|
||||
// Get current UTC date/time
|
||||
__offtime(&g_rtcTime, -g_eeGeneral.timezone * 3600, tp);
|
||||
__offtime(&g_rtcTime, -timezoneOffsetSeconds(g_eeGeneral.timezone, g_eeGeneral.timezoneMinutes), tp);
|
||||
|
||||
tp->tm_hour = hour;
|
||||
tp->tm_min = min;
|
||||
|
||||
Reference in New Issue
Block a user