Skip to content

Commit da42c7a

Browse files
committed
trottle login attempts after consecutive fails
1 parent 6b230f1 commit da42c7a

File tree

9 files changed

+62
-53
lines changed

9 files changed

+62
-53
lines changed

hardware/EvohomeBase.cpp

100755100644
File mode changed.

hardware/EvohomeBase.h

100755100644
File mode changed.

hardware/EvohomeWeb.cpp

100755100644
Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
#include "../json/json.h"
2525
#include <string>
2626

27+
28+
#define LOGONFAILTRESHOLD 3
29+
#define MAXPOLINTERVAL 3600
30+
2731
extern std::string szUserDataFolder;
2832

2933
const uint8_t CEvohomeWeb::m_dczToEvoWebAPIMode[7]={0,2,3,4,6,1,5};
@@ -44,6 +48,7 @@ CEvohomeWeb::CEvohomeWeb(const int ID, const std::string &Username, const std::s
4448
m_loggedon=false;
4549
m_tzoffset=-1;
4650
m_lastDST=-1;
51+
m_logonfailures=0;
4752

4853
Init();
4954
}
@@ -67,16 +72,25 @@ void CEvohomeWeb::Init()
6772

6873
bool CEvohomeWeb::StartSession()
6974
{
75+
_log.Log(LOG_NORM, "EvohomeWeb: connect to Evohome server");
7076
m_loggedon=false;
7177
if (!login(m_username,m_password))
78+
{
79+
m_logonfailures++;
80+
if (m_logonfailures > LOGONFAILTRESHOLD)
81+
_log.Log(LOG_STATUS, "EvohomeWeb: logon fail treshold reached - trottling");
82+
if ((m_logonfailures * m_refreshrate) > MAXPOLINTERVAL)
83+
m_logonfailures--;
7284
return false;
85+
}
7386
full_installation();
7487
m_tcs = NULL;
7588
if (is_single_heating_system())
7689
m_tcs = &locations[0].gateways[0].temperatureControlSystems[0];
7790

7891
m_zones[0] = 0;
7992
m_loggedon=true;
93+
m_logonfailures=0;
8094
return true;
8195
}
8296

@@ -110,6 +124,7 @@ bool CEvohomeWeb::StopHardware()
110124
void CEvohomeWeb::Do_Work()
111125
{
112126
int sec_counter = m_refreshrate - 10;
127+
int pollcounter = LOGONFAILTRESHOLD;
113128
_log.Log(LOG_STATUS, "EvohomeWeb: Worker started...");
114129
while (!m_stoprequested)
115130
{
@@ -118,9 +133,10 @@ void CEvohomeWeb::Do_Work()
118133
if (sec_counter % 10 == 0) {
119134
m_LastHeartbeat=mytime(NULL);
120135
}
121-
if (sec_counter % m_refreshrate == 0)
136+
if ( (sec_counter % m_refreshrate == 0) && (pollcounter++ > m_logonfailures) )
122137
{
123-
GetStatus();
138+
if (GetStatus())
139+
int pollcounter = LOGONFAILTRESHOLD;
124140
}
125141
}
126142
_log.Log(LOG_STATUS,"EvohomeWeb: Worker stopped...");
@@ -157,16 +173,14 @@ bool CEvohomeWeb::WriteToHardware(const char *pdata, const unsigned char length)
157173
}
158174

159175

160-
void CEvohomeWeb::GetStatus()
176+
bool CEvohomeWeb::GetStatus()
161177
{
162178
if (!m_loggedon && !StartSession())
163-
return;
179+
return false;
164180
if (!get_status(m_tcs->locationId))
165181
{
166-
//FIXME: should I distinguish between simple HTTP errors and session related errors?
167-
_log.Log(LOG_ERROR,"Evohome: failed to retrieve status");
168182
m_loggedon = false;
169-
return;
183+
return false;
170184
}
171185

172186
// system status
@@ -179,17 +193,19 @@ void CEvohomeWeb::GetStatus()
179193
// hot water status
180194
if (has_dhw(m_tcs))
181195
DecodeDHWState(m_tcs);
196+
197+
return true;
182198
}
183199

184200

185201
bool CEvohomeWeb::SetSystemMode(uint8_t sysmode)
186202
{
187203
if (set_system_mode(m_tcs->systemId, (int)(m_dczToEvoWebAPIMode[sysmode])))
188204
{
189-
_log.Log(LOG_STATUS,"Evohome: changed system status to %s",GetControllerModeName(sysmode));
205+
_log.Log(LOG_STATUS,"EvohomeWeb: changed system status to %s",GetControllerModeName(sysmode));
190206
return true;
191207
}
192-
_log.Log(LOG_ERROR,"Evohome: error changing system status");
208+
_log.Log(LOG_ERROR,"EvohomeWeb: error changing system status");
193209
m_loggedon = false;
194210
return false;
195211
}
@@ -206,7 +222,7 @@ bool CEvohomeWeb::SetSetpoint(const char *pdata)
206222
zone* hz=get_zone_by_ID(zoneId);
207223
if (hz == NULL) // zone number not known by installation (manually added?)
208224
{
209-
_log.Log(LOG_ERROR,"Evohome: attempt to change setpoint on unknown zone");
225+
_log.Log(LOG_ERROR,"EvohomeWeb: attempt to change setpoint on unknown zone");
210226
return false;
211227
}
212228

