
    8Gj                        d Z ddlZddlZddlZddlZddlZddlZddlmZ dddddZ	e	d	         Z
 G d
 d          Z G d d          Zd Zd Zd ZddZd Zd Zd ZddZd Zd Zd Zd Zd Zedk    r e             dS dS )a  
SolarPower / EyBond Console Client
===================================
Reverse-engineered from SolarPower_1.6.1.0 APK.

Connects to the EyBond cloud API to:
  1. Log in with email or phone credentials
  2. List plants (solar installations)
  3. List devices (inverters/collectors) per plant
  4. Show device status and live data

API Gateway: http://cfb.eybond.com/cfb/api?action=...
Auth tokens: utoken (returned on login, sent as header)
    N)datetimezhttp://cfb.eybond.com/cfb/apizhttps://pro.eybond.comzhttps://pro2.eybond.comzhttps://pro3.eybond.com)cfbpropro2pro3r   c                   2    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
S )Cz[95mz[94mz[96mz[92mz[93mz[91mz[1mz[2mz[0mN)__name__
__module____qualname__HEADERBLUECYANGREENYELLOWREDBOLDDIMRESET      /root/solar/solarpower_client.pyr	   r	   (   s;        FDDEFCDCEEEr   r	   c                       e Zd ZdZefdZd"dZd Zd Zd Z	d	 Z
d
 Zd Zd#dZd Zd Zd Zd Zd Zd#dZd#dZd Zd Zd Zd Zd Zd Zd Zd$dZd%d Zd! ZdS )&SolarPowerClientz+Client for the EyBond SolarPower cloud API.c                     || _         t          j                    | _        | j        j                            ddd           d | _        d | _        d | _        d S )NzSolarPower/1.6.1.0 Androidzapplication/json)z
User-AgentAccept)	base_urlrequestsSessionsessionheadersupdateutokenztoken	user_info)selfr   s     r   __init__zSolarPowerClient.__init__;   sa     '))##6(%
 %
 	 	 	 r    GETc           	         d| }|r|d|                     d           z  }|                     |          }t          t          t	          j                                                    dz                      }| j        rz| j        rs|| j        z   | j        z   |z   }t          j
        |                    d                                                                                    }d| d| d| j         | }	ng }
| j        r<|
                    dt          j                            | j        d	
                      |
                    d|            |r(|
                    |                     d                     | j         dd                    |
           }	t)          dt*          j         d|                                 d|	 t*          j                    	 |                                dk    r| j                            |	d          }n| j                            |	d          }|                                 |                                S # t<          j        j         $ r\ t)          dt*          j!         d| j         t*          j                    t)          t*          j         dt*          j                    Y dS t<          j        j"        $ r- t)          dt*          j!         dt*          j                    Y dS t<          j        j#        $ r6}t)          dt*          j!         d| t*          j                    Y d}~dS d}~wt:          j$        $ rd t)          dt*          j!         dt*          j                    t)          t*          j         d|j%        dd          t*          j                    Y dS w xY w)zIMake an authenticated API request with the proper Shinemonitor signature.z&action=&  utf-8-http://android.shinemonitor.com/public/?sign=&salt=z&token=zutoken=r(   safezaction=?
z--> [z] r)      timeoutz[ERROR] Could not connect to z9Check your internet connection or try a different server.Nz[ERROR] Request timed out.z[ERROR] HTTP Error: z[ERROR] Invalid JSON response.zResponse text:   )&lstrip_get_base_actionstrintr   now	timestampr#   r$   hashlibsha1encode	hexdigestlowerappendurllibparsequoter   joinprintr	   r   upperr   r    getpostraise_for_statusjsonr   
exceptionsConnectionErrorr   Timeout	HTTPErrorJSONDecodeErrortext)r&   actionextra_paramsmethod
action_strbase_actionsalt
sign_inputsignurlpartsrespes                r   _requestzSolarPowerClient._requestF   s    )((
 	98l11#66888J ++J77 3x|~~//11D899:: ; 	74; 	7+dk9KGJ<
 1 1' : :;;EEGGMMOODu$uuduu[_[fuhsuuCC E{ SQv|'9'9$+B'9'O'OQQRRRLL+6++,,, 7\0055666]66SXXe__66C?15??v||~~???ag??@@@	||~~&&|''R'88|((b(99!!###99;;"2 	 	 	SquSS4=S!'SSTTTQU^^UVU\^^___44"* 	 	 	AquAAAABBB44", 	 	 	>qu>>!>QW>>???44444# 	 	 	EquEEAGEEFFFQUEE49TcT?EAGEEFFF44	s-   "A8I A,O
<O	O+MA2OOc                     d}d}| d| d| S )z3Construct the base action string with app metadata.zcom.eybond.solarpowerz1.6.1.0z8&i18n=en&lang=en&source=1&_app_client_=android&_app_id_=z&_app_version_=r   )r&   rW   app_idapp_versions       r   r9   z!SolarPowerClient._get_base_action   s*    (zzV\zzmxzzzr   c                 Z   d}t           j                            |d          }d| d| }|                     |          }t	          t          t          j                                                    dz                      }t          j
        |                    d                                                                                    }||z   |z   }	t          j
        |	                    d                                                                                    }
