+
    ßRZjt9  ã                   ó:  € R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHtHt ^ RIH	t	 ^ RI
HtHtHtHtHtHt ^ RIHtHtHt ]! R]4      t]t]t]tRtRtR	tR
tRR0t]P>                  ! 4       t ]	! R4      t!R t"R t#R t$R t%R t&R t'R t(R t)R t*R t+R t,R,R lt-R t.R-R lt/R.R lt0R t1R t2R R  lt3]Pi                  R!R".R#7      R$ 4       t5]Pi                  R%R".R#7      R& 4       t6]Pi                  R'R(.R#7      R) 4       t7]Pi                  R*R"R(.R#7      R+ 4       t8R# )/zEFillDrainPump dashboard, schedule sync, logging, and device commands.N)ÚdatetimeÚtimezone)ÚZoneInfo)Ú	BlueprintÚjsonifyÚredirectÚrender_templateÚrequestÚurl_for)ÚFILLDRAIN_COMMAND_FILEÚFILLDRAIN_LOG_FILEÚFILLDRAIN_SCHEDULE_FILEÚ	filldrainz08:00z19:00ÚdisabledÚ40ÚfullÚlightzAmerica/Chicagoc                óˆ   € \        V 4      pVf$   \        T ;'       g    R4      P                  4       # VP                  R4      # )z2Convert a UTC log timestamp to local display time.Ú ú%I:%M:%S %p %Y-%m-%d)Úparse_log_datetimeÚstrÚstripÚstrftime)ÚvalueÚlocal_dts   & Ú</workplace/Workspace/Software/Server/blueprints/filldrain.pyÚto_local_timestampr   "   s>   € ä! %Ó(€HØÒÜ�5—;�;˜BÓ×%Ñ%Ó'Ð'Ø×ÑÐ3Ó4Ð4ó    c                óâ   € \        T ;'       g    R4      P                  4       pV'       g   R# R F)  p \        P                  ! W4      P	                  R4      u # 	  V#   \
         d     K=  i ; i)zGFormat device-reported time like Local time: HH:MM:SS AM/PM YYYY-MM-DD.r   r   )z%Y-%m-%dT%H:%M:%Sú%Y-%m-%d %H:%M:%Sz%Y-%m-%dT%H:%M:%S%z)r   r   r   Ústrptimer   Ú
