示例#1
0
文件: devcmds.py 项目: chava33/Vesta
def Prod(devKey):  # Ask device a question, just to provoke a response
    nwkId = database.GetDeviceItem(devKey, "nwkId")
    ep = database.GetDeviceItem(devKey, "endPoints")
    if nwkId != None and ep != None:
        log.debug("Prodding devKey " + str(devKey) + " (nwkId:" + nwkId + ")")
        cmdRsp = telegesis.ReadAttr(
            nwkId, ep, zcl.Cluster.Basic, zcl.Attribute.Model_Name
        )  # Get Basic's Device Name in order to prod it into life
        queue.EnqueueCmd(devKey, cmdRsp)
示例#2
0
def CheckPresence():  # Expected to be called infrequently - ie once/minute
    global info
    devIdx = 0
    for device in info:
        if GetTempVal(
                devIdx, "AtCmdRsp"
        ) == None:  # No pending command, so check whether device is present
            lastSeen = GetTempVal(devIdx, "LastSeen")
            if lastSeen != None:
                if datetime.now() > lastSeen + timedelta(
                        seconds=900
                ):  # More than 15 minutes since we last heard from device
                    devId = GetVal(devIdx, "devId")
                    ep = GetVal(devIdx, "EP")
                    if devId != None and ep != None:
                        pendingAtCmd = telegesis.ReadAttr(
                            devId, ep, zcl.Cluster.Basic, zcl.Attribute.
                            Model_Name)  # Get Basic's Device Name
                        SetTempVal(devIdx, "AtCmdRsp", pendingAtCmd)
                if datetime.now() > lastSeen + timedelta(
                        seconds=1800
                ):  # More than 30 minutes since we last heard from device
                    SetStatus(devIdx, "Presence", "* Missing *")
        devIdx = devIdx + 1