d|
 d	| | }|S )
zDBuild the complex login URL using Shinemonitor public API signature.bnrl_frRFjEz8Mknr(   r0   z&action=authSource&usr=z&company-key=r,   r-   r.   r/   )rD   rE   rF   r9   r:   r;   r   r<   r=   r>   r?   r@   rA   rB   )r&   usrpwdcompany_keyusr_encodedrW   rX   rY   pwd_sha1rZ   r[   r\   s               r   _build_login_urlz!SolarPowerClient._build_login_url   s   (l((2(66 W{VVVV
 ++J77 3x|~~//11D899:: <

7 3 344>>@@FFHH H_{2
|J--g6677AACCIIKK ^d]]$]P[]]
r   c                    |                      ||          }t          dt          j         d| t          j                    	 | j                            |d          }|                                 |                                }| 	                    |          S # t          $ r6}t          dt          j         d| t          j                    Y d}~dS d}~ww xY w)zLogin using email and password.r3   
--> [GET] r4   r5   [ERROR] Login request failed: NFrk   rH   r	   r   r   r    rJ   rL   rM   _handle_login_response	Exceptionr   )r&   emailpasswordr\   r^   datar_   s          r   login_by_emailzSolarPowerClient.login_by_email       ##E84421522C222333	<##C#44D!!###99;;D..t444 	 	 	HquHHAHqwHHIII55555	   AB 
C&+CCc                    |                      ||          }t          dt          j         d| t          j                    	 | j                            |d          }|                                 |                                }| 	                    |          S # t          $ r6}t          dt          j         d| t          j                    Y d}~dS d}~ww xY w)z&Login using phone number and password.r3   rm   r4   r5   rn   NFro   )r&   phoners   r\   r^   rt   r_   s          r   login_by_phonezSolarPowerClient.login_by_phone   rv   rw   c                    |dS t          dt          j         dt          j        |dd          dd          t          j                    d}t          |t                    r|                    d|                    d	|                    d
|                    dd                                        }|                    d|                    d|                    d|                    dd                                        }|dk    s|dk    s|dk    s|dk    r|                    d|                    d|                    }|                    d|                    d|                    dd                              | _	        |                    d|                    dd                    | _
        || _        d}ntd|v r@|                    dd          | _	        |                    dd          | _
        || _        d}n0t          dt          j         d| d| t          j                    dS |r| j	        rt          dt          j         t          j         d t          j                    t          d!t          j         d"| j	        dd#          d$t          j                    | j
        r9t          d!t          j         d%| j
        dd#          d$t          j                    dS |r+t          dt          j         d&t          j                    dS t          dt          j         d't          j                    dS )(z*Process login response and extract tokens.NFr3   zRaw response:    indentensure_asciir,   codestatuserrCodeerrmsgmessageerrMsgdescr(   r      0200rt   datr#   tokenaccess_tokenr$   secretTz[LOGIN FAILED] Code: z, Message: u   ✔ Login successful!  zutoken: (   z...zztoken: z/[WARNING] Login response OK but no token found.z*[LOGIN FAILED] Unexpected response format.)rH   r	   r   rM   dumpsr   