ValueError)r   ÚtextÚfmts   &  r   Úformat_device_timer%   *   sj   € äˆu�{ˆ{˜Ó×!Ñ!Ó#€DßÙóˆð
	Ü×$Ò$ TÓ/×8Ñ8Ð9OÓPÒPñð €Køô ô 	Úð	ús   ´$AÁA.Á-A.c                óÐ  € \        T ;'       g    R4      P                  4       pV'       g   R#  VP                  R4      '       d7   \        P                  ! VR4      P                  \        P                  R7      pM5\        P                  ! VR4      P                  \        P                  R7      pVP                  \        4      P                  RR7      #   \         d     R# i ; i)z@Parse a UTC log timestamp into a naive America/Chicago datetime.r   Nz UTCú%Y-%m-%d %H:%M:%S UTC)Útzinfor    )r   r   Úendswithr   r!   Úreplacer   ÚutcÚ
astimezoneÚLOCAL_TZr"   )r   r#   Úutc_dts   &  r   r   r   ;   sÀ   € äˆu�{ˆ{˜Ó×!Ñ!Ó#€DßÙðØ�=‰=˜× Ò Ü×&Ò& tÐ-DÓE×MÑMÜ—|‘|ð Nó ‰Fô ×&Ò& tÐ-@ÓA×IÑIÜ—|‘|ð Jó ˆFð × Ñ ¤Ó*×2Ñ2¸$Ð2Ó?Ð?øÜô Úðús   ¯C ÁBC ÃC%Ã$C%c                 óN  € \         P                  P                  \        4      '       g   \        \
        \        3#  \        \        RRR7      ;_uu_ 4       p V P                  4        Uu. uF  qP                  4       NK  	  ppRRR4       \        X4      ^ 8”  d"   \        V^ ,          4      '       d
   V^ ,          M\        p\        V4      ^8”  d    \        V^,          4      '       d   \        pMA\        V4      ^8”  d,   \        V^,          4      '       d   \        V^,          4      pM\
        p\        V4      ^8”  d"   \        V^,          4      '       d
   V^,          M\        pW4V3# u upi   + '       g   i     L÷; i  \          d    \        \
        \        3u # i ; i)zPRead on1, on2, duration from schedule file. Return (on1, on2, duration) strings.Úrúutf-8©ÚencodingN)ÚosÚpathÚisfileÚSCHEDULE_FILEÚDEFAULT_ON1ÚDEFAULT_ON2ÚDEFAULT_DURATIONÚopenÚ	readlinesr   ÚlenÚ
valid_timeÚis_disabled_on2ÚDISABLED_ON2Únormalize_timeÚvalid_durationÚ	Exception)ÚfÚlineÚlinesÚon1Úon2Údurations         r   Úread_schedulerJ   N   s.  € ä�7‰7�>‰>œ-×(Ò(ÜœKÔ)9Ð9Ð9ð:Ü”- ¨w×7Õ7¸1Ø./¯k©k¬mÓ<©m d—Z‘Z–\©mˆEÐ<÷ 8ä˜e›* qœ.¬Z¸¸a½×-AÒ-Aˆe�AŽhÄ{ˆÜˆu‹:˜Œ>œo¨e°A­h×7Ò7Ü‰CÜ�‹Z˜!Œ^¤
¨5°­8× 4Ò 4Ü   q¥Ó*‰CäˆCô �5‹z˜AŒ~¤.°°qµ×":Ò":ð �!ŽHä!ð 	ð
 ˜Ð!Ð!ùò =÷ 8×7ûô ô :ÜœKÔ)9Ð9Ò9ð:ús<   ¼F ÁE2Á)E-ÂE2ÂC)F Å-E2Å2F	Å=F ÆF$Æ#F$c                ón   € \        T ;'       g    R4      P                  4       P                  4       pVR9   # )z8Return True when second start is intentionally disabled.r   >   r   Ú-ÚoffÚnoner   )r   r   Úlower©r   r#   s   & r   r?   r?   f   s0   € äˆu�{ˆ{˜Ó×!Ñ!Ó#×)Ñ)Ó+€DØÐ7Ñ7Ð7r   c                óÐ   € \         P                  ! R\        V 4      P                  4       4      p\	        VP                  ^4      4      R R\	        VP                  ^4      4      R 2# )z,Normalize HH:MM to zero-padded 24-hour form.ú(\d{1,2}):(\d{2})Ú02dÚ:)ÚreÚ	fullmatchr   r   ÚintÚgroup©r   Úmatchs   & r   rA   rA   l   sQ   € ä�LŠLÐ-¬s°5«z×/?Ñ/?Ó/AÓB€EÜ�%—+‘+˜a“.Ó! #Ð& a¬¨E¯K©K¸«NÓ(;¸CÐ'@ÐAÐAr   c                ó  € \         P                  ! R\        V 4      P                  4       4      p\	        T;'       dC    \        VP                  ^4      4      ^8*  ;'       d    \        VP                  ^4      4      ^;8*  4      # )z&Return True for a 24-hour HH:MM value.rR   )rU   rV   r   r   ÚboolrW   rX   rY   s   & r   r>   r>   r   s_   € ä�LŠLÐ-¬s°5«z×/?Ñ/?Ó/AÓB€EÜ�×QÐQœ#˜eŸk™k¨!›nÓ-°Ñ3×QÐQ¼¸E¿K¹KÈ»NÓ8KÈrÑ8QÓRÐRr   c                ór   €  ^\        V 4      u;8*  ;'       d    R8*  # u #   \        \        3 d     R# i ; i)zBReturn True for a duration representable by the firmware's uint16.iÿÿ  F)rW   Ú	TypeErrorr"   )r   s   &r   rB   rB   x   s;   € ðØ”C˜“J×'Ô' %Ñ'Ð'Ñ'Ð'øÜ”zÐ"ô Úðús   ‚! ž! ¡6µ6c           
     óX  € \         P                  ! \         P                  P                  \        4      RR7       \         R2p\        VRRR7      ;_uu_ 4       pVP                  V  RV RV R24       RRR4       \         P                  ! V\        4       R#   + '       g   i     L-; i)	z!Atomically write schedule values.T©Úexist_okú.tmpÚwr1   r2   Ú