示例#3
0
文件: devices.py 项目: chava33/Vesta
def Check(devKey):
    global pendingBinding, msp_ota
    if devKey == 0: return  # We don't need anything from the hub
    nwkId = database.GetDeviceItem(devKey, "nwkId")
    if None == nwkId:
        return  # Make sure it's a real device before continuing (it may have just been deleted)
    ep = database.GetDeviceItem(devKey, "endPoints")
    if None == ep:
        return (["AT+ACTEPDESC:" + nwkId + "," + nwkId, "ActEpDesc"])
    eui = database.GetDeviceItem(devKey, "eui64")
    if None == eui: return (["AT+EUIREQ:" + nwkId + "," + nwkId, "AddrResp"])
    inClstr = database.GetDeviceItem(
        devKey, "inClusters",
        "[]")  # Assume we have a list of clusters if we get this far
    if "[]" == inClstr:
        return ([
            "AT+SIMPLEDESC:" + nwkId + "," + nwkId + "," + ep, "OutCluster"
        ])
    outClstr = database.GetDeviceItem(devKey, "outClusters", "[]")
    binding = database.GetDeviceItem(devKey, "binding" "[]")
    if str(pendingBinding[devKey]
           ) == "":  # Only try to add one binding per device at once
        if zcl.Cluster.PollCtrl in inClstr and zcl.Cluster.PollCtrl not in binding:
            return SetBinding(
                devKey, zcl.Cluster.PollCtrl,
                "01")  # 01 is our endpoint we want CHECKIN messages to come to
        if zcl.Cluster.OnOff in outClstr and zcl.Cluster.OnOff not in binding:  # If device sends OnOff commands (eg a Button)
            return SetBinding(
                devKey, zcl.Cluster.OnOff, "0A"
            )  # 0A is our endpoint we want messages to come to (so that we get TOGGLE, ON and OFF commands)
        if zcl.Cluster.Temperature in inClstr and zcl.Cluster.Temperature not in binding:
            return SetBinding(
                devKey, zcl.Cluster.Temperature, "01"
            )  # 01 is our endpoint we want Temperature reports to come to
        if zcl.Cluster.SimpleMetering in inClstr and zcl.Cluster.SimpleMetering not in binding:
            return SetBinding(
                devKey, zcl.Cluster.SimpleMetering, "01"
            )  # 01 is our endpoint we want SimpleMetering messages to come to
        if zcl.Cluster.Thermostat in inClstr and zcl.Cluster.Thermostat not in binding:
            return SetBinding(
                devKey, zcl.Cluster.Thermostat, "01"
            )  # 01 is our endpoint we want Thermostat messages to come to
    if zcl.Cluster.IAS_Zone in inClstr:
        if None == database.GetDeviceItem(devKey, "iasZoneType"):
            return telegesis.ReadAttr(
                nwkId, ep, zcl.Cluster.IAS_Zone, zcl.Attribute.Zone_Type
            )  # Get IAS device type (PIR or contact, etc.)
    if zcl.Cluster.Basic in inClstr:
        if None == database.GetDeviceItem(devKey, "modelName"):
            return telegesis.ReadAttr(
                nwkId, ep, zcl.Cluster.Basic,
                zcl.Attribute.Model_Name)  # Get Basic's Device Name
        if None == database.GetDeviceItem(devKey, "manufName"):
            return telegesis.ReadAttr(
                nwkId, ep, zcl.Cluster.Basic,
                zcl.Attribute.Manuf_Name)  # Get Basic's Manufacturer Name
    if zcl.Cluster.PowerConfig in inClstr and "SED" == database.GetDeviceItem(
            devKey, "devType"):
        checkBatt = GetTempVal(devKey, "GetNextBatteryAfter")
        if checkBatt != None:
            if datetime.now() > checkBatt:
                log.debug("Now = " + str(datetime.now()) +
                          " and checkBatt = " + str(checkBatt))
                return telegesis.ReadAttr(
                    nwkId, ep, zcl.Cluster.PowerConfig,
                    zcl.Attribute.Batt_Percentage)  # Get Battery percentage
    if zcl.Cluster.PollCtrl in inClstr:
        if None == database.GetDeviceItem(devKey, "longPollInterval"):
            return telegesis.ReadAttr(
                nwkId, ep, zcl.Cluster.PollCtrl, zcl.Attribute.
                LongPollIntervalQs)  # Get Poll Control's Long poll interval
    if zcl.Cluster.OTA in outClstr:
        if None == database.GetDeviceItem(devKey, "firmwareVersion"):
            return ("AT+READCATR:" + nwkId + "," + ep + ",0," +
                    zcl.Cluster.OTA + "," + zcl.Attribute.firmwareVersion,
                    "RESPATTR"
                    )  # Get OTA's Version number as a string of hex digits
    if msp_ota != None and msp_ota in outClstr:
        if None == database.GetDeviceItem(devKey, "firmwareVersion"):
            return ("AT+READMCATR:" + nwkId + "," + ep + ",0," +
                    config.Get(mfgId) + "," + msp_ota + "," +
                    zcl.Attribute.firmwareVersion, "RESPMATTR"
                    )  # Get OTA's Version number as a string of hex digits
    reporting = database.GetDeviceItem(devKey, "reporting", "[]")
    if zcl.Cluster.PowerConfig in binding and "SED" == database.GetDeviceItem(
            devKey, "devType"):
        atCmd = CheckReporting(
            devKey, reporting, "batteryReporting", zcl.Cluster.PowerConfig,
            zcl.Attribute.Batt_Percentage, zcl.AttributeTypes.Uint8,
            "43200,43200,2"
        )  # Default temperature reporting is "Every 12 hours"
        if atCmd != None: return atCmd
    if zcl.Cluster.Temperature in binding:
        atCmd = CheckReporting(
            devKey, reporting, "temperatureReporting", zcl.Cluster.Temperature,
            zcl.Attribute.Celsius, zcl.AttributeTypes.Uint16, "300,3600,100"
        )  # Default temperature reporting is "between 5 mins and 1 hr, or +/- 1.00'C"
        if atCmd != None: return atCmd
    if zcl.Cluster.SimpleMetering in binding:
        atCmd = CheckReporting(
            devKey, reporting, "powerReporting", zcl.Cluster.SimpleMetering,
            zcl.Attribute.InstantaneousDemand, zcl.AttributeTypes.Sint24,
            "-1,-1,10"
        )  # Default power reporting is "between 5 seconds and 15 minutes, or +/- 10W"
        if atCmd != None: return atCmd
        atCmd = CheckReporting(
            devKey, reporting, "energyConsumedReporting",
            zcl.Cluster.SimpleMetering,
            zcl.Attribute.CurrentSummationDelivered, zcl.AttributeTypes.Uint48,
            "-1,-1,100"
        )  # Default energy consumed reporting is "between 1 minute and 15 minutes, or +100Wh"
        if atCmd != None: return atCmd
        atCmd = CheckReporting(
            devKey, reporting, "energyGeneratedReporting",
            zcl.Cluster.SimpleMetering, zcl.Attribute.CurrentSummationReceived,
            zcl.AttributeTypes.Uint48, "-1,-1,0"
        )  # Default energy generated reporting is "never" (-1 as max)
        if atCmd != None: return atCmd
    if zcl.Cluster.Thermostat in binding:
        atCmd = CheckReporting(
            devKey, reporting, "targetTempReporting", zcl.Cluster.Thermostat,
            zcl.Attribute.OccupiedHeatingSetPoint, zcl.AttributeTypes.Sint16,
            "60,900,100"
        )  # Default target temperature reporting is "between 1 minute and 15 minutes, or +/-1.00'C"
        if atCmd != None: return atCmd
    if GetTempVal(devKey, "JustSentOnOff"):
        DelTempVal(devKey, "JustSentOnOff")
        return telegesis.ReadAttr(
            nwkId, ep, zcl.Cluster.OnOff,
            zcl.Attribute.OnOffState)  # Get OnOff state after sending toggle
    return None