isinstancedictrJ   r#   r$   r%   r   r   r   r   )r&   rt   successr   r   inners         r   rp   z'SolarPowerClient._handle_login_response   s   <5 	h15hh
4PU(V(V(VW\X\W\(]h_`_fhhiii  dD!! 	88FDHHXtxx	488TY[]K^K^7_7_$`$`aaD((5$((9dhhxRXZ\I]I]6^6^"_"_``CqyyDCKK43;;$%--%)>)>??#ii%))GUYY~_aEbEb2c2cdd#ii%))Hb2I2IJJ!&T!!"hhx44"hhx44!%V15VVtVVVQWVVWWWu 	t{ 	FqwFFFQWFFGGGDquDDdk#2#&6DD17DDEEE{ JH15HH$+crc*:HHqwHHIII4 	YqxYYPQPWYYZZZ4QquQQQQRRR5r   c                 ,    |                      d          S )zGet the total number of plants.queryPlantCountr`   r&   s    r   get_plant_countz SolarPowerClient.get_plant_count   s    }}.///r   r   
   c                 :    |                      dd| d|           S )z)Get list of plants (solar installations).webQueryPlants&page=
&pagesize=r   r&   pagepagesizes      r   
get_plantszSolarPowerClient.get_plants   s(    }}-/R/R/R/R/RSSSr   c                 4    |                      dd|           S )z'Get detailed info for a specific plant.queryPlantInfoplantid=r   )r&   plant_ids     r   get_plant_infozSolarPowerClient.get_plant_info   s     }}-/D(/D/DEEEr   c                 ,    |                      d          S )z'Get today's energy data for all plants.queryPlantsEnergyDayr   r   s    r   get_plants_energy_dayz&SolarPowerClient.get_plants_energy_day   s    }}3444r   c                 ,    |                      d          S )z/Get current active output power for all plants."queryPlantsActiveOuputPowerCurrentr   r   s    r   get_plants_active_powerz(SolarPowerClient.get_plants_active_power   s    }}ABBBr   c                 4    |                      dd|           S )z@Get output power history curve for all plants on a specific day.!queryPlantsActiveOuputPowerOneDayzdate=r   )r&   dates     r   get_plants_active_power_one_dayz0SolarPowerClient.get_plants_active_power_one_day   s    }}@.$..QQQr   c                 ,    |                      d          S )z Get the total number of devices.queryDeviceCountr   r   s    r   get_device_countz!SolarPowerClient.get_device_count      }}/000r   c           	      @    |                      dd| d| d|           S )z!Get devices for a specific plant.queryDevicesr   r   r   r   r&   r   r   r   s       r   get_deviceszSolarPowerClient.get_devices  s0    }}^-b-b-b-b-bX`-b-bcccr   c           	      @    |                      dd| d| d|           S )z$Get collectors for a specific plant.queryCollectorsz	pagesize=r   z	&plantid=r   r   s       r   get_collectorszSolarPowerClient.get_collectors	  s1    }}.0eH0e0eD0e0e[c0e0efffr   c                 4    |                      dd|           S )z.Get devices connected to a specific collector.queryCollectorDevicespn=r   r&   pns     r   get_collector_devicesz&SolarPowerClient.get_collector_devices  s    }}4jBjjAAAr   c                 4    |                      dd|           S )z/Get status of devices connected to a collector.queryCollectorDevicesStatusr   r   r   s     r   get_collector_devices_statusz-SolarPowerClient.get_collector_devices_status  s    }}:J"JJGGGr   c                 F    |                      dd| d| d| d|           S )z+Get last known data from a specific device.querySPDeviceLastDatar   	&devcode=	&devaddr=&sn=r   r&   r   devcodedevaddrsns        r   get_device_last_dataz%SolarPowerClient.get_device_last_data  sA    }}4S2SSSS'SSrSSU U 	Ur   c                 F    |                      dd| d| d| d|           S )z"Get energy flow data for a device.webQueryDeviceEnergyFlowEsr   r   r   r   r   )r&   r   r   r   r   s        r   get_device_energy_flowz'SolarPowerClient.get_device_energy_flow  sA    }}9S2SS2SSSS'SSU U 	Ur   c                 L    |                      dd| d| d| d| d| 
          S )z,Get one day of historical data for a device.queryDeviceDataOneDayr   r   r   r   z&date=r   )r&   r   r   r   r   r   s         r   get_device_data_one_dayz(SolarPowerClient.get_device_data_one_day  sJ    }}4_2____R__'__Y]__a a 	ar   c                 F    |                      dd| d| d| d|           S )z%Get controllable fields for a device.webQueryDeviceCtrlFieldr   r   r   r   r   r   s        r   get_device_ctrl_fieldsz'SolarPowerClient.get_device_ctrl_fields$  sA    }}6S2SSSS'SSrSSU U 	Ur   c                 ,    |                      d          S )z Get current account information.queryAccountInfor   r   s    r   get_account_infoz!SolarPowerClient.get_account_info)  r   r   2   Nc                 R    d| d| }|r|d| z  }|                      d|          S )z)Query all devices (Elasticsearch-backed).r   r   z&pn=webQueryDeviceEsr   )r&   r   r   r   paramss        r   web_query_devicesz"SolarPowerClient.web_query_devices/  sD    4$44(44 	"kRkk!F}}/888r   c                 <    |                      dd| d| d          S )z,Query all collectors (Elasticsearch-backed).webQueryCollectorsEsr   r   z	&loaded=2r   r   s      r   web_query_collectorsz%SolarPowerClient.web_query_collectors6  s4    }}3IdIIhIIIK K 	Kr   c                 ,    |                      d          S )zQuery device status view.webQueryDeviceStatusViewEsr   r   s    r   web_query_device_statusz(SolarPowerClient.web_query_device_status;  s    }}9:::r   )r(   r)   )r   r   )r   r   N)r   r   )r
   r   r   __doc__BASE_URLr'   r`   r9   rk   ru   rz   rp   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   8   s       55 ( 	 	 	 	5 5 5 5r{ { {  2    + + +^0 0 0T T T TF F F5 5 5C C CR R R1 1 1d d d dg g g gB B BH H HU U U