N)r4   Úmakedirsr5   Údirnamer7   r;   Úwriter*   )rG   rH   rI   Ú	temp_fileÚfiles   &&&  r   Úwrite_schedulerj   €   su   € ä‡K‚K”—‘—‘¤Ó.¸Õ>Ü �/ Ð&€IÜ	ˆi˜ w×	/Õ	/°4Ø�
‰
�c�U˜"˜S˜E  H :¨RÐ0Ô1÷ 
0ä‡J‚Jˆyœ-Ö(÷ 
0×	/ús   ÁBÂB)	c            	     ó�  €  \        \        RRR7      ;_uu_ 4       p \        P                  ! V 4      pRRR4       R\	        XP                  R/ 4      P                  RR4      4      R\	        VP                  R/ 4      P                  RR4      4      /#   + '       g   i     Lh; i  \        \        \        3 d
    RRRR/u # i ; i)	z#Read per-hardware pending commands.r0   r1   r2   Nr   ÚrebootFr   )	r;   ÚCOMMAND_FILEÚjsonÚloadr\   ÚgetÚOSErrorr"   r^   )ri   Údatas     r   Úread_commandsrs   ‰   s©   € ð/Ü”, ¨g×6Õ6¸$Ü—9’9˜T“?ˆD÷ 7ð ”D˜Ÿ™ &¨"Ó-×1Ñ1°(¸EÓBÓCØ”T˜$Ÿ(™( 7¨BÓ/×3Ñ3°H¸eÓDÓEð
