From 422a6a0c4610ac0308f092f72e15a83f652f354a Mon Sep 17 00:00:00 2001 From: Steffen Pohle Date: Sat, 29 Jan 2022 01:42:49 +0100 Subject: [PATCH] adding gethzr, fixing issued with readin default config file. --- cfg.cc | 2 - fb-login-test.sh | 11 +++- fbsh-cli.cc | 157 +++++++++++++++++++++++++++++--------------- fbsh.cc | 166 +++++++++++++++++++++++++++++++++++++++++++++++ fbsh.h | 16 +++++ 5 files changed, 298 insertions(+), 54 deletions(-) diff --git a/cfg.cc b/cfg.cc index 7e391ff..3ea250a 100644 --- a/cfg.cc +++ b/cfg.cc @@ -83,8 +83,6 @@ int Config::LoadConfig() { int i; if ((f = fopen (filename.c_str(), "r")) == NULL) { - fprintf (stderr, "error on writing config '%s' : %s\n", filename.c_str(), - strerror(errno)); return -1; } diff --git a/fb-login-test.sh b/fb-login-test.sh index 2974396..e5a70ec 100755 --- a/fb-login-test.sh +++ b/fb-login-test.sh @@ -36,8 +36,17 @@ function getdevices () { } +function getdevinfo () { + curl -v -s "$1/webservices/homeautoswitch.lua?switchcmd=getbasicdevicestats&sid=$SID&ain=13979%200002675" + echo "*************************" + curl -v -s "$1/webservices/homeautoswitch.lua?switchcmd=getdeviceinfos&sid=$SID&ain=13979%200002675" + return 0 +} + + login $FBSH_HOSTNAME $FBSH_USER $FBSH_PASS getdevices $FBSH_HOSTNAME +getdevinfo $FBSH_HOSTNAME "13979 0002675" + -echo $LIST diff --git a/fbsh-cli.cc b/fbsh-cli.cc index cbe8ab5..ab059f5 100644 --- a/fbsh-cli.cc +++ b/fbsh-cli.cc @@ -20,6 +20,7 @@ void help() { printf ("\tconnect connect to the device, it will save the SID file.\n"); printf ("\tlist lists all devices, connection will be recovered from SID.\n"); printf ("\t If silent parameter is set, we will not be asked for credentials\n"); + printf ("\tgethzr AIN reads heating control device\n"); printf ("\tsaveconfig save configfile.\n"); printf ("\n"); printf ("Parameters:\n"); @@ -66,63 +67,117 @@ void getlist(int argpos, int argc, char **argv) { delete devlist; } +#define CHARTSIZE 20 +void gethzr(char *ain) { + FBSmartHomeHZR hzr; + list::iterator iter; + float fmin, fmax; + std::string s; + int c, i; + char t[64]; + struct tm *tmp; + time_t ctime = time(NULL); + + if (ain == NULL) return; + connect(); + fbsh.GetHZR((std::string)ain, &hzr); + + printf ("Name:%s ID:%s\n", hzr.name.c_str(), hzr.id.c_str()); + printf (" Temp: %.1f\n", hzr.temp); + printf (" Temp Akt: %.1f\n", hzr.temp_cur); + printf (" Temp Set: %.1f\n", hzr.temp_set); + printf (" Temp Komfort: %.1f\n", hzr.temp_h); + printf (" Temp Absenk: %.1f\n", hzr.temp_l); + printf (" Offset: %d\n", hzr.offset); + printf (" Grid: %d\n", hzr.statsgrid); + + for (iter = hzr.stats.begin(); iter != hzr.stats.end(); iter++) { + if (iter == hzr.stats.begin()) fmin = fmax = *iter; + if (fmin > *iter) fmin = *iter; + if (fmax < *iter) fmax = *iter; + } + + printf (" %-2.1f %-2.1f\n", fmin/10.0, fmax/10.0); + + ctime = (ctime / hzr.statsgrid) * hzr.statsgrid; + + for (iter = hzr.stats.begin(); iter != hzr.stats.end(); iter++) { + s = " "; + c = ((float)(CHARTSIZE * (*iter - fmin) / (fmax-fmin))); + for (i = 0; i < c; i++) s += " "; + s += "*"; + for (i = c+1; i <= CHARTSIZE; i++) s += " "; + + ctime -= hzr.statsgrid; + tmp = localtime(&ctime); + strftime(t, 64, "%H:%M", tmp); + printf (" %s |%s|\n", t, s.c_str()); + } + printf (" %-2.1f %-2.1f\n", fmin/10.0, fmax/10.0); +} + int main(int argc, char** argv) { int i; - if (argc < 2) help(); + if (argc < 2 || argv == NULL) help(); else { - for (i = 1; i < argc; i++) { - // - // commands to run, all parameters must be set by here. - // - if (strcmp(argv[i], "help") == 0) { - help(); - break; - } - else if (strcmp(argv[i], "connect") == 0) { - connect(); - printf ("SID:%s\n", fbsh.GetSID().c_str()); - break; - } - else if (strcmp(argv[i], "list") == 0) { - getlist(i, argc, argv); - break; - } - else if (strcmp(argv[i], "saveconfig") == 0) { - config.SaveConfig(); - break; + for (i = 1; i < argc; i++) + if (argv[i] != NULL) { + // + // commands to run, all parameters must be set by here. + // + if (strcmp(argv[i], "help") == 0) { + help(); + break; + } + else if (strcmp(argv[i], "connect") == 0) { + connect(); + printf ("SID:%s\n", fbsh.GetSID().c_str()); + break; + } + else if (strcmp(argv[i], "list") == 0) { + getlist(i, argc, argv); + break; + } + else if (strcmp(argv[i], "saveconfig") == 0) { + config.SaveConfig(); + break; + } + else if (strcmp(argv[i], "gethzr") == 0) { + gethzr(argv[++i]); + } + + // + // parameters will follow here + // + else if (strcmp(argv[i], "-host") == 0) { + config.SetFBHostname(argv[++i]); + } + else if (strcmp(argv[i], "-user") == 0) { + config.SetUsername(argv[++i]); + } + else if (strcmp(argv[i], "-pass") == 0) { + config.SetPassword(argv[++i]); + } + else if (strcmp(argv[i], "-silent") == 0) { + config.SetSilent(atoi(argv[++i])); + } + else if (strcmp(argv[i], "-S") == 0) { + config.SetSilent(true); + } + else if (strcmp(argv[i], "-sidfile") == 0) { + config.SetSIDFile(argv[++i]); + } + else if (strcmp(argv[i], "-savepassword") == 0) { + config.SetSavePassword(atoi(argv[++i])); + } + else if (strcmp(argv[i], "-config") == 0) { + config.SetFilename(argv[++i]); + if (config.LoadConfig() < 0) + fprintf (stderr, "could not load config file '%s'\n", argv[i]); + } } - - // - // parameters will follow here - // - else if (strcmp(argv[i], "-host") == 0) { - config.SetFBHostname(argv[++i]); - } - else if (strcmp(argv[i], "-user") == 0) { - config.SetUsername(argv[++i]); - } - else if (strcmp(argv[i], "-pass") == 0) { - config.SetPassword(argv[++i]); - } - else if (strcmp(argv[i], "-silent") == 0) { - config.SetSilent(atoi(argv[++i])); - } - else if (strcmp(argv[i], "-S") == 0) { - config.SetSilent(true); - } - else if (strcmp(argv[i], "-sidfile") == 0) { - config.SetSIDFile(argv[++i]); - } - else if (strcmp(argv[i], "-savepassword") == 0) { - config.SetSavePassword(atoi(argv[++i])); - } - else if (strcmp(argv[i], "-config") == 0) { - config.SetFilename(argv[++i]); - config.LoadConfig(); - } - } } return 0; } diff --git a/fbsh.cc b/fbsh.cc index 085817e..2838d68 100644 --- a/fbsh.cc +++ b/fbsh.cc @@ -427,3 +427,169 @@ std::list *FBSmartHome::GetDevices() { } +/* + * read data from device and fill out FBSmartHomeHZR structure + */ +int FBSmartHome::GetHZR(std::string ain, FBSmartHomeHZR *hzr) { + std::string s; + FBSmartHomeDevice smd; + xmlDocPtr xmldoc; + xmlNodePtr xmlnode; + xmlAttrPtr xmlattr; + int len, i; + + if (hzr == NULL) return -1; + for (s = "", i = 0; i < (int)ain.length(); i++) { + if (ain[i] == ' ') s += "%20"; + else s += ain[i]; + } + + // + // read device info + // + + // + // retrieve data + len = tcp.WebGetFile(hostname+"/webservices/homeautoswitch.lua?sid="+SID+"&switchcmd=getdeviceinfos&ain="+s, inbuffer, FB_BUFFER, NULL); + if (len > FB_BUFFER) len = FB_BUFFER; + else if (len < 0) { + fprintf (stderr, "%s:%d Error getting challenge from Fritzbox\n", __FILE__, __LINE__); + errno = EAI_FAIL; + return -1; + } + inbuffer[len] = '\0'; + XMLPrepare(inbuffer, len, &xmldoc, &xmlnode); + + // + // parse for SID and Challange + while (xmlnode) { + if ((!xmlStrcmp(xmlnode->name, (const xmlChar *)"device"))){ + xmlNodePtr xmlchild = xmlnode->xmlChildrenNode; + + xmlattr = xmlnode->properties; + while (xmlattr) { + if (!xmlStrcmp(xmlattr->name, (const xmlChar *)"identifier")) + hzr->id = (char *) xmlNodeListGetString(xmldoc, xmlattr->children, 1); + xmlattr = xmlattr->next; + } + while (xmlchild) { + + // name + if (!xmlStrcmp(xmlchild->name, (const xmlChar *)"name")) + hzr->name = (char *) xmlNodeListGetString(xmldoc, xmlchild->children, 1); + + // temperatur + else if (!xmlStrcmp(xmlchild->name, (const xmlChar *)"temperature")) { + xmlNodePtr xmlc = xmlchild->children; + while(xmlc) { + if (!xmlStrcmp(xmlc->name, (const xmlChar *)"celsius")) { + hzr->temp = (atof ((char *) xmlNodeListGetString(xmldoc, xmlc->children, 1))) / 10.0; + } + else if (!xmlStrcmp(xmlc->name, (const xmlChar *)"offset")) { + hzr->offset = atoi ((char *) xmlNodeListGetString(xmldoc, xmlc->children, 1)); + } + + xmlc = xmlc->next; + } + } + + // hzr + else if (!xmlStrcmp(xmlchild->name, (const xmlChar *)"hkr")) { + xmlNodePtr xmlc = xmlchild->children; + while(xmlc) { + if (!xmlStrcmp(xmlc->name, (const xmlChar *)"tist")) { + hzr->temp_cur = atof ((char *) xmlNodeListGetString(xmldoc, xmlc->children, 1)); + hzr->temp_cur = hzr->temp_cur / 2.0; + } + else if (!xmlStrcmp(xmlc->name, (const xmlChar *)"tsoll")) { + hzr->temp_set = atof ((char *) xmlNodeListGetString(xmldoc, xmlc->children, 1)); + hzr->temp_set = hzr->temp_set / 2.0; + } + else if (!xmlStrcmp(xmlc->name, (const xmlChar *)"absenk")) { + hzr->temp_l = atof ((char *) xmlNodeListGetString(xmldoc, xmlc->children, 1)); + hzr->temp_l = hzr->temp_l / 2.0; + } + else if (!xmlStrcmp(xmlc->name, (const xmlChar *)"komfort")) { + hzr->temp_h = atof ((char *) xmlNodeListGetString(xmldoc, xmlc->children, 1)); + hzr->temp_h = hzr->temp_h / 2.0; + } + + xmlc = xmlc->next; + } + } + + xmlchild = xmlchild->next; + } + } + xmlnode = xmlnode->next; + } + xmlFreeDoc(xmldoc); + + // + // + // + // retrieve data + len = tcp.WebGetFile(hostname+"/webservices/homeautoswitch.lua?sid="+SID+"&switchcmd=getbasicdevicestats&ain="+s, inbuffer, FB_BUFFER, NULL); + if (len > FB_BUFFER) len = FB_BUFFER; + else if (len < 0) { + fprintf (stderr, "%s:%d Error getting challenge from Fritzbox\n", __FILE__, __LINE__); + errno = EAI_FAIL; + return -1; + } + inbuffer[len] = '\0'; + XMLPrepare(inbuffer, len, &xmldoc, &xmlnode); + + // + // parse for SID and Challange + while (xmlnode) { + if ((!xmlStrcmp(xmlnode->name, (const xmlChar *)"devicestats"))){ + xmlNodePtr xmlchild = xmlnode->xmlChildrenNode; + std::string txt; + float f; + char *t; + + while (xmlchild) { + // temperatur + if (!xmlStrcmp(xmlchild->name, (const xmlChar *)"temperature")) { + xmlNodePtr xmlc = xmlchild->children; + int count = 0; + + while(xmlc) { + if (!xmlStrcmp(xmlc->name, (const xmlChar *)"stats")) { + xmlattr = xmlc->properties; + while (xmlattr) { + if (!xmlStrcmp(xmlattr->name, (const xmlChar *)"count")) + count = atoi((char *) xmlNodeListGetString(xmldoc, xmlattr->children, 1)); + else if (!xmlStrcmp(xmlattr->name, (const xmlChar *)"grid")) + hzr-> statsgrid = atoi((char *) xmlNodeListGetString(xmldoc, xmlattr->children, 1)); + xmlattr = xmlattr->next; + } + + txt = ((char *) xmlNodeListGetString(xmldoc, xmlc->children, 1)); + + hzr->stats.clear(); + t = (char*)txt.c_str(); + for (int i = 0; t != NULL && i < count; i++) { + if (*t == ',') t++; + f = atoi (t); + hzr->stats.push_back(f); + t = strchr(t, ','); + } + } + xmlc = xmlc->next; + } + } + + xmlchild = xmlchild->next; + } + } + xmlnode = xmlnode->next; + } + xmlFreeDoc(xmldoc); + + + return 0; +} + + + diff --git a/fbsh.h b/fbsh.h index e4c1006..e65621c 100644 --- a/fbsh.h +++ b/fbsh.h @@ -16,6 +16,7 @@ std::string generateMD5 (char* input, int size); #define FB_BUFFER (4*1024*1024) + struct { std::string id; std::string name; @@ -24,6 +25,20 @@ struct { } typedef FBSmartHomeDevice; +struct { + std::string id; + std::string name; + float temp; + float temp_cur; + float temp_set; + float temp_h; + float temp_l; + int offset; + std::liststats; + int statsgrid; +} typedef FBSmartHomeHZR; + + class FBSmartHome { private: char inbuffer[FB_BUFFER]; @@ -51,6 +66,7 @@ public: int Connect(std::string host); // return 0 on success int Connect(std::string host, std::string username, std::string password); + int GetHZR(std::string ain, FBSmartHomeHZR *hzr); std::list *GetDevices(); };