U U U
a a a
U U U
1 1 19 9 9 9K K K K
; ; ; ; ;r   r   c                  v    dt           j         t           j         dt           j         d} t	          |            d S )Nr3   u  ╔══════════════════════════════════════════════════════╗
║          ☀  SolarPower Console Client  ☀             ║
║          EyBond API v1.6.1.0 (RE'd)                  ║
╚══════════════════════════════════════════════════════╝)r	   r   r   r   rH   )banners    r   print_bannerr   D  sP    	
  jk  jq	  F 
&MMMMMr   c                     t          dt          j         t          j         d            t          d|             t          d t          j                    d S )Nr3   u   ──────────────────────────────────────────────────r   )rH   r	   r   r   r   )titles    r   print_sectionr   N  s\    	
+qv
+qv
+z
+
+,,,	,u,,	Z
"
"
"#####r   c           
         |s+t          dt          j         dt          j                    dS d | D             }|D ]]}t	          |          D ]K\  }}|t          |          k     r3t          ||         t          t          |                              ||<   L^d}t	          |           D ]/\  }}|t          j         |d||          t          j         dz  }0t          |           t          dd	                    d |D                                   |D ]Z}d}t	          |          D ]7\  }}|t          |          k     r|t          |          d||          dz  }8t          |           [dS )z'Print a formatted table to the console.r   z	(no data)Nc                 ,    g | ]}t          |          S r   )len).0hs     r   
<listcomp>zprint_table.<locals>.<listcomp>[  s    &&&c!ff&&&r   <c                     g | ]}d |z  S )u   ─r   )r   ws     r   r   zprint_table.<locals>.<listcomp>f  s    444%!)444r   )
rH   r	   r   r   	enumerater   maxr:   r   rG   )	r!   rowswidthsrowicellheader_liner   lines	            r   print_tabler  T  s    ,15,,17,,--- '&g&&&F ; ; ~~ 	; 	;GAt3v;;q	3s4yy>>::q		;
 K'"" > >1!&=!=fQi===!'====	+	
7tyy44V44455
7
7888    ~~ 	6 	6GAt3v;;3t995vay555555d r   c                    | g S |g d}t          | t                    r| S t          | t                    r|                     d|                     d|                     }|D ]q}||v rk||         }t          |t                    r|c S t          |t                    r5|D ]-}||v r't          ||         t                    r||         c c S .|gc S rd| v sd| v rg S | gS g S )z5Extract list items from various API response formats.N)rt   r   r   listitemsresultrecordsplantsdevices
collectorsplantdevice	collectorr   rt   r   r   )r   r  r   rJ   )rt   key_candidatesr   keyvalk2s         r   extract_itemsr  q  s2   |	] ] ] $ $  6 677 " 
	! 
	!Ce||Cjc4(( !JJJT** !, + +99CGT)B)B9#&r7NNNNN5LLL T>>X--I vIr   c                    t          d           |                                 }|r|                    d|                    d|                    }|                    d|                    dd                    }t          dt          j         d| t          j                    |                     d	d
          }|+t          dt          j         dt          j                    g S t          |          }|srt          dt          j
         dt          j                    t          dt          j         t          j        |dd          dd          t          j                    g S g d}g }t          |          D ]q\  }}	|	                    d|	                    d|	                    d|	                    dd                                        }