ð 	
÷ 7×6ûô ”Z¤Ð+ô /Ø˜˜w¨Ð.Ò.ð/ús(   ‚B& œB³AB& ÂB#	ÂB& Â&CÃCc                óä  € \         P                  ! \         P                  P                  \        4      RR7       \
         Uu/ uF!  pVR\        V P                  VR4      4      /bK#  	  pp\         R2p\        VRRR7      ;_uu_ 4       p\        P                  ! W$^RR	7       VP                  R
4       RRR4       \         P                  ! V\        4       R# u upi   + '       g   i     L2; i)z1Atomically persist per-hardware pending commands.Tr`   rl   Frb   rc   r1   r2   )ÚindentÚ	sort_keysrd   N)r4   re   r5   rf   rm   ÚVALID_VARIANTSr\   rp   r;   rn   Údumprg   r*   )ÚcommandsÚvariantÚpayloadrh   ri   s   &    r   Úwrite_commandsr|   –   s·   € ä‡K‚K”—‘—‘¤Ó-¸Õ=õ &óá%ˆGð 	�(œD §¡¨g°uÓ!=Ó>Ð?Ò?Ù%ð ð ô  �. Ð%€IÜ	ˆi˜ w×	/Õ	/°4Ü�	Š	�'¨°TÕ:Ø�
‰
�4Ô÷ 
0ô ‡J‚Jˆyœ,Ö'ùò÷
 
0×	/ús   Á'CÂ
+CÃC/	c                óö   € V f   \        \        4      M
\        V 4      p\        ;_uu_ 4        \        4       pV F  pV\        9   g   K  RW#&   K  	  \	        V4       RRR4       R#   + '       g   i     R# ; i)z?Queue reboot for one or more hardware variants (default: both).NT)Úlistrw   ÚCOMMAND_LOCKrs   r|   )ÚvariantsÚtargetsry   rz   s   &   r   Úqueue_rebootr‚   ¤   sS   € à&.Ò&6Œd”>Ô"¼DÀ»N€Gß	ŽÜ “?ˆÛˆGØœ.Ö(Ø$(�Ó!ñ ô 	�xÔ ÷ 
��Šús   ­A'Á
A'Á'A8	c                óì   € V \         9  d   R# \        ;_uu_ 4        \        4       pVP                  V 4      '       g    RRR4       R# RW&   \	        V4       RRR4       R#   + '       g   i     R# ; i)z<Return and clear a pending command for one hardware variant.rN   NFrl   )rw   r   rs   rp   r|   )rz   ry   s   & r   Úconsume_commandr„   ¯   s[   € à”nÔ$Ùß	ŽÜ “?ˆØ�|‰|˜G×$Ò$Ø÷ 
‰ð "ˆÑÜ�xÔ ÷ 
ñ ÷ 
Žñ ús   œ#A"Á	A"Á"A3	c                óÀ  €  \        \        RRR7      ;_uu_ 4       pVP                  4       V ) R pRRR4       . p\	        X4       EFÐ  pTP                  4       P                  R4      w  rVp/ pT'       d1    \        P                  ! T4      p	\        T	\        4      '       d   T	pMRTP                  4       /pTP                  / R\        T4      bR\        T4      bR	TP!                  R	R
4      bRTP!                  RR
4      bRTP!                  RR
4      bR\#        TP!                  RR
4      4      bRTP!                  RR
4      bRTP!                  RR
4      bRTP!                  RR
4      bRTP!                  RTP!                  RR
4      4      bRTP!                  RR
4      bRTP!                  RR
4      bR\%        TP!                  RTP!                  RR
4      4      4      bRTP!                  RR
4      bR\'        T4      bRTP!                  RR
4      b4       EKÓ  	  T#   + '       g   i     ELõ; i  \         d    . u # i ; i  \        \        3 d	    RT/p EL¤i ; i)z5Parse newest log lines into table rows, newest first.r0   r1   r2   Nú | ÚrawÚ	timestampÚseen_atrz   r   Ú	client_ipÚfirmware_versionÚdevice_timeÚtimeÚpumprG   rH   rI   Úduration_secondsÚambient_temp_fÚhumidity_pctÚ	ds18b20_fÚnutrient_temp_fÚcommandÚevent)r;   ÚLOG_FILEr<   rq   Úreversedr   Ú	partitionÚastÚliteral_evalÚ
isinstanceÚdictr"   ÚSyntaxErrorÚappendr   r   rp   r%   Ú_temp_fÚ_event_label)
Úlimitri   rF   ÚentriesÚraw_linerˆ   Ú	separatorÚpayload_textr{   Úparseds
   &         r   Úread_log_entriesr§   ¼   s„  € ðÜ”(˜C¨'×2Õ2°dØ—N‘NÓ$ e V WÐ-ˆE÷ 3ð
 €GÜ˜U—OˆØ-5¯^©^Ó-=×-GÑ-GÈÓ-NÑ*ˆ	˜lØˆßð0Ü×)Ò)¨,Ó7�Ü˜f¤d×+Ò+Ø$�Gøð ˜hŸn™nÓ.Ð/ˆGà�‰ðØÔ/°	Ó:ðàÔ-¨iÓ8ðð ˜7Ÿ;™; y°"Ó5ðð ˜WŸ[™[¨°bÓ9ð	ð
 # G§K¡KÐ0BÀBÓ$Gðð Ô1°'·+±+¸fÀbÓ2IÓJðð ˜Ÿ™ F¨BÓ/ðð �w—{‘{ 5¨"Ó-ðð �w—{‘{ 5¨"Ó-ðð ˜GŸK™KØ&¨¯©°JÀÓ(Cóðð ! '§+¡+Ð.>ÀÓ"Cðð  §¡¨N¸BÓ ?ðð œWØ—K‘K ¨W¯[©[Ð9JÈBÓ-OÓPóðð$ ˜7Ÿ;™; y°"Ó5ð%ð& œ gÓ.ð'ð( �w—{‘{ 5¨"Ó-ð)÷	
ñ $ðJ €N÷W 3×2Ð2ûäô ØŠ	ðûô ¤Ð,ô 0Ø  ,Ð/“ð0ús?   ‚H1 œH±H1 Á7.IÈH.	È(H1 È.H1 È1IÉ IÉIÉIc                óv  € / p\        V R7       F|  p\        VP                  RR4      ;'       g    R4      P                  4       P	                  4       pV\
        9  d   KQ  W19   d   KY  W!V&   \        V4      \        \
        4      8X  g   K|   M	  . pR F"  pW19   g   K  VP                  W,          4       K$  	  V# )zv
Return the newest device check-in for each variant (full / light).
Skips dashboard-only events that have no variant.
)r¡   rz   r   )r   r   )r§   r   rp   r   rO   rw   r=   rž   )r¡   Ú
by_variantÚentryrz   Úordereds   &    r   Úlatest_checkins_by_variantr¬   í   s¤   € ð
 €JÜ!¨×.ˆÜ�e—i‘i 	¨2Ó.×4Ð4°"Ó5×;Ñ;Ó=×CÑCÓEˆØœ.Ô(ÙØÔ ÙØ#�7ÑÜˆz‹?œc¤.Ó1Ö1Ùñ /ð €GÛ$ˆØÖ Ø�N‰N˜:Õ.Ö/ñ %ð €Nr   c                ó  € \        V P                  RR4      ;'       g    R4      P                  4       pV'       d   V# \        V P                  RR4      ;'       g    R4      P                  4       pV'       d   VP                  4       R9  d   V# \        V P                  RR4      ;'       g    R4      P                  4       P                  4       pVR8X  d   R# \        V P                  RR4      ;'       g    R4      P                  4       pV# )	z=Pick the most useful Command / event cell text for a log row.r•   r   r”   rŽ   Úonzpump onr‡   >   rL   rN   Únull)r   rp   r   rO   )r{   r•   r”   rŽ   r‡   s   &    r   r    r      sÐ   € ä�—‘˜G RÓ(×.Ð.¨BÓ/×5Ñ5Ó7€EßØˆä�'—+‘+˜i¨Ó,×2Ð2°Ó3×9Ñ9Ó;€Gß�7—=‘=“?Ð*?Ô?Øˆäˆw�{‰{˜6 2Ó&×,Ð,¨"Ó-×3Ñ3Ó5×;Ñ;Ó=€DØˆt„|Ùä