@@ -257,7 +273,7 @@ bool CEvohomeWeb::SetDHWState(const char *pdata)
257273
{
258274
if (!has_dhw(m_tcs)) // Installation has no Hot Water device
259275
{
260-
_log.Log(LOG_ERROR,"Evohome: attempt to set state on non existing Hot Water device");
276+
_log.Log(LOG_ERROR,"EvohomeWeb: attempt to set state on non existing Hot Water device");
261277
return false;
262278
}
263279

@@ -363,7 +379,7 @@ void CEvohomeWeb::DecodeZone(zone* hz)
363379
{
364380
m_sql.safe_query("UPDATE DeviceStatus SET Name='%q' WHERE (ID == %" PRIu64 ")", zonedata["name"].c_str(), DevRowIdx);
365381
if (sdevname.find("zone ")!=std::string::npos)
366-
_log.Log(LOG_STATUS,"Evohome: register new zone '%c'", zonedata["name"].c_str());
382+
_log.Log(LOG_STATUS,"EvohomeWeb: register new zone '%c'", zonedata["name"].c_str());
367383
}
368384
}
369385

@@ -470,7 +486,7 @@ uint8_t CEvohomeWeb::GetUnit_by_ID(unsigned long evoID)
470486
return row;
471487
}
472488
}
473-
_log.Log(LOG_ERROR,"Evohome: cannot add new zone because you have no free zones left");
489+
_log.Log(LOG_ERROR,"EvohomeWeb: cannot add new zone because you have no free zones left");
474490
}
475491
return -1;
476492
}
@@ -512,7 +528,7 @@ std::string CEvohomeWeb::local_to_utc(std::string local_time)
512528

513529

514530
/*
515-
* Evohome client API
531+
* Evohome client API starts here
516532
*/
517533