|	                    d|	                    dd                    }|	                    d|	                    d|	                    dd                              }|	                    d|	                    dd                    }|	                    di           }t          |t                     r+|                    d|                    d d                    }n|rt#          |          nd}|                    |d!z   |
||||g           st'          ||           |S )"zFetch and display all plants.zSolar Plantsr   rt   counttotalr2   r   zTotal plants: r   r   r   r   NzFailed to fetch plants.zNo plants found. Raw response:r|   Fr}      )#Plant IDNameCapacityStatusLocationpidplantidplantIdidname	plantNamenominalPowercapacityinstalledCapacityr   plantStatusaddresscountry   )r   r   rJ   rH   r	   r   r   r   r   r  r   r   rM   r   r   r   r   r:   rC   r  )client
count_datar   r  plants_datar	  r!   r   r   pr  r#  capr   addrlocations                   r   display_plantsr3    s   .!!! ''))J <ujnnVZ&H&HII		'599Wc#:#:;;:17::%:::;;; ##R#88K:15::::;;;	;''F D18DD17DDEEE`15`$*[OOOPTQTPTU`WXW^``aaa	 JIIGD&!! 
? 
?1eeE155AEE)QUU4=M=M,N,NOOPPuuVQUU;4455eeNAEE*aee<OQT6U6U$V$VWWx}c!:!:;;uuY##dD!! 	2xx	488Is+C+CDDHH$(1s4yyycHQUCsFH=>>>>Mr   c           
         |                     d|                     d|                     d                              }|                     d|                     dd                    }t          d| d| d	           |                     |d
d          }t          |          }|st	          dt
          j         dt
          j                    |                     |d
d          }t          |          }|r
t	          dt
          j	         dt          |           dt
          j                    g d}g }	t          |          D ]\  }
}|                     d|                     dd                    }|                     d|                     dd                    }|                     dd          }|                     d|                     dd                    }|	                    |
dz   ||||g           t          ||	           |D ]}|                     d|                     d                    }|r|                     |          }t          |          }|r;t	          dt
          j         d| dt
          j                    t!          |           |                     |          }|rLt          |          }|r;t	          dt
          j         d| dt
          j                    t!          |           nt	          dt
          j         dt
          j                    |rHt	          dt
          j         dt'          j        |dd !          d"d#          t
          j                    |rHt	          dt
          j         d$t'          j        |dd !          d"d#          t
          j                    nt!          |           |S )%z,Fetch and display devices for a given plant.r   r!  r"  r#  r$  r2   zDevices for Plant: z (ID: )r   r   r  r   zTrying collectors endpoint...
  zFound z collector(s):)r  PNAliasr  Onliner   collectorPnaliasr   onlineisOnliner+  zDevices on collector :zDevice status on collector zNo devices or collectors found.zDevices response: r|   Fr}   Nr7   zCollectors response: )rJ   r   r   r  rH   r	   r   r   r   r   r   r   rC   r  r   r   display_device_listr   r   rM   r   )r,  r  r  pnamedevices_datar
  collectors_datar  r!   r   r   colr   r;  r   r<  col_devices_datacol_devicesstatus_datastatusess                       r   display_devices_for_plantrH    s   
))IuyyEIIdOODD
E
ECIIfeiiS99::E;;;S;;;<<< %%cB%??LL))G *%@15@@qw@@AAA //!b/II"?33
 "	CPPPJPPqwPPQQQ>>>GD#J// @ @3WWT377=##>#>??)=)=>>3//377:s+C+CDDQUBvv>????&&& " : :WWT377=#9#9:: :'-'C'CB'G'G$"/0@"A"AK" 9PQVPP"PPqwPPQQQ+K888 #)"E"Eb"I"IK" :#0#=#=# :!"Z"Z"ZB"Z"ZQRQX"Z"Z[[[/999:" IqxIIIIJJJ }{15{{DJ|TUdi4j4j4jkoloko4p{rsry{{||| C  B15  B  Btz/Z[jo7p7p7pquruqu7v  Bxyx  B  B  C  C  CG$$$Nr   c                 ^   g d}g }t          |           D ]\  }}|                    d|                    d|                    dd                              }|                    d|                    d|                    dd                              }|                    d	|                    d