ˆg�k‰k˜% Ó$×*Ð*¨Ó
+×
1Ñ
1Ó
3€CØ€Jr   c                óÈ   € \        T ;'       g    R4      P                  4       pV'       d   VP                  4       R9   d   R#  \        V4      R #   \         d    Tu # i ; i)zEReturn a displayable Fahrenheit value, or empty when missing/invalid.r   z.1f>   ÚinfÚnanrN   ú-inf)r   r   rO   Úfloatr"   rP   s   & r   rŸ   rŸ     sW   € äˆu�{ˆ{˜Ó×!Ñ!Ó#€Dß�4—:‘:“<Ð#AÔAÙðÜ˜“+˜cÐ"Ð#øÜô ØŠðús   ÁA ÁA!Á A!c                ó$   € V ^8„  d   QhR\         /# )é   rr   )rœ   )Úformats   "r   Ú__annotate__r¸   "  s   € ÷ 
'ñ 
'”Dñ 
'r   c                ó
  €  \         P                  P                  \        4      pV'       d>   \         P                  P	                  V4      '       g   \         P
                  ! VRR7       \        \        RRR7      ;_uu_ 4       p\        P                  ! 4       P                  R4      pVP                  V RV  R24       R	R	R	4       R	#   + '       g   i     R	# ; i  \         d   p\        R
T 24        R	p?R	# R	p?ii ; i)z4Append one line to log file with timestamp and data.Tr`   Úar1   r2   r'   r†   rd   NzLog write error: )r4   r5   rf   r–   Úisdirre   r;   r   Úutcnowr   rg   rC   Úprint)rr   Úlog_dirrD   ÚtsÚes   &    r   Ú	log_entryrÁ   "  s±   € ð'Ü—'‘'—/‘/¤(Ó+ˆßœ2Ÿ7™7Ÿ=™=¨×1Ò1Ü�KŠK˜¨$Õ/Ü”(˜C¨'×2Õ2°aÜ—’Ó"×+Ñ+Ð,CÓDˆBØ�G‰G�r�d˜#˜d˜V 2Ð&Ô'÷ 3×2×2Ò2ûô ô 'ÜÐ! ! Ð%×&Ò&ûð'ús@   ‚*C ­$C Á2C Â<C
Ã C Ã
C	ÃC ÃC ÃDÃ)C=Ã=DÚ/ÚGET)Úmethodsc                  ó&  € \        4       w  rp\        4       p\        V4      '       * p\        R T \        V4      '       d   RMTVVV\	        4       \
        P                  P                  RR4      \
        P                  P                  RR4      R7	      # )zfilldrain/index.htmlr   ÚmessageÚerror)rG   rH   Úon2_enabledrI   ry   Úlog_entriesrÆ   rÇ   )rJ   rs   r?   r   r§   r	   Úargsrp   )rG   rH   rI   ry   rÈ   s        r   ÚindexrË   /  s{   € ä&›Ñ€CˆhÜ‹€HÜ% cÓ*Ô*€KÜØØÜ! #×&Ò&‰B¨CØØØÜ$Ó&Ü—‘× Ñ  ¨BÓ/Ü�l‰l×Ñ˜w¨Ó+ô