518534
/*
@@ -528,8 +544,8 @@ std::string CEvohomeWeb::local_to_utc(std::string local_time)
528544
#define EVOHOME_HOST "https://tccna.honeywell.com"
529545

530546

531-
const std::string weekdays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
532-
//const std::string evo_modes[7] = {"Auto", "HeatingOff", "AutoWithEco", "Away", "DayOff", "", "Custom"};
547+
const std::string CEvohomeWeb::weekdays[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
548+
//const std::string CEvohomeWeb::evo_modes[7] = {"Auto", "HeatingOff", "AutoWithEco", "Away", "DayOff", "", "Custom"};
533549

534550

535551
/************************************************************************
@@ -556,7 +572,7 @@ bool CEvohomeWeb::login(std::string user, std::string password)
556572
std::string s_res;
557573
if (!HTTPClient::POST(EVOHOME_HOST"/Auth/OAuth/Token", pdata.str(), LoginHeaders, s_res))
558574
{
559-
_log.Log(LOG_ERROR,"Evohome: HTTP client error at login!");
575+
_log.Log(LOG_ERROR,"EvohomeWeb: HTTP client error at login!");
560576
return false;
561577
}
562578

@@ -573,15 +589,15 @@ bool CEvohomeWeb::login(std::string user, std::string password)
573589
i++;
574590
c = html[i];
575591
}
576-
_log.Log(LOG_ERROR,"Evohome: login failed with message: %s", edata.str().c_str());
592+
_log.Log(LOG_ERROR,"EvohomeWeb: login failed with message: %s", edata.str().c_str());
577593
return false;
578594
}
579595

580596
json_object *j_ret = json_tokener_parse(s_res.c_str());
581597
json_object *j_msg;
582598
if ( (json_object_object_get_ex(j_ret, "error", &j_msg)) || (json_object_object_get_ex(j_ret, "message", &j_msg)) )
583599
{
584-
_log.Log(LOG_ERROR,"Evohome: login failed with message: %s", json_object_get_string(j_msg));
600+
_log.Log(LOG_ERROR,"EvohomeWeb: login failed with message: %s", json_object_get_string(j_msg));
585601
return false;
586602
}
587603

@@ -612,7 +628,7 @@ bool CEvohomeWeb::user_account()
612628
std::string s_res;
613629
if (!HTTPClient::GET(EVOHOME_HOST"/WebAPI/emea/api/v1/userAccount", SessionHeaders, s_res))
614630
{
615-
_log.Log(LOG_ERROR,"Evohome: HTTP client error at retrieve user account info!");
631+
_log.Log(LOG_ERROR,"EvohomeWeb: HTTP client error at retrieve user account info!");
616632
return false;
617633
}
618634
json_object *j_ret = json_tokener_parse(s_res.c_str());
@@ -642,17 +658,15 @@ void CEvohomeWeb::get_zones(int location, int gateway, int temperatureControlSys
642658
for (i=0; i<l; i++)
643659
{
644660
locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].zones[i].installationInfo = json_object_array_get_idx(j_list, i);
645-
646-
json_object *j_zoneId;
647-
json_object_object_get_ex(locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].zones[i].installationInfo, "zoneId", &j_zoneId);
648-
locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].zones[i].zoneId = json_object_get_string(j_zoneId);
661+
locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].zones[i].zoneId = json_get_val(locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].zones[i].installationInfo,"zoneId");
649662
locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].zones[i].systemId = locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].systemId;
650663
locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].zones[i].gatewayId = locations[location].gateways[gateway].gatewayId;
651664
locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem].zones[i].locationId = locations[location].locationId;
652665
}
653666
}
654667
}
655668

669+
656670
void CEvohomeWeb::get_temperatureControlSystems(int location, int gateway)
657671
{
658672
locations[location].gateways[gateway].temperatureControlSystems.clear();
@@ -666,13 +680,9 @@ void CEvohomeWeb::get_temperatureControlSystems(int location, int gateway)
666680
for (i = 0; i < l; i++)
667681
{
668682
locations[location].gateways[gateway].temperatureControlSystems[i].installationInfo = json_object_array_get_idx(j_list, i);
669-
670-
json_object *j_tcsId;
671-
json_object_object_get_ex(locations[location].gateways[gateway].temperatureControlSystems[i].installationInfo, "systemId", &j_tcsId);
672-
locations[location].gateways[gateway].temperatureControlSystems[i].systemId = json_object_get_string(j_tcsId);
683+
locations[location].gateways[gateway].temperatureControlSystems[i].systemId = json_get_val(locations[location].gateways[gateway].temperatureControlSystems[i].installationInfo, "systemId");
673684
locations[location].gateways[gateway].temperatureControlSystems[i].gatewayId = locations[location].gateways[gateway].gatewayId;
674685
locations[location].gateways[gateway].temperatureControlSystems[i].locationId = locations[location].locationId;
675-
676686
get_zones(location, gateway, i);
677687
}
678688
}
@@ -691,13 +701,8 @@ void CEvohomeWeb::get_gateways(int location)
691701
for (i = 0; i < l; i++)
692702
{
693703
locations[location].gateways[i].installationInfo = json_object_array_get_idx(j_list, i);
694-
695-
json_object *j_gwInfo, *j_gwId;
696-
json_object_object_get_ex(locations[location].gateways[i].installationInfo, "gatewayInfo", &j_gwInfo);
697-
json_object_object_get_ex(j_gwInfo, "gatewayId", &j_gwId);
698-
locations[location].gateways[i].gatewayId = json_object_get_string(j_gwId);
704+
locations[location].gateways[i].gatewayId = json_get_val(locations[location].gateways[i].installationInfo, "gatewayInfo", "gatewayId");
699705
locations[location].gateways[i].locationId = locations[location].locationId;
700-
701706
get_temperatureControlSystems(location,i);
702707
}
703708
}
@@ -713,7 +718,7 @@ bool CEvohomeWeb::full_installation()
713718
std::string s_res;
714719
if (!HTTPClient::GET(url.str(), SessionHeaders, s_res))
715720
{
716-
_log.Log(LOG_ERROR,"Evohome: HTTP client error at retrieve installation!");
721+
_log.Log(LOG_ERROR,"EvohomeWeb: HTTP client error at retrieve installation!");
717722
return false;
718723
}
719724

@@ -730,12 +735,7 @@ bool CEvohomeWeb::full_installation()
730735
for (i=0; i<l; i++)
731736
{
732737
locations[i].installationInfo = json_object_array_get_idx(j_list, i);
733-
734-
json_object *j_locInfo, *j_locId;
735-
json_object_object_get_ex(locations[i].installationInfo, "locationInfo", &j_locInfo);
736-
json_object_object_get_ex(j_locInfo, "locationId", &j_locId);
737-
locations[i].locationId = json_object_get_string(j_locId);
738-
738+
locations[i].locationId = json_get_val(locations[i].installationInfo, "locationInfo", "locationId");
739739
get_gateways(i);
740740
}
741741
return true;
@@ -773,7 +773,7 @@ bool CEvohomeWeb::get_status(int location)
773773
std::string s_res;
774774
if (!HTTPClient::GET(url.str(), SessionHeaders, s_res))
775775
{
776-
_log.Log(LOG_ERROR,"Evohome: HTTP client error at get status!");
776+
_log.Log(LOG_ERROR,"EvohomeWeb: HTTP client error at get status!");
777777
return false;
778778
}
779779
locations[location].status = json_tokener_parse(s_res.c_str());
@@ -817,6 +817,8 @@ bool CEvohomeWeb::get_status(int location)
817817
else
818818
valid_json = false;
819819

820+
if (!valid_json)
821+
_log.Log(LOG_ERROR,"EvohomeWeb: status request did not return a valid response");
820822
return valid_json;
821823
}
822824

@@ -946,13 +948,14 @@ std::string CEvohomeWeb::get_next_switchpoint(CEvohomeWeb::temperatureControlSys
946948
return "";
947949
return get_next_switchpoint(tcs->zones[zone].schedule);
948950
}
949-
951+
/*
950952
std::string CEvohomeWeb::get_next_switchpoint(std::string zoneId)
951953
{
952954
if ( (get_zone_by_ID(zoneId)->schedule == NULL) && !get_schedule(zoneId) )
953955
return "";
954956
return get_next_switchpoint(get_zone_by_ID(zoneId)->schedule);
955957
}
958+
*/
956959
std::string CEvohomeWeb::get_next_switchpoint(zone* hz)
957960
{
958961
if ( (hz->schedule == NULL) && !get_schedule(hz->zoneId) )
@@ -961,10 +964,10 @@ std::string CEvohomeWeb::get_next_switchpoint(zone* hz)
961964
}
962965
std::string CEvohomeWeb::get_next_switchpoint(json_object *schedule)
963966
{
964-
std::string current_temperature;
965-
return get_next_switchpoint_ex(schedule, current_temperature);
967+
std::string current_setpoint;
968+
return get_next_switchpoint_ex(schedule, current_setpoint);
966969
}
967-
std::string CEvohomeWeb::get_next_switchpoint_ex(json_object *schedule, std::string &current_temperature)
970+
std::string CEvohomeWeb::get_next_switchpoint_ex(json_object *schedule, std::string &current_setpoint)
968971
{
969972
if (schedule == NULL)
970973
return "";
@@ -1019,7 +1022,7 @@ std::string CEvohomeWeb::get_next_switchpoint_ex(json_object *schedule, std::str
10191022
else
10201023
{
10211024
json_object_object_get_ex(j_sp, "temperature", &j_temp);
1022-
current_temperature = json_object_get_string(j_temp);
1025+
current_setpoint = json_object_get_string(j_temp);
10231026
}
10241027
}
10251028
}
@@ -1074,6 +1077,7 @@ std::string CEvohomeWeb::json_get_val(json_object *j_json, const char* key1, con
10741077
* *
10751078
************************************************************************/
10761079

1080+
10771081
bool CEvohomeWeb::verify_date(std::string date)
10781082
{
10791083
if (date.length() < 10)
@@ -1185,11 +1189,12 @@ bool CEvohomeWeb::set_temperature(std::string zoneId, std::string temperature, s
11851189
return true;
11861190
return false;
11871191
}
1192+
/*
11881193
bool CEvohomeWeb::set_temperature(std::string zoneId, std::string temperature)
11891194
{
11901195
return set_temperature(zoneId, temperature, "");
11911196
}
1192-
1197+
*/
11931198

11941199
bool CEvohomeWeb::cancel_temperature_override(std::string zoneId)
11951200
{
@@ -1202,12 +1207,13 @@ bool CEvohomeWeb::cancel_temperature_override(std::string zoneId)
12021207
return false;
12031208
}
12041209

1205-
1210+
/*
12061211
bool CEvohomeWeb::has_dhw(int location, int gateway, int temperatureControlSystem)
12071212
{
12081213
CEvohomeWeb::temperatureControlSystem *tcs = &locations[location].gateways[gateway].temperatureControlSystems[temperatureControlSystem];
12091214
return has_dhw(tcs);
12101215
}
1216+
*/
12111217
bool CEvohomeWeb::has_dhw(CEvohomeWeb::temperatureControlSystem *tcs)
12121218
{
12131219
json_object *j_dhw;
@@ -1253,8 +1259,9 @@ bool CEvohomeWeb::set_dhw_mode(std::string dhwId, std::string mode, std::string
12531259
return true;
12541260
return false;
12551261
}
1262+
/*
12561263
bool CEvohomeWeb::set_dhw_mode(std::string systemId, std::string mode)
12571264
{
12581265
return set_dhw_mode(systemId, mode, "");
12591266
}
1260-
1267+
*/

0 commit comments

Comments
 (0)