|                    d|                    dd                                        }|                    d|                    dd                    }|                    d|                    dd                    }	|                    d|                    d|                    dd                              }
|                    |dz   |||||	|
g           t          ||           dS )z*Display a list of devices in table format.)r  SNz
Name/AliasTypeDevCodeDevAddrr  r   deviceSnserialNumberr2   r;  r#  
deviceNamedevTypeName
deviceTypetypedeviceTypeNamer   
deviceCoder   
deviceAddrr   deviceStatus	runStatusr+  N)r   rJ   rC   r  )r
  r!   r   r   dr   r;  dtyper   r   r   s              r   r?  r?    s{   OOOGD'"" I I1UU4z155+E+EFFGGgquuVQUU<-E-EFFGGmQUU<vquuM]_bGcGc9d9d%e%eff%%	155s#;#;<<%%	155s#;#;<<x~quu[#7N7N!O!OPPQUBugwGHHHHr   c           
         |                     d|                     dd                    }|                     d|                     dd                    }|                     d|                     dd                    }|p)|                     d|                     d	d                    }t          ||||g          s+t          d
t          j         dt          j                    dS t          d|            |                     ||||          }|rt          |          }|rd|D ]_}	t          |	t                    rH|	                                D ]3\  }
}t          d
t          j         |
dt          j         d|            4`dS t          d
t          j         t          j        |dd          dd          t          j                    dS t          d
t          j         dt          j                    dS )z2Fetch and display live data for a specific device.r   rN  r(   r   rU  r   rV  r   r:  r   z3Missing device identifiers (sn/devcode/devaddr/pn).NzLive Data for Device: z<30 r|   Fr}     zFailed to fetch device data.)rJ   allrH   r	   r   r   r   r   r  r   r   r  r   r   rM   r   r   )r,  r  r   r   r   r   pn_valrt   r  itemkvs               r   display_device_datarc    s   	D&**Z44	5	5BjjFJJ|R$@$@AAGjjFJJ|R$@$@AAGB6::dFJJ}b$A$ABBFGWf-.. Y18YYPQPWYYZZZ/2//000&&vwDDD 
Ad## 	` A AdD)) A $

 A A1?16?1??!'??A??@@@@A A
 ^qu^djaeLLLUdUS^UVU\^^_____?15??ag??@@@@@r   c           	         t          d           |                     dd          }|+t          dt          j         dt          j                    g S t          |          }|rt          |           npt          dt          j         dt          j                    t          dt          j	         t          j        |d	d
          dd          t          j                    |S )z<Fetch and display all devices across all plants (web query).zAll Devices (Web Query)r   r   r  Nr   zFailed to fetch devices.zNo devices found. Raw response:r|   Fr}   r  )r   r   rH   r	   r   r   r  r?  r   r   rM   r   )r,  rt   r
  s      r   display_all_devicesre  &  s    +,,,##R#88D|;15;;!';;<<<	D!!G [G$$$$E18EEAGEEFFFY15Y$*T!%HHH#NYPQPWYYZZZNr   c           	      j   t          d           |                     dd          }|+t          dt          j         dt          j                    dS t          |          }|rg d}g }t          |          D ]\  }}|                    d	|                    d
