def status(config={}, output="default"): result = {} xmlpaths = {} if "ipaddr" not in config: logger.exception("No IP address specified in config file.") raise ValueError if "inputs" not in config: logger.exception("No inputs specified in config file.") raise ValueError else: xmlpaths = config["inputs"] if output == "signalk": logger.debug("prepping sk output...") from pivac import sk_init_deltas, sk_add_source, sk_add_value deltas = sk_init_deltas() sk_source = sk_add_source(deltas) try: logger.debug("Parsing TED data...") page = requests.get("http://%s/api/LiveData.xml" % config["ipaddr"], timeout=2) logger.debug("Got request...") e = ET.fromstring(page.text) # logger.debug("E = %s" % e.__dict__) for i in xmlpaths.keys(): # logger.debug("i = %s" % i) a = e.find(".//%s" % i) # logger.debug("a = %s" % a.__dict__) # logger.debug("xmlpaths = %s, i = %s, xmlpaths[i] = %s, name = %s" % (xmlpaths, i, xmlpaths[i], xmlpaths[i]["outname"])) if output == "signalk": sk_add_value( sk_source, "%s.%s.power" % (xmlpaths[i]["sk_path"], xmlpaths[i]["outname"]), int(a.text)) else: result[xmlpaths[i]["outname"]] = int(a.text) except: logger.exception("Exception collecting data from TED5000") if output == "signalk": logger.debug("deltas = %s" % deltas) return deltas else: logger.debug("result = %s" % result) return result
def status(config={}, output="default"): result = {} deltas = {} if "inputs" in config: if not pins_initted: pinmode = GPIO.BCM if "numbering" in config and config["numbering"] == "board": pinmode = GPIO.BOARD init_pins(config["inputs"], pinmode) if output == "signalk": logger.debug("formatting signalk output...") from pivac import sk_init_deltas, sk_add_value, sk_add_source deltas = sk_init_deltas() sk_source = sk_add_source(deltas) for pinnum, pindict in config["inputs"].iteritems(): logger.debug("pin = %s, pindict = %s" % (pinnum, pindict)) presult = GPIO.input(pinnum) == (pindict["pullmode"] == "pulldown") if output == "signalk": if pindict["sk_literal"] == False: sk_add_value( sk_source, "%s.%s.state" % (pindict["sk_path"], pindict["outname"]), presult) sk_add_value( sk_source, "%s.%s.statenum" % (pindict["sk_path"], pindict["outname"]), int(presult)) else: sk_add_value(sk_source, "%s.name" % config["sk_path"], pindict["outname"]) sk_add_value(sk_source, "%s.state" % config["sk_path"], presult) sk_add_value(sk_source, "%s.statenum" % config["sk_path"], int(presult)) else: result[pindict["outname"]] = presult else: logger.exception("No input pins specified for GPIO") raise KeyError if output == "signalk": return deltas else: return result
def status(config={}, output="default"): logger.debug("generating status") result = {} dnames = {} # not an error if no sensors specified, you just won't get pretty names if "inputs" in config: dnames = config["inputs"] for s in sensors: if s.id not in dnames: dnames[s.id] = {} from pivac import propagate_defaults logger.debug("before prop: %s" % dnames) propagate_defaults(config, dnames, config["propagate"]) logger.debug("after prop: %s" % dnames) # prep for signalk output if output == "signalk": logger.debug("prepping sk output...") from pivac import sk_init_deltas, sk_add_source, sk_add_value deltas = sk_init_deltas() sk_source = sk_add_source(deltas) logger.debug("sensors = %s" % sensors) for sensor in sensors: temp = 0 sname = "" # read the sensor and prep for output (both types) temp_type = DEG_FAHRENHEIT temps = { "fahrenheit": DEG_FAHRENHEIT, "celsius": DEG_CELSIUS, "kelvin": DEG_KELVIN } if "scale" in dnames[sensor.id] and config["scale"] in temps: temp_type = temps[dnames[sensor.id]["scale"]] if output == "signalk" or temp_type == DEG_KELVIN: thermtemp = sensor.get_temperature(W1ThermSensor.KELVIN) elif temp_type == DEG_CELSIUS: thermtemp = sensor.get_temperature(W1ThermSensor.DEGREES_C) else: thermtemp = sensor.get_temperature(W1ThermSensor.DEGREES_F) logger.debug("Temp for %s is: %f" % (sensor.id, thermtemp)) if sensor.id in dnames and "outname" in dnames[sensor.id]: sname = dnames[sensor.id]["outname"] else: # this will add a new member to the dict with the name of the sensor sname = sensor.id round_digits = dnames[sensor.id]["rounding"] if round_digits == 0: result[sname] = int(round(thermtemp, 0)) elif round_digits > 0: result[sname] = round(thermtemp, round_digits) else: result[sname] = thermtemp if output == "signalk": # output delta if not dnames[sensor.id]["sk_literal"]: sk_add_value( sk_source, "%s.%s.temperature" % (dnames[sensor.id]["sk_path"], sname), result[sname]) else: sk_add_value(sk_source, "%s.temperature" % dnames[sensor.id]["sk_path"], result[sname]) if output == "signalk": logger.debug(deltas) return deltas else: logger.debug(result) return result
def status(config={}, output="default"): result = {} if output == "signalk": logger.debug("prepping sk output...") from pivac import sk_init_deltas, sk_add_source, sk_add_value deltas = sk_init_deltas() cams = config["inputs"] for cam, camdict in cams.iteritems(): logger.debug("iterating camera %s", cam) if output == "signalk": sk_source = sk_add_source(deltas, "flirfx:%s" % cam) try: # no session yet if "fake" in camdict and camdict["fake"] == True: temp_units = "F" temp_value = 68 humidity_value = 49 else: if cam not in Cams: logger.debug("logging into camera...") Cams[cam] = {} r = requests.post( 'http://%s/API/1.0/ChiconyCameraLogin' % cam, data='{ "password" : "%s" }' % camdict["pwd"]) session = r.cookies['Session'] Cams[cam]["cookies"] = dict(Session=session) req = requests.post( 'http://%s/API/1.1/CameraStatus' % cam, cookies=cookies, data='{ "getCameraStatus" : [ "humidity", "temperature"] }' ) res = req.json() temp_units = res['temperature']['tempUnits'] temp_value = res['temperature']['tempValue'] humidity_value = res['humidity']['humidityLevel'] if temp_units == 'F': temp_value = pytemperature.f2k(temp_value) elif temp_units == 'C': temp_value = pytemperature.c2k(temp_value) if output == "signalk": sk_add_value(sk_source, "%s.temperature" % camdict["sk_path"], temp_value) sk_add_value(sk_source, "%s.humidity" % camdict["sk_path"], humidity_value) else: if camdict["scale"] == "fahrenheit": temp_value = pytemperature.k2f(temp_value) if camdict["scale"] == "celcius": temp_value = pytemperature.k2c(temp_value) result[cam] = {} result[cam]["temperature"] = temp_value result[cam]["humidity"] = humidity_value except: logger.exception("error getting data from FLIR camera %s" % cam) if output == "signalk": return deltas else: return result
def status(config={}, output="default"): global logged_in global locationId, locationId_prog global statsId_prog, statsData_prog, status_prog global cj, br result = {} if "website" in config: homepage = config["website"] else: homepage = HOMEPAGE if not "uid" in config or not "pwd" in config: logger.error("Credentials not specified in config file.") raise ValueError # log in to mytotalconnectcomfort.com # NOTE: this code currently only works if you only have one location defined... stats_page = "" try: if logged_in == False: logger.debug("Not logged in; logging in...") response = br.open(homepage) # sometimes we get an exception but still logged in... stats_page = response.read() if locationId_prog.findall(stats_page): logger.debug("Already logged in %s" % locationId) logged_in = True else: logger.debug("filling login form...") try: br.select_form(nr=0) except: # try retsetting Mechanize logger.exception("form error on: %s" % stats_page) init_site() br.open(homepage) br.select_form(nr=0) br.form['UserName'] = config["uid"] br.form['Password'] = config["pwd"] response = br.submit() stats_page = response.read() logger.debug("done logging in") list = locationId_prog.findall(stats_page) logger.debug("loclist= %s" % list) if len(list): locationId = list[0] else: raise IOError logger.debug("locationId=%s" % locationId) logger.debug("Stats page = %s" % stats_page) logged_in = True else: refresh_link = homepage logger.debug("Refresh link = %s" % refresh_link) response = br.open(refresh_link) stats_page = response.read() logger.debug("Stats page = %s" % stats_page) except: logger.exception("Error scraping MyTotalConnectComfort.com") logger.debug("Failed on page: %s" % stats_page) init_site() raise IOError if output == "signalk": logger.debug("Composing signalk output...") from pivac import sk_init_deltas, sk_add_source, sk_add_value deltas = sk_init_deltas() sk_source = sk_add_source(deltas) statenums = {"heat": 1, "cool": -1, "fan": 0.5, "off": 0} verbose = False if "verbose" in config: verbose = config["verbose"] if verbose == True: logger.debug("Verbose mode...") # get stat list out of the home page stats_list = statsId_prog.findall(stats_page) logger.debug("Stats list = %s" % stats_list) try: for s in stats_list: linktext = "/portal/Device/Control/%s?page=1" % s # logger.debug("link text = %s" % linktext) link = br.find_link(url=linktext) br.click_link(link) response = br.follow_link(link) stattext = response.read() statdata = statsData_prog.findall(stattext) statname = statname_prog.findall(stattext) stat = status_prog.findall(stattext) sname = statname[0] sstat = "off" if stat != []: sstat = stat[0] sdict = dict(statdata) if config["scale"] == "fahrenheit": scale = "fahrenheit" ktemp = pytemperature.f2k(float(sdict["dispTemperature"])) if s in config["inputs"] and config["inputs"][s][ "scale"] == "celsius": scale = "celsius" ktemp = pytemperature.c2k( float(sdict["dispTemperature"])) else: scale = "celsius" ktemp = pytemperature.c2k(sdict["dispTemperature"]) if s in config["inputs"] and config["inputs"][s][ "scale"] == "fahrenheit": scale = "fahrenheit" ktemp = pytemperature.f2k(sdict["dispTemperature"]) if output == "signalk": fname = re.sub(r"[\s+]", '_', sname) sk_add_value( sk_source, "%s.%s.temperature" % (config["inputs"]["thermostat"]["sk_path"], fname), int(ktemp)) sk_add_value( sk_source, "%s.%s.scale" % (config["inputs"]["thermostat"]["sk_path"], fname), ktemp) sk_add_value( sk_source, "%s.%s.humidity" % (config["inputs"]["thermostat"]["sk_path"], fname), float(sdict["indoorHumidity"]) / 100) sk_add_value( sk_source, "%s.%s.state" % (config["inputs"]["thermostat"]["sk_path"], fname), status_map[sstat]) sk_add_value( sk_source, "%s.%s.statenum" % (config["inputs"]["thermostat"]["sk_path"], fname), statenums[status_map[sstat]]) sk_add_value( sk_source, "%s.%s.heatset" % (config["inputs"]["thermostat"]["sk_path"], fname), int(float(sdict["heatSetpoint"]))) sk_add_value( sk_source, "%s.%s.coolset" % (config["inputs"]["thermostat"]["sk_path"], fname), int(float(sdict["coolSetpoint"]))) sk_add_value( sk_source, "%s.%s.humidity" % (config["inputs"]["outdoor_sensor"]["sk_path"], fname), float(sdict["outdoorHumidity"]) / 100) else: result[s] = { "name": sname, "temp": sdict["dispTemperature"], "scale": scale, "hum": float(sdict["indoorHumidity"]), "status": status_map[sstat], "heatset": int(float(sdict["heatSetpoint"])), "coolset": int(float(sdict["coolSetpoint"])), "rawdata": sdict } # there is no way to get this from the outdoor sensor so it is set by every stat... result["outhum"] = float(sdict["outdoorHumidity"]) # logger.debug("stat = %s %s %s" % (sname, sstat, sdict)) br.open(homepage) except: # too tricky to handle retries, just come back next time logger.exception("Error scraping stat page") init_site() raise IOError else: logger.debug("concise mode") soup = BeautifulSoup(stats_page, "lxml") laststat = "" for e in soup.find_all("tr", attrs={ 'class': re.compile(r".*\capsule pointerCursor\b.*") }): logger.debug("e = %s" % str(e)) stat = {} stat["status"] = "off" for f in e.find_all(): if f.has_attr("class"): if f["class"] == ["location-name"]: stat["name"] = f.string if f["class"] == ["hum-num"]: tstr = re.findall("[0-9]+", f.string) if len(tstr) > 0: stat["hum"] = int(tstr[0]) else: stat["hum"] = 0 if f["class"] == ["tempValue"]: tstr = re.findall("[0-9]+", f.string) if len(tstr) > 0: stat["temp"] = int(tstr[0]) else: stat["temp"] = 0 if "coolIcon" in f["class"] and f["style"] == "": stat["status"] = "cool" if "heatIcon" in f["class"] and f["style"] == "": stat["status"] = "heat" if "fanOnIcon" in f["class"] and f["style"] == "": stat["status"] = "fan" logger.debug("Stat = %s" % stat) if config["scale"] == "fahrenheit": stat["scale"] = "fahrenheit" ktemp = pytemperature.f2k(stat["temp"]) logger.debug("name = %s, value = %s" % (stat["name"], config["inputs"])) if stat["name"] in config["inputs"] and config["inputs"][ stat["name"]]["scale"] == "celsius": logger.debug("celcius exception") stat["scale"] = "celsius" ktemp = pytemperature.c2k(stat["temp"]) else: stat["scale"] = "celsius" ktemp = pytemperature.c2k(stat["temp"]) logger.debug("name = %s, value = %s" % (stat["name"], config["inputs"])) if stat["name"] in config["inputs"] and config["inputs"][ stat["name"]]["scale"] == "fahrenheit": logger.debug("fahrenheit exception") stat["scale"] = "fahrenheit" ktemp = pytemperature.f2k(stat["temp"]) if output == "signalk": fname = re.sub(r"[\s+]", '_', stat["name"]) sk_add_value( sk_source, "%s.%s.temperature" % (config["inputs"]["thermostat"]["sk_path"], fname), ktemp) sk_add_value( sk_source, "%s.%s.scale" % (config["inputs"]["thermostat"]["sk_path"], fname), stat["scale"]) sk_add_value( sk_source, "%s.%s.humidity" % (config["inputs"]["thermostat"]["sk_path"], fname), float(stat["hum"]) / 100) sk_add_value( sk_source, "%s.%s.redlinkid" % (config["inputs"]["thermostat"]["sk_path"], fname), e["data-id"]) sk_add_value( sk_source, "%s.%s.state" % (config["inputs"]["thermostat"]["sk_path"], fname), stat["status"]) sk_add_value( sk_source, "%s.%s.statenum" % (config["inputs"]["thermostat"]["sk_path"], fname), statenums[stat["status"]]) else: result[e["data-id"]] = stat laststat = e["data-id"] logger.debug("laststat = %s", laststat) try: if not laststat: logger.exception("No stats found") raise IOError logger.debug("getting outdoor humidity") linktext = "/portal/Device/Control/%s?page=1" % laststat logger.debug("link text = %s" % linktext) link = br.find_link(url=linktext) response = br.follow_link(link) stattext = response.read() statdata = conciseStatData_prog.findall(stattext) sdict = dict(statdata) if output == "signalk": sk_add_value( sk_source, "%s.humidity" % config["inputs"]["outdoor_sensor"]["sk_path"], float(sdict["outdoorHumidity"]) / 100) else: result["outhum"] = float(sdict["outdoorHumidity"]) except: # too tricky to handle retries, just come back next time logger.exception("Error scraping stat page") init_site() raise IOError if output == "signalk": return deltas else: return result