Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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
Пример #5
0
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