d                    }|                    d|                    dd                    }|                    dd          }	|                    d|                    dd                    }
|	                    |dz   |||	|
g           t          ||           dS t          dt          j         dt          j                    t          dt          j         t          j        |dd          dd          t          j                    dS )z!Fetch and display all collectors.zAll Collectors (Web Query)r   r   r  Nr   zFailed to fetch collectors.)r  r7  r8  r  r  r   r:  r2   r;  r#  r   r   r!  r+  z"No collectors found. Raw response:r|   Fr}   r  )r   r   rH   r	   r   r   r  r   rJ   rC   r  r   r   rM   r   )r,  rt   r  r!   r   r   rC  r   r;  r   r  s              r   display_all_collectorsrg  7  s   .///&&A&;;D|>15>>QW>>???t$$J [<<<
++ 	9 	9FAssww}c::;;BGGGSWWVS%9%9::EWWXs++F'')SWWY%<%<==CKKQE6378888GT"""""H18HHqwHHIIIY15Y$*T!%HHH#NYPQPWYYZZZZZr   c           	      &   t          d           |                                 }|r|                    d|          }t          |t                    rN|                                D ]7\  }}|dvr.t          dt          j         |dt          j	         d|            8d
S t          dt          j
         t          j        |dd	          d
d          t          j	                    d
S t          dt          j         dt          j	                    d
S )z&Fetch and display account information.zAccount Informationrt   )r   r   r   r   r   z<25r\  r|   Fr}   Nr  zFailed to fetch account info.)r   r   rJ   r   r   r  rH   r	   r   r   r   rM   r   r   )r,  rt   infora  rb  s        r   display_account_inforj  O  s%   '(((""$$D 	Bxx%%dD!! 	_

 = =1@@@;qv;q;;ag;;;;<<<= = ]qu]djaeLLLTcTR]TUT[]]^^^^^@15@@qw@@AAAAAr   c           	      0   	 t          dt          j         t          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         d	t          j         dt          j                    t          t          j         dt          j         d
t          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         dt          j         dt          j         dt          j                    t          t          j         t          j         dt          j                    t          dt          j         dt          j                                                   }|dk    rt          |           }nA|dk    r|st          |           }|r	 t          dt          |           d                                          }|rt          |          dz
  nd}d|cxk    rt          |          k     rn nt          | ||                    n)t          dt          j         dt          j                    n# t          $ r- t          dt          j         dt          j                    Y nJw xY wnD|dk    rt          |           }n-|dk    rt          |            n|dk    rt          |            n|dk    rnt!          d            |                                 }|rGt          dt          j         t'          j        |d!d"#          d$d%          t          j                    n|d&k    rnt!          d'           |                                 }|rGt          dt          j         t'          j        |d!d"#          d$d%          t          j                    n|d(k    r|st          |           }|r	 t          d)t          |           d                                          }|rt          |          dz
  nd}d|cxk    rt          |          k     rn nt-          | ||                    n)t          dt          j         dt          j                    nV# t          $ r- t          dt          j         dt          j                    Y n w xY wn|d*k    rt          d+                                          }|s&t/          j                                        d,          }t!          d-|            |                     |          }|rGt          dt          j         t'          j        |d!d"#          d$d.          t          j                    nY|d/k    rS|st          |           }|r>	 t          d)t          |           d                                          }|rt          |          dz
  nd}d|cxk    rt          |          k     run nq||         }|                    d0|                    d1d2                    }	|                    d3|                    d4d2                    }
|                    d5|                    d6d2                    }|                    d7|                    d8d2                    }t          d+                                          }|s&t/          j                                        d,          }t!          d9|	 d:|            |                     ||
|	||          }|rGt          dt          j         t'          j        |d!d"#          d$d.          t          j                    n)t          dt          j         dt          j                    n:# t          $ r- t          dt          j         dt          j                    Y nw xY wn|d;k    rt          d<                                          }t          d=                                          }|rYt!          d>|            |                     ||          }|r/t          dt'          j        |d!d"#          d$d.                     n[|d?k    r,t          dt          j         d@t          j         d           d$S t          dt          j         dAt          j                    )Bz*Show interactive menu for further actions.Tr3   u   ┌─ Menu ──────────────────────────────────────┐u   │z-  1. Refresh plants list                     z-  2. Show devices for a plant                z-  3. Show all devices (web query)            z-  4. Show all collectors                     z-  5. Show account info                       z-  6. Show current active power               z-  7. Show today's energy                     z-  8. Show device live data                   z-  9. Show plant history curve for a day      z- 10. Show device history data for a day      z- 11. Raw API call (custom action)            z-  0. Exit                                    u   └─────────────────────────────────────────────┘zSelect option: 12z  Enter plant number (1-z) [1]: r+  r   r   zInvalid selection.zInvalid input.3456zCurrent Active Output Powerr|   Fr}   Nr]  7zToday's Energy Data8z  Enter device number (1-9z#  Enter date (YYYY-MM-DD) [today]: z%Y-%m-%dzPlant History Curve for i  10r   rN  r(   r   rU  r   rV  r   r:  zDevice History for z on 11z  Enter action name: z$  Enter extra params (key=val&...): zCustom API Call: r   u   Goodbye! ☀zInvalid option.) rH   r	   r   r   r   inputstripr3  r   r;   rH  r   
ValueErrorre  rg  rj  r   r   r   rM   r   r   rc  r   r<   strftimer   rJ   r   r`   r   r   )r,  r	  all_deviceschoiceidx_stridxrt   date_strr  r   r   r   r   rT   r   s                  r   interactive_menur  _  s'   w;  n16  n16  n  n  ef  el  n  n  	o  	o  	offAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffgggffAGffRSRXff]^]dffggg  x  x  x  op  ov  x  x  	y  	y  	y<AF<<17<<==CCEES==#F++FFs]] 0'// 	??#$Ss6{{$S$S$STTZZ\\G.5<#g,,**1CC----#f++-----1&&+FFFFE15EEAGEEFFF! ? ? ?=qu==AG==>>>>>?	? s]]-f55KKs]]"6****s]] ((((s]]78881133D db15b$*T!%"P"P"PQVRVQV"WbYZY`bbcccs]]/000//11D db15b$*T!%"P"P"PQVRVQV"WbYZY`bbcccs]] :1&99 	??#$YK@P@P$Y$Y$YZZ``bbG.5<#g,,**1CC2222#k"2"222222+FK4DEEEEE15EEAGEEFFF! ? ? ?=qu==AG==>>>>>?	? s]]CDDJJLLH ?#<>>22:>>?X??@@@99(CCD db15b$*T!%"P"P"PQVRVQV"WbYZY`bbccct^^ :1&99 ??#$YK@P@P$Y$Y$YZZ``bbG.5<#g,,**1CC2222#k"2"222222!,S!1#ZZfjjR.H.HII"(**Y

<QS8T8T"U"U"(**Y

<QS8T8T"U"U#ZZfjj.K.KLL#()O#P#P#V#V#X#X' K'/|~~'>'>z'J'JH%&NB&N&NH&N&NOOO%==b'2wX`aa p!"nqu"ndjaV[.\.\.\]b^b]b.c"nefel"n"noooE15EEAGEEFFF! ? ? ?=qu==AG==>>>>>?+?0 t^^344::<<FBCCIIKKF X:&::;;;vv66 XVtz$quMMMeteTVVWWWs]]7qw77AG777888E9qx9999:::ow;s9   /B%R 3SSB%[   3[76[7Hg 3hhc                      t                       t          d         } t          |           }t          dt          j         dt          j                    t          dt          j         dt          j                                                   }t          j	        dt          j         dt          j                   }|r|s=t          dt          j
         dt          j                    t          j        d           |                    ||          }|set          d	t          j
         d
t          j                    t          t          j         dt          j                    t          j        d           t          d	t          j         d            t          d           t          d t          j                    t!          |          }t#          |          }|r|st%          ||d                    t'          |||           d S )Nr   r6  zLogin (Email + Password)r   zEmail: z
Password: z Email and password are required.r+  r3   z:Login failed. Please check your credentials and try again.z9If the API server is unreachable, try a different server.u   ══════════════════════════════════════════════════z*  Fetching your solar installation data...r   )r   API_SERVERSr   rH   r	   r   r   rw  rx  getpassr   sysexitru   r   r   r3  re  rH  r  )r   r,  rr   rs   r   r	  r{  s          r   mainr    s   NNN 5!Hh''F 

:
:
:
:
:;;;/qv//ag//006688E?AF??ag??@@H  C15CC!'CCDDD##E844G ]15]]TUT[]]^^^ZZQRQXZZ[[[ 

$qw
$

$
$%%%	
7888	Z
"
"
"### F##F &f--K  5k 5!&&)444 VV[11111r   __main__)N)r   r   rM   r  r  r>   urllib.parserD   r   r  r   r	   r   r   r   r  r  r3  rH  r?  rc  re  rg  rj  r  r  r
   r   r   r   <module>r     s      



             ,$%%	  u	 	 	 	 	 	 	 	 E; E; E; E; E; E; E; E;X  $ $ $  :$ $ $ $N' ' 'T6 6 6r   A A A A6  "[ [ [0B B B y; y; y;@)2 )2 )2X zDFFFFF r   