@@ -177,10 +177,15 @@ bool posixTimezone(TimeChangeRule &dst, TimeChangeRule &std) {
177177 // example: "Europe/Ljubljana":"CET-1CEST,M3.5.0,M10.5.0/3"
178178}
179179*/
180+
180181static const char __weeks[] PROGMEM = " LasFirSecThiFou" ;
181182static char _week[4 ];
183+
182184static const char * weekShortStr (uint8_t dow) {
183- if (dow > 4 ) dow = 0 ;
185+ if (dow > 4 ) {
186+ DEBUG_PRINTF_P (PSTR (" TZ Error: JSON week parsing. (%d)" ), (int )dow);
187+ dow = 0 ;
188+ }
184189 uint8_t index = dow*3 ;
185190 for (int i=0 ; i < 3 ; i++) _week[i] = pgm_read_byte (&(__weeks[index + i]));
186191 _week[3 ] = 0 ;
@@ -192,70 +197,76 @@ bool jsonTimezone(TimeChangeRule &dst, TimeChangeRule &std) {
192197 // example: {"dst":{"w":"Last","dow":"Sun","m":"Mar","h":1,"off":60},"std":{"w":"Last","dow":"Sun","m":"Oct","h":1,"off":0}}
193198 bool success = false ;
194199 File f;
195- f = WLED_FS.open (" timezone.json" , " r" );
200+ f = WLED_FS.open (" / timezone.json" , " r" );
196201 if (f) {
202+ DEBUG_PRINTLN (F (" Reading timezone form JSON file" ));
197203 StaticJsonDocument<64 > filter;
198204 filter[" dst" ] = true ;
199205 filter[" std" ] = true ;
200- StaticJsonDocument<256 > d;
206+ StaticJsonDocument<384 > d;
201207 if (deserializeJson (d, f, DeserializationOption::Filter (filter)) == DeserializationError::Ok) {
202208 JsonObject o = d.as <JsonObject>();
203- if (!(o[F (" dst" )].isNull () || o[F (" std" )].isNull ())) {
204- if (o[" dst" ][" w" ].is <const char *>())
209+ if (!(o[" dst" ].isNull () || o[" std" ].isNull ())) {
210+ // fill default values from UTC in case of missing data
211+ memcpy_P (&dst, &std::get<1 >(TZ_TABLE[0 ]), sizeof (TimeChangeRule));
212+ memcpy_P (&std, &std::get<2 >(TZ_TABLE[0 ]), sizeof (TimeChangeRule));
213+
214+ if (!o[" dst" ][" w" ].isNull () && o[" dst" ][" w" ].is <const char *>())
205215 for (int i=0 ; i<5 ; i++) {
206216 if (strncmp (weekShortStr (i), o[" dst" ][" w" ].as <const char *>(), 3 ) == 0 ) {
207217 dst.week = i;
208218 break ;
209219 }
210220 }
211- else dst.week = o[" dst" ][" w" ] | 0 ;
212- if (o[" dst" ][" dow" ].is <const char *>())
221+ else dst.week = max ( min ( o[" dst" ][" w" ] | 0 , 4 ), 0 ) ;
222+ if (!o[ " dst " ][ " dow " ]. isNull () && o[" dst" ][" dow" ].is <const char *>())
213223 for (int i=0 ; i<7 ; i++) {
214224 if (strncmp (dayShortStr (i+1 ), o[" dst" ][" dow" ].as <const char *>(), 3 ) == 0 ) {
215225 dst.dow = i+1 ;
216226 break ;
217227 }
218228 }
219- else dst.dow = o[" dst" ][" dow" ] | 1 ;
220- if (o[" dst" ][" m" ].is <const char *>())
229+ else dst.dow = max ( min ( o[" dst" ][" dow" ] | 1 , 7 ), 1 ) ;
230+ if (!o[ " dst " ][ " m " ]. isNull () && o[" dst" ][" m" ].is <const char *>())
221231 for (int i=0 ; i<12 ; i++) {
222232 if (strncmp (monthShortStr (i+1 ), o[" dst" ][" m" ].as <const char *>(), 3 ) == 0 ) {
223233 dst.month = i+1 ;
224234 break ;
225235 }
226236 }
227- else dst.month = o[" dst" ][" m" ] | 3 ;
228- dst.hour = o[" dst" ][" h" ] | 1 ;
229- dst.offset = o[" dst" ][" off" ] | 0 ;
237+ else dst.month = max ( min ( o[" dst" ][" m" ] | 3 , 12 ), 1 ) ;
238+ dst.hour = max ( min ( o[" dst" ][" h" ] | 1 , 23 ), 0 ) ;
239+ dst.offset = max ( min ( o[" dst" ][" off" ] | 0 , 1440 ), - 1440 ) ;
230240
231- if (o[" std" ][" w" ].is <const char *>())
241+ if (!o[ " std " ][ " w " ]. isNull () && o[" std" ][" w" ].is <const char *>())
232242 for (int i=0 ; i<5 ; i++) {
233243 if (strncmp (weekShortStr (i), o[" std" ][" w" ].as <const char *>(), 3 ) == 0 ) {
234244 std.week = i;
235245 break ;
236246 }
237247 }
238- else std.week = o[" std" ][" w" ] | 0 ;
239- if (o[" std" ][" dow" ].is <const char *>())
248+ else std.week = max ( min ( o[" std" ][" w" ] | 0 , 4 ), 0 ) ;
249+ if (!o[ " std " ][ " dow " ]. isNull () && o[" std" ][" dow" ].is <const char *>())
240250 for (int i=0 ; i<7 ; i++) {
241251 if (strncmp (dayShortStr (i+1 ), o[" std" ][" dow" ].as <const char *>(), 3 ) == 0 ) {
242252 std.dow = i+1 ;
243253 break ;
244254 }
245255 }
246- else std.dow = o[" std" ][" dow" ] | 1 ;
247- if (o[" std" ][" m" ].is <const char *>())
256+ else std.dow = max ( min ( o[" std" ][" dow" ] | 1 , 7 ), 1 ) ;
257+ if (!o[ " std " ][ " m " ]. isNull () && o[" std" ][" m" ].is <const char *>())
248258 for (int i=0 ; i<12 ; i++) {
249259 if (strncmp (monthShortStr (i+1 ), o[" std" ][" m" ].as <const char *>(), 3 ) == 0 ) {
250260 std.month = i+1 ;
251261 break ;
252262 }
253263 }
254- else std.month = o[" std" ][" m" ] | 3 ;
255- std.hour = o[" std" ][" h" ] | 1 ;
256- std.offset = o[" std" ][" off" ] | 0 ;
264+ else std.month = max ( min ( o[" std" ][" m" ] | 3 , 12 ), 1 ) ;
265+ std.hour = max ( min ( o[" std" ][" h" ] | 1 , 23 ), 0 ) ;
266+ std.offset = max ( min ( o[" std" ][" off" ] | 0 , 1440 ), - 1440 ) ;
257267
258268 success = true ;
269+ DEBUG_PRINTLN (F (" ... was successful." ));
259270 }
260271 }
261272 f.close ();
0 commit comments