ð 
r   z	/log.jsonc                 ó@   € \        R\        4       R\        4       /4      # )z7Newest device check-ins for the dashboard auto-refresh.r¢   ry   )r   r§   rs   © r   r   Úlog_jsonrÎ   A  s   € ô �IÔ/Ó1°:¼}»ÐOÓPÐPr   z	/settingsÚPOSTc                  ór  € \         P                  P                  R R4      p V R8X  d=   \        4        \	        RRR\        \        4      /4       \        \        RRR7      4      # V R	8w  d   \        \        RR
R7      4      # \         P                  P                  RR4      P                  4       p\         P                  P                  RR4      P                  4       p\         P                  P                  RR4      P                  4       p\         P                  P                  R4      R8H  p\        V4      '       g   \        \        RRR7      4      # V'       d(   \        V4      '       g   \        \        RRR7      4      # \        V4      '       g   \        \        RRR7      4      # \        V4      pV'       d   \        V4      M\        p\        W\        \!        V4      4      4       \        4        \	        RRR\        \        4      RVRVR\!        V4      RR/4       \        \        RRR7      4      # )Úactionr   rl   r•   Úreboot_queuedr€   zfilldrain.indexz!Reboot queued for Full and Light.)rÆ   Úsave_rebootzUnknown action.)rÇ   rG   rH   rI   Ú
enable_on2Ú1z(First start must be a valid HH:MM value.z6Second start must be a valid HH:MM value when enabled.z-Duration must be between 1 and 65535 seconds.Úsettings_savedr�   Tz1Settings saved; reboot queued for Full and Light.)r	   Úformrp   r‚   rÁ   Úsortedrw   r   r
   r   r>   rB   rA   r@   rj   r   rW   )rÑ   rG   rH   rI   rÔ   s        r   Úupdate_settingsrÙ   G  sà  € ä�\‰\×Ñ˜h¨Ó+€Fà�ÔÜŒÜ�7˜O¨Z¼ÄÓ9OÐPÔQÜÜØ!Ø;ôó