示例#4
0
def Check(devIdx, consume):
    global pendingBinding, pendingRptAttrId
    devId = GetVal(devIdx, "devId")
    ep = GetVal(devIdx, "EP")
    eui = GetVal(devIdx, "EUI")
    if None == ep:
        return ("AT+ACTEPDESC:" + devId + "," + devId, "ActEpDesc")
    if None == eui:
        return ("AT+EUIREQ:" + devId + "," + devId, "AddrResp")
    if None == GetVal(devIdx, "InCluster") or None == GetVal(
            devIdx, "OutCluster"):
        SetVal(devIdx, "OutCluster", [])  # Some devices have no outclusters...
        return ("AT+SIMPLEDESC:" + devId + "," + devId + "," + ep,
                "OutCluster")
    inClstr = GetVal(
        devIdx,
        "InCluster")  # Assume we have a list of clusters if we get this far
    outClstr = GetVal(devIdx, "OutCluster")
    binding = GetVal(devIdx, "Binding")
    rprtg = GetVal(devIdx, "Reporting")
    if inClstr != None:
        if binding != None:
            if zcl.Cluster.PollCtrl in inClstr and zcl.Cluster.PollCtrl not in binding:
                return SetBinding(
                    devIdx, zcl.Cluster.PollCtrl,
                    "01")  # 01 is our endpoint we want messages to come to
            if zcl.Cluster.OnOff in outClstr and zcl.Cluster.OnOff not in binding:  # If device sends OnOff commands...
                return SetBinding(
                    devIdx, zcl.Cluster.OnOff,
                    "0A")  # 0A is our endpoint we want messages to come to
            if zcl.Cluster.Temperature in inClstr and zcl.Cluster.Temperature not in binding:
                return SetBinding(
                    devIdx, zcl.Cluster.Temperature,
                    "01")  # 01 is our endpoint we want messages to come to
        else:
            SetVal(devIdx, "Binding", [])
        if zcl.Cluster.IAS_Zone in inClstr:
            if None == GetAttrVal(devIdx, zcl.Cluster.IAS_Zone,
                                  zcl.Attribute.Zone_Type):
                return telegesis.ReadAttr(
                    devId, ep, zcl.Cluster.IAS_Zone, zcl.Attribute.Zone_Type
                )  # Get IAS device type (PIR or contact, etc.)
        if zcl.Cluster.Basic in inClstr:
            if None == GetAttrVal(devIdx, zcl.Cluster.Basic,
                                  zcl.Attribute.Model_Name):
                return telegesis.ReadAttr(
                    devId, ep, zcl.Cluster.Basic,
                    zcl.Attribute.Model_Name)  # Get Basic's Device Name
            if None == GetAttrVal(devIdx, zcl.Cluster.Basic,
                                  zcl.Attribute.Manuf_Name):
                return telegesis.ReadAttr(
                    devId, ep, zcl.Cluster.Basic,
                    zcl.Attribute.Manuf_Name)  # Get Basic's Manufacturer Name
        if zcl.Cluster.PowerConfig in inClstr and "SED" == GetVal(
                devIdx, "DevType"):
            if None == GetAttrVal(
                    devIdx, zcl.Cluster.PowerConfig,
                    zcl.Attribute.Batt_Percentage
            ) or datetime.now() > GetTempVal(devIdx, "GetNextBatteryAfter"):
                return telegesis.ReadAttr(
                    devId, ep, zcl.Cluster.PowerConfig,
                    zcl.Attribute.Batt_Percentage)  # Get Battery percentage
        if rprtg != None:
            if zcl.Cluster.Temperature in inClstr:
                tmpRpt = zcl.Cluster.Temperature + ":" + zcl.Attribute.Celsius
                if zcl.Cluster.Temperature in binding and tmpRpt not in rprtg:
                    pendingRptAttrId = zcl.Attribute.Celsius
                    return (
                        "AT+CFGRPT:" + devId + "," + ep + ",0," +
                        zcl.Cluster.Temperature + ",0," +
                        zcl.Attribute.Celsius + "," +
                        zcl.AttributeTypes.Uint16 + ",012C,0E10,0064",
                        "CFGRPTRP"
                    )  # 012C is 300==5 mins, 0E10 is 3600==1 hour, 0064 is 100, being 1.00'C
        else:
            SetVal(devIdx, "Reporting", [])
    wantOnOff = GetTempVal(devIdx, "JustSentOnOff")
    if wantOnOff:
        DelTempVal(devIdx, "JustSentOnOff")
        return telegesis.ReadAttr(
            devId, ep, zcl.Cluster.OnOff,
            zcl.Attribute.OnOffState)  # Get OnOff state after sending toggle
    pendingAtCmd = GetTempVal(devIdx, "AtCmdRsp")
    if pendingAtCmd:
        if consume:
            DelTempVal(
                devIdx, "AtCmdRsp"
            )  # Remove item if we're about to use it (presuming successful sending of command...)
    return pendingAtCmd