ð 	
ð �ÔÜœÐ 1Ð9JÔKÓLÐLä
�,‰,×
Ñ
˜5 "Ó
%×
+Ñ
+Ó
-€CÜ
�,‰,×
Ñ
˜5 "Ó
%×
+Ñ
+Ó
-€CÜ�|‰|×Ñ 
¨BÓ/×5Ñ5Ó7€HÜ—‘×!Ñ! ,Ó/°3Ñ6€JÜ�c�?Š?ÜÜÐ%Ð-WÔXó
ð 	
÷ œ* SŸ/š/ÜÜØ!ØNôó
ð 	
ô ˜(×#Ò#ÜÜØ!ØEôó
ð 	
ô ˜Ó
€Cß!+Œ.˜Ô
´€CÜ�3œS¤ X£Ó/Ô0Ü„NÜàÐ%Øœœ~Ó.Ø�3Ø�3Ø¤ H£Ø˜Tð	
ô	ô ÜØØGô	
óð r   z/syncc                 ó¨  € \         P                  R8X  Ed6   \         P                  '       Ed   \         P                  ! RR7      ;'       g    / p V P	                  RR4      pV P	                  RR4      pV P	                  RR4      pV P	                  RR4      pV P	                  R	R4      p\        V P	                  R
R4      4      P                  4       P                  4       pV P	                  RR4      pV P	                  RR4      pV P	                  RR4      p	V P	                  RR4      p
V P	                  RV P	                  RR4      4      pEMš\         P                  P	                  RR4      p\         P                  P	                  RR4      p\         P                  P	                  RR4      p\         P                  P	                  RR4      p\         P                  P	                  R	R4      p\         P                  P	                  R
R4      P                  4       P                  4       p\         P                  P	                  RR4      p\         P                  P	                  RR4      p\         P                  P	                  RR4      p	\         P                  P	                  RR4      p
\         P                  P	                  R\         P                  P	                  RR4      4      p\        V4      pR\         P                  R
T;'       g    RRVRVRVRVRVRVRVRV	RV
RVRVRV/p\        V4       \        4       w  rïpV RV RV RV R2pV^ÈRR/3# )zf
ESP32 sends status every five minutes.
Respond with four lines: on1, on2, duration_seconds, command.
rÏ   T)ÚsilentÚepochr   r�   rG   rH   rI   rz   r‹   rŽ   r�   r‘   r’   r“   rŠ   Úunknownr�   r”   rd   zContent-Typeztext/plain; charset=utf-8)r	   ÚmethodÚis_jsonÚget_jsonrp   r   r   rO   rÊ   r„   Úremote_addrrÁ   rJ   )rr   rÜ   Útime_strrG   rH   rI   rz   r‹   rŽ   r�   r‘   r“   r”   Úlog_dataÚs_on1Ús_on2Ú
s_durationÚbodys                     r   Úsyncrè   …  sÖ  € ô ‡~�~˜Õ¤G§O§O¡OÜ×Ò tÔ,×2Ð2°ˆØ—‘˜ "Ó%ˆØ—8‘8˜F BÓ'ˆØ�h‰h�u˜bÓ!ˆØ�h‰h�u˜bÓ!ˆØ—8‘8˜J¨Ó+ˆÜ�d—h‘h˜y¨"Ó-Ó.×4Ñ4Ó6×<Ñ<Ó>ˆØŸ8™8Ð$6¸Ó;ÐØ�x‰x˜ Ó#ˆØŸ™Ð"2°BÓ7ˆØ—x‘x °Ó3ˆØŸ(™(Ø˜Ÿ™Ð"3°RÓ8ó
Šô —‘× Ñ  ¨"Ó-ˆÜ—<‘<×#Ñ# F¨BÓ/ˆÜ�l‰l×Ñ˜u bÓ)ˆÜ�l‰l×Ñ˜u bÓ)ˆÜ—<‘<×#Ñ# J°Ó3ˆÜ—,‘,×"Ñ" 9¨bÓ1×7Ñ7Ó9×?Ñ?ÓAˆÜ"Ÿ<™<×+Ñ+Ð,>ÀÓCÐÜ�|‰|×Ñ ¨Ó+ˆÜ Ÿ™×)Ñ)Ð*:¸BÓ?ˆÜ—|‘|×'Ñ'¨¸Ó;ˆÜ!Ÿ,™,×*Ñ*ØœŸ™×)Ñ)Ð*;¸RÓ@ó
ˆô ˜gÓ&€Gà”W×(Ñ(Ø�7×'Ð'˜iØÐ,Ø�Ø�ØˆsØˆsØ˜HØ�Ø˜.Ø˜Ø�_Ø˜?Ø�7ð€Hô  ˆhÔä,›Ñ€E�*ØˆW�B�u�g˜R 
˜|¨2¨g¨Y°bÐ9€DØ��~Ð'BÐCÐCÐCr   )N)éú   )iô  )9Ú__doc__r™   rn   r4   rU   Ú	threadingr   r   Úzoneinfor   Úflaskr   r   r   r   r	   r
   Úconfigr   r   r   Ú__name__Úbpr7   rm   r–   r8   r9   r@   r:   rw   ÚLockr   r-   r   r%   r   rJ   r?   rA   r>   rB   rj   rs   r|   r‚   r„   r§   r¬   r    rŸ   rÁ   ÚrouterË   rÎ   rÙ   rè   rÍ   r   r   Ú<module>ró      sp  ðÙ KÛ 
Û Û 	Û 	Û ß 'Ý ç Q× Q÷ñ ñ ˆ{˜HÓ%€à'€Ø%€Ø€à€Ø€Ø€ØÐ Ø˜'Ð"€Ø�~Š~Ó€áÐ%Ó&€ò5òò"ò&:ò08òBòSòò)ò
/ò(ô!ò
ô.ôbò0ò$õ
'ð ‡�ˆ#˜�w€Óñó  ðð" ‡�ˆ+ ˜w€Ó'ñQó (ðQð
 ‡�ˆ+ ˜x€Ó(ñ:ó )ð:ðz ‡�ˆ'˜E 6˜?€Ó+ñ8Dó ,ò8Dr   