예제 #1
0
def rest_binding(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())

    if verb != "PUT" or len(parameters) != 0:
        return _response

    _response["Data"] = None

    data = data.decode("utf8")
    data = json.loads(data)

    if "sourceIeee" not in data and "sourceEp" not in data and "destIeee" not in data and "destEp" not in data and "cluster" not in data:
        Domoticz.Error("-----> uncomplet json %s" % data)
        _response["Data"] = json.dumps("uncomplet json %s" % data)
        return _response

    self.logging(
        "Debug",
        "rest_binding - Source: %s/%s Dest: %s/%s Cluster: %s" %
        (data["sourceIeee"], data["sourceEp"], data["destIeee"],
         data["destEp"], data["cluster"]),
    )
    webBind(self, data["sourceIeee"], data["sourceEp"], data["destIeee"],
            data["destEp"], data["cluster"])
    _response["Data"] = json.dumps(
        "Binding cluster %s between %s/%s and %s/%s" %
        (data["cluster"], data["sourceIeee"], data["sourceEp"],
         data["destIeee"], data["destEp"]))
    return _response
예제 #2
0
def rest_bindLSTdevice(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())

    if len(parameters) != 1:
        Domoticz.Error("Must have 1 argument. %s" % parameters)
        return _response

    listofdevices = []
    clustertobind = parameters[0]

    for key in self.ListOfDevices:
        if key == "0000":
            dev = {
                "IEEE": self.ListOfDevices[key]["IEEE"],
                "NwkId": key,
                "Ep": "01",
                "ZDeviceName": self.ListOfDevices[key]["ZDeviceName"],
            }
            listofdevices.append(dev)
            continue

        for ep in self.ListOfDevices[key]["Ep"]:
            if clustertobind in self.ListOfDevices[key]["Ep"][ep]:
                dev = {
                    "IEEE": self.ListOfDevices[key]["IEEE"],
                    "NwkId": key,
                    "Ep": ep,
                    "ZDeviceName": self.ListOfDevices[key]["ZDeviceName"],
                }

                if dev not in listofdevices:
                    listofdevices.append(dev)
    _response["Data"] = json.dumps(listofdevices)
    return _response
예제 #3
0
def rest_ota_devices_for_manufcode(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())
    _response["Data"] = None

    if self.OTA is None or verb != "GET" or len(parameters) != 1:
        return _response

    if len(self.zigatedata) == 0:
        _response["Data"] = fake_rest_ota_devices_for_manufcode()
        return _response

    manuf_code = parameters[0]
    device_list = []
    for x in self.ListOfDevices:
        if "Manufacturer" not in self.ListOfDevices[
                x] and "Manufacturer Name" not in self.ListOfDevices[x]:
            continue

        compatible = False
        if (manuf_code in MATRIX_MANUFACTURER_NAME
                and "Manufacturer Name" in self.ListOfDevices[x]
                and MATRIX_MANUFACTURER_NAME[manuf_code]
                == self.ListOfDevices[x]["Manufacturer Name"]):
            compatible = True

        if not compatible and self.ListOfDevices[x][
                "Manufacturer"] != manuf_code:
            continue

        Domoticz.Log("Found device: %s" % x)

        device_list.append(get_device_informations(self, x))
    _response["Data"] = json.dumps(device_list, sort_keys=True)
    return _response
예제 #4
0
def rest_group_unbinding(self, verb, data, parameters):

    # curl -X PUT -d '{"sourceIeee":" 84fd27fffe17e4c5", "sourceEp": "01", "groupId": " 4ca3", "cluster": "0006"}' http://127.0.0.1:9441/rest-zigate/1/unbinding-group

    _response = prepResponseMessage(self, setupHeadersResponse())

    if verb != "PUT" or len(parameters) != 0:
        return _response

    _response["Data"] = None

    data = data.decode("utf8")
    data = json.loads(data)

    if "sourceIeee" not in data and "sourceEp" not in data and "groupId" not in data and "cluster" not in data:
        Domoticz.Error("-----> uncomplet json %s" % data)
        _response["Data"] = json.dumps("uncomplet json %s" % data)
        return _response

    self.logging(
        "Debug",
        "rest_group_unbinding - Source: %s/%s Dest: %s Cluster: %s" %
        (data["sourceIeee"], data["sourceEp"], data["groupId"],
         data["cluster"]),
    )
    unbindGroup(self, data["sourceIeee"], data["sourceEp"], data["cluster"],
                data["groupId"])

    _response["Data"] = json.dumps(
        "UnBinding cluster %s between %s/%s and %s" %
        (data["cluster"], data["sourceIeee"], data["sourceEp"],
         data["groupId"]))
    return _response
예제 #5
0
def rest_scan_devices_for_group(self, verb, data, parameter):
    # wget --method=PUT --body-data='[ "0000", "0001", "0002", "0003" ]' http://127.0.0.1:9442/rest-zigate/1/ScanDeviceForGrp

    _response = prepResponseMessage(self, setupHeadersResponse())
    _response["Data"] = None
    if self.groupmgt is None:
        # Group is not enabled!
        return _response

    if verb != "PUT":
        # Only Put command with a Valid JSON is allow
        return _response

    if data is None:
        return _response

    if len(parameter) != 0:
        return _response

    # We receive a JSON with a list of NwkId to be scaned
    data = data.decode("utf8")
    data = json.loads(data)
    self.logging(
        "Debug",
        "rest_scan_devices_for_group - Trigger GroupMemberShip scan for devices: %s "
        % (data))
    self.groupmgt.ScanDevicesForGroupMemberShip(data)
    action = {"Name": "Scan of device requested.", "TimeStamp": int(time())}
    _response["Data"] = json.dumps(action, sort_keys=True)
    return _response
예제 #6
0
def rest_casa_device_ircode_update(self, verb, data, parameters):
    # wget --method=PUT --body-data='[
    # {
    # 	"NwkId": "0a90",
    # 	"IRCode": "1234",
    # },
    # {
    # ....
    # ]
    # ' http://127.0.0.1:9440/rest-zigate/1/ota-firmware-update

    _response = prepResponseMessage(self, setupHeadersResponse())
    _response["Data"] = None

    if verb != "PUT":
        # Only Put command with a Valid JSON is allow
        return _response

    if data is None:
        return _response

    if len(parameters) != 0:
        return _response

    # We receive a JSON with a list of NwkId to be scaned
    data = data.decode("utf8")

    self.logging(
        "Debug",
        "rest_casa_device_ircode_update - Data received  %s " % (data))

    data = json.loads(data)
    self.logging(
        "Debug",
        "rest_casa_device_ircode_update - List of Device IRCode  %s " % (data))

    status = 0
    for x in data:
        if "NwkId" not in x and "IRCode" not in x:
            status = 1
            continue

        if x["NwkId"] in self.ListOfDevices and "CASA.IA" in self.ListOfDevices[
                x["NwkId"]]:
            Domoticz.Log("Updating : %s with %s" % (x["NwkId"], x["IRCode"]))
            if self.ListOfDevices[
                    x["NwkId"]] and "Model" in self.ListOfDevices[x["NwkId"]]:
                self.ListOfDevices[
                    x["NwkId"]]["CASA.IA"][DEVICE_ID]["IRCode"] = x["IRCode"]

    action = {
        " Name": "IRCode update performed status: %s" % status,
        "TimeStamp": int(time())
    }
    _response["Data"] = json.dumps(action, sort_keys=True)
    return _response
예제 #7
0
def rest_new_hrdwr(self, verb, data, parameters):
    """
    This is call to Enable/Disable a Provisioning process. As a toggle you will enable the provisioning or disable it
    it will return either Enable or Disable
    """
    _response = prepResponseMessage(self, setupHeadersResponse())

    if verb != "GET":
        return _response

    data = {}
    if len(parameters) != 1:
        Domoticz.Error("rest_new_hrdwr - unexpected parameter %s " %
                       parameters)
        _response["Data"] = {"unexpected parameter %s " % parameters}
        return _response

    if parameters[0] not in ("enable", "cancel", "disable"):
        Domoticz.Error("rest_new_hrdwr - unexpected parameter %s " %
                       parameters[0])
        _response["Data"] = {"unexpected parameter %s " % parameters[0]}
        return _response

    if parameters[0] == "enable":
        Domoticz.Log("Enable Assisted pairing")
        if len(self.DevicesInPairingMode):
            del self.DevicesInPairingMode
            self.DevicesInPairingMode = []
        if not self.zigatedata:
            # Seems we are in None mode - Testing for ben
            self.fakeDevicesInPairingMode = 0

        if self.permitTojoin["Duration"] != 255 and self.pluginParameters[
                "Mode2"] != "None":
            ZigatePermitToJoin(self, (4 * 60))

        _response["Data"] = {"start pairing mode at %s " % int(time())}
        return _response

    if parameters[0] in ("cancel", "disable"):
        Domoticz.Log("Disable Assisted pairing")
        if len(self.DevicesInPairingMode) != 0:
            del self.DevicesInPairingMode
            self.DevicesInPairingMode = []

        if not self.zigatedata:
            # Seems we are in None mode - Testing for ben
            self.fakeDevicesInPairingMode = 0

        if not (self.permitTojoin["Duration"] == 255
                or self.pluginParameters["Mode2"] == "None"):
            ZigatePermitToJoin(self, 0)

        _response["Data"] = {"stop pairing mode at %s " % int(time())}
        return _response
예제 #8
0
def rest_ota_firmware_update(self, verb, data, parameter):

    # wget --method=PUT --body-data='{
    # 	"NwkId": "0a90",
    # 	"Ep": "0b",
    # 	"Brand": "Schneider",
    # 	"FileName": "EH_ZB_SNP_R_04_01_14_VACT.zigbee"
    # }' http://127.0.0.1:9440/rest-zigate/1/ota-firmware-update
    _response = prepResponseMessage(self, setupHeadersResponse())
    _response["Data"] = None

    if self.OTA is None:
        # OTA is not enabled!
        return _response

    if verb != "PUT":
        # Only Put command with a Valid JSON is allow
        return _response

    if data is None:
        return _response

    if len(parameter) != 0:
        return _response

    # We receive a JSON with a list of NwkId to be scaned
    data = data.decode("utf8")

    self.logging("Debug",
                 "rest_ota_firmware_update - Data received  %s " % (data))

    data = json.loads(data)
    self.logging(
        "Debug",
        "rest_ota_firmware_update - Trigger OTA upgrade  %s " % (data))

    # Check
    for x in data:
        if "Brand" not in x or "FileName" not in x or "NwkId" not in x or "Ep" not in x or "ForceUpdate" not in x:
            self.logging(
                "Error",
                "rest_ota_firmware_update - Missing key parameters  %s " %
                (data))
            _response["Data"] = json.dumps({"Error": "Missing attributes"},
                                           sort_keys=True)
            return _response

    self.logging("Debug", "rest_ota_firmware_update - data: %s" % (data))

    if self.OTA:
        self.OTA.restapi_firmware_update(data)

    action = {"Name": "OTA requested.", "TimeStamp": int(time())}
    _response["Data"] = json.dumps(action, sort_keys=True)
    return _response
예제 #9
0
def rest_ota_firmware_list(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())
    _response["Data"] = None

    if self.OTA and verb == "GET" and len(parameters) == 0:
        if len(self.zigatedata) == 0:
            _response["Data"] = fake_rest_ota_firmware_list()
            return _response

        _response["Data"] = json.dumps(self.OTA.restapi_list_of_firmware(),
                                       sort_keys=True)

    return _response
예제 #10
0
def rest_casa_device_list(self, verb, data, parameters):  # Ok 10/11/2020

    _response = prepResponseMessage(self, setupHeadersResponse())
    _response["Data"] = None

    _response["Data"] = list_casaia_ac201(self)

    if verb == "GET" and len(parameters) == 0:
        if len(self.zigatedata) == 0:
            _response["Data"] = json.dumps(fake_list_casaia_ac201(),
                                           sort_keys=True)
            return _response

        _response["Data"] = json.dumps(list_casaia_ac201(self), sort_keys=True)

    return _response
예제 #11
0
def rest_recreate_widgets(self, verb, data, parameters):

    # curl -X PUT -d '{"IEEE":"00158d0005bea6da"}' http://127.0.0.1:9441/rest-zigate/1/recreate-widgets

    _response = prepResponseMessage(self, setupHeadersResponse())

    Domoticz.Log("rest_recreate_widgets -->Verb: %s Data: %s Parameters: %s" %
                 (verb, data, parameters))

    if verb != "PUT":
        return _response

    data = data.decode("utf8")
    data = eval(data)
    self.logging("Log", "rest_recreate_widgets - Data: %s" % data)

    if "IEEE" not in data and "NWKID" not in data:
        Domoticz.Error("rest_recreate_widgets - unexpected parameter %s " %
                       parameters)
        _response["Data"] = {"unexpected parameter %s " % parameters}
        return _response

    if "IEEE" in data:
        key = data["IEEE"]
        if key not in self.IEEE2NWK:
            Domoticz.Error("rest_recreate_widgets - Unknown device %s " % key)
            return _response
        nwkid = self.IEEE2NWK[key]
        _response["Data"] = {
            "IEEE %s set to Provisioning Requested at %s" % (key, int(time()))
        }
    else:
        nwkid = data["NWKID"]
        if nwkid not in self.ListOfDevices:
            Domoticz.Error("rest_recreate_widgets - Unknown device %s " %
                           nwkid)
            return _response
        _response["Data"] = {
            "NwkId %s set to Provisioning Requested at %s" %
            (nwkid, int(time()))
        }

    over_write_type_from_deviceconf(self, self.Devices, nwkid)
    self.ListOfDevices[nwkid]["Status"] = "CreateDB"
    CreateDomoDevice(self, self.Devices, nwkid)

    return _response
예제 #12
0
def rest_rescan_group(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())
    _response["Headers"]["Content-Type"] = "application/json; charset=utf-8"
    action = {}
    if verb != "GET":
        return _response
    if self.groupmgt:
        self.groupmgt.ScanAllDevicesForGroupMemberShip()
    else:
        Domoticz.Error("rest_rescan_group Group not enabled!!!")
    action["Name"] = "Full Scan"
    action["TimeStamp"] = int(time())

    _response["Data"] = json.dumps(action, sort_keys=True)

    return _response
예제 #13
0
def rest_full_reprovisionning(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())

    Domoticz.Log(
        "rest_full_reprovisionning -->Verb: %s Data: %s Parameters: %s" %
        (verb, data, parameters))

    if verb != "PUT":
        return _response

    data = data.decode("utf8")
    data = eval(data)
    self.logging("Log", "Data: %s" % data)

    if "IEEE" not in data and "NWKID" not in data:
        Domoticz.Error("rest_full_reprovisionning - unexpected parameter %s " %
                       parameters)
        _response["Data"] = {"unexpected parameter %s " % parameters}
        return _response

    if "IEEE" in data:
        key = data["IEEE"]
        if key not in self.IEEE2NWK:
            Domoticz.Error("rest_full_reprovisionning - Unknown device %s " %
                           key)
            return _response
        nwkid = self.IEEE2NWK[key]
        _response["Data"] = {
            "IEEE %s set to Provisioning Requested at %s" % (key, int(time()))
        }
    else:
        nwkid = data["NWKID"]
        if nwkid not in self.ListOfDevices:
            Domoticz.Error("rest_full_reprovisionning - Unknown device %s " %
                           nwkid)
            return _response
        _response["Data"] = {
            "NwkId %s set to Provisioning Requested at %s" %
            (nwkid, int(time()))
        }

    self.ListOfDevices[nwkid]["Status"] = "provREQ"

    return _response
예제 #14
0
def rest_req_topologie(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())

    if verb == "GET":
        action = {"Name": "Req-Topology", "TimeStamp": int(time())}
        _response["Data"] = json.dumps(action, sort_keys=True)

        self.logging("Log", "Request a Start of Network Topology scan")
        if self.networkmap:
            if not self.networkmap.NetworkMapPhase():
                self.networkmap.start_scan()
            else:
                self.logging(
                    "Log",
                    "Cannot start Network Topology as one is in progress...")

    return _response
예제 #15
0
def rest_binding_table_disp(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())
    if verb != "GET":
        return _response

    if len(parameters) != 1:
        return _response

    if parameters[0] not in self.ListOfDevices:
        return _response

    nwkid = parameters[0]

    if "BindingTable" not in self.ListOfDevices[nwkid]:
        return _response

    bindtable = self.ListOfDevices[nwkid]["BindingTable"]
    _response["Data"] = json.dumps(bindtable, sort_keys=True)
    return _response
예제 #16
0
def rest_binding_table_req(self, verb, data, parameters):

    # curl http://127.0.0.1:9440/rest-zigate/1/binding-table-req/bd92
    _response = prepResponseMessage(self, setupHeadersResponse())
    _response["Headers"]["Content-Type"] = "application/json; charset=utf-8"
    if verb != "GET":
        return _response

    if len(parameters) != 1:
        return _response

    if parameters[0] not in self.ListOfDevices:
        return _response

    nwkid = parameters[0]

    mgt_binding_table_req(self, nwkid, start_index="00")
    action = {"Name": "Requested Binding table for device: %s" % nwkid}
    _response["Data"] = json.dumps(action, sort_keys=True)

    return _response
예제 #17
0
def rest_bindLSTcluster(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())

    bindCluster = []
    for key in self.ListOfDevices:
        if key == "0000":
            continue

        for ep in self.ListOfDevices[key]["Ep"]:
            for cluster in self.ListOfDevices[key]["Ep"][ep]:
                if cluster in ZCL_CLUSTERS_ACT:
                    item = {
                        "ClusterId": cluster,
                        "ClusterDesc": ZCL_CLUSTERS_ACT[cluster]
                    }
                    if item not in bindCluster:
                        bindCluster.append(item)
    _response["Data"] = json.dumps(bindCluster)

    return _response
예제 #18
0
def rest_rcv_nw_hrdwr(self, verb, data, parameters):
    """
    Will return a status on the provisioning process. Either Enable or Disable and in case there is a new device provisionned
    during the period, it will return the information captured.
    """

    _response = prepResponseMessage(self, setupHeadersResponse())

    if verb != "GET":
        return _response

    data = {}
    data["NewDevices"] = []

    if not self.zigatedata:
        # Seems we are in None mode - Testing for ben
        if self.fakeDevicesInPairingMode in (0, 1):
            # Do nothing just wait the next pool
            self.fakeDevicesInPairingMode += 1
            _response["Data"] = json.dumps(data)
            return _response

        if self.fakeDevicesInPairingMode in (2, 3):
            self.fakeDevicesInPairingMode += 1
            newdev = {}
            newdev["NwkId"] = list(self.ListOfDevices.keys())[0]
            data["NewDevices"].append(newdev)
            _response["Data"] = json.dumps(data)
            return _response

        if self.fakeDevicesInPairingMode in (4, 5):
            self.fakeDevicesInPairingMode += 1
            newdev = {}
            newdev["NwkId"] = list(self.ListOfDevices.keys())[0]
            data["NewDevices"].append(newdev)
            newdev = {}
            newdev["NwkId"] = list(self.ListOfDevices.keys())[1]
            data["NewDevices"].append(newdev)
            _response["Data"] = json.dumps(data)
            return _response

        if self.fakeDevicesInPairingMode in (6, 7):
            self.fakeDevicesInPairingMode += 1
            self.DevicesInPairingMode.append(
                list(self.ListOfDevices.keys())[0])
            self.DevicesInPairingMode.append(
                list(self.ListOfDevices.keys())[1])
            self.DevicesInPairingMode.append(
                list(self.ListOfDevices.keys())[2])

    Domoticz.Log("Assisted Pairing: Polling: %s" %
                 str(self.DevicesInPairingMode))
    if len(self.DevicesInPairingMode) == 0:
        Domoticz.Log("--> Empty queue")
        _response["Data"] = json.dumps(data)
        return _response

    listOfPairedDevices = list(self.DevicesInPairingMode)
    _fake = 0
    for nwkid in listOfPairedDevices:
        if not self.zigatedata:
            _fake += 1
        if nwkid not in self.ListOfDevices:
            continue
        newdev = {}
        newdev["NwkId"] = nwkid

        Domoticz.Log("--> New device: %s" % nwkid)
        if "Status" not in self.ListOfDevices[nwkid]:
            Domoticz.Error(
                "Something went wrong as the device seems not be created")
            data["NewDevices"].append(newdev)
            continue

        if self.ListOfDevices[nwkid]["Status"] in ("004d", "0045", "0043",
                                                   "8045", "8043") or (_fake
                                                                       == 1):
            # Pairing in progress, just return the Nwkid
            data["NewDevices"].append(newdev)
            continue

        elif self.ListOfDevices[nwkid]["Status"] == "UNKNOW" or (_fake == 2):
            Domoticz.Log("--> UNKNOW , removed %s from List" % nwkid)
            self.DevicesInPairingMode.remove(nwkid)
            newdev["ProvisionStatus"] = "Failed"
            newdev["ProvisionStatusDesc"] = "Failed"

        elif self.ListOfDevices[nwkid]["Status"] == "inDB":
            Domoticz.Log("--> inDB , removed %s from List" % nwkid)
            self.DevicesInPairingMode.remove(nwkid)
            newdev["ProvisionStatus"] = "inDB"
            newdev["ProvisionStatusDesc"] = "inDB"
        else:
            Domoticz.Log("--> Unexpected , removed %s from List" % nwkid)
            self.DevicesInPairingMode.remove(nwkid)
            newdev["ProvisionStatus"] = "Unexpected"
            newdev["ProvisionStatusDesc"] = "Unexpected"
            Domoticz.Error("Unexpected")
            continue

        newdev["IEEE"] = "Unknown"
        if "IEEE" in self.ListOfDevices[nwkid]:
            newdev["IEEE"] = self.ListOfDevices[nwkid]["IEEE"]

        newdev["ProfileId"] = ""
        newdev["ProfileIdDesc"] = "Unknow"
        if "ProfileID" in self.ListOfDevices[nwkid]:
            if self.ListOfDevices[nwkid]["ProfileID"] != {}:
                newdev["ProfileId"] = self.ListOfDevices[nwkid]["ProfileID"]
                if int(newdev["ProfileId"], 16) in PROFILE_ID:
                    newdev["ProfileIdDesc"] = PROFILE_ID[int(
                        newdev["ProfileId"], 16)]

        newdev["ZDeviceID"] = ""
        newdev["ZDeviceIDDesc"] = "Unknow"
        if "ZDeviceID" in self.ListOfDevices[nwkid]:
            if self.ListOfDevices[nwkid]["ZDeviceID"] != {}:
                newdev["ZDeviceID"] = self.ListOfDevices[nwkid]["ZDeviceID"]
                if int(newdev["ProfileId"], 16) == 0x0104:  # ZHA
                    if int(newdev["ZDeviceID"], 16) in ZHA_DEVICES:
                        newdev["ZDeviceIDDesc"] = ZHA_DEVICES[int(
                            newdev["ZDeviceID"], 16)]
                    else:
                        newdev["ZDeviceIDDesc"] = "Unknow"
                elif int(newdev["ProfileId"], 16) == 0xC05E:  # ZLL
                    if int(newdev["ZDeviceID"], 16) in ZLL_DEVICES:
                        newdev["ZDeviceIDDesc"] = ZLL_DEVICES[int(
                            newdev["ZDeviceID"], 16)]

        if "Model" in self.ListOfDevices[nwkid]:
            newdev["Model"] = self.ListOfDevices[nwkid]["Model"]

        newdev["PluginCertified"] = "Unknow"
        if "ConfigSource" in self.ListOfDevices[nwkid]:
            if self.ListOfDevices[nwkid]["ConfigSource"] == "DeviceConf":
                newdev["PluginCertified"] = "yes"
            else:
                newdev["PluginCertified"] = "no"

        newdev["Ep"] = []
        if "Ep" in self.ListOfDevices[nwkid]:
            for iterEp in self.ListOfDevices[nwkid]["Ep"]:
                ep = {}
                ep["Ep"] = iterEp
                ep["Clusters"] = []
                for clusterId in self.ListOfDevices[nwkid]["Ep"][iterEp]:
                    if clusterId in ("ClusterType", "Type", "ColorControl"):
                        continue

                    cluster = {}
                    cluster["ClusterId"] = clusterId
                    if clusterId in ZCL_CLUSTERS_LIST:
                        cluster["ClusterDesc"] = ZCL_CLUSTERS_LIST[clusterId]
                    else:
                        cluster["ClusterDesc"] = "Unknown"
                    ep["Clusters"].append(cluster)
                    Domoticz.Log("------> New Cluster: %s" % str(cluster))
                newdev["Ep"].append(ep)
                Domoticz.Log("----> New Ep: %s" % str(ep))
        data["NewDevices"].append(newdev)
        Domoticz.Log(" --> New Device: %s" % str(newdev))
    # for nwkid in listOfPairedDevices:

    _response["Data"] = json.dumps(data)
    return _response
예제 #19
0
def onMessage(self, Connection, Data):

    self.logging("Debug", "WebServer onMessage : %s" % Data)
    # DumpHTTPResponseToLog(Data)

    headerCode = "200 OK"
    if "Verb" not in Data:
        Domoticz.Error("Invalid web request received, no Verb present")
        headerCode = "400 Bad Request"

    elif Data["Verb"] not in ("GET", "PUT", "POST", "DELETE"):
        Domoticz.Error(
            "Invalid web request received, only GET requests allowed (" +
            Data["Verb"] + ")")
        headerCode = "405 Method Not Allowed"

    elif "URL" not in Data:
        Domoticz.Error("Invalid web request received, no URL present")
        headerCode = "400 Bad Request"

    parsed_url = urlparse(Data["URL"])
    self.logging("Debug",
                 "URL: %s , Path: %s" % (Data["URL"], parsed_url.path))
    if Data["URL"][0] == "/":
        parsed_query = Data["URL"][1:].split("/")

    else:
        parsed_query = Data["URL"].split("/")

    # Any Cookie ?
    cookie = None
    if "Cookie" in Data["Headers"]:
        cookie = Data["Headers"]["Cookie"]

    if "Data" not in Data:
        Data["Data"] = None

    if headerCode != "200 OK":
        self.sendResponse(Connection, {"Status": headerCode})
        return

    if len(parsed_query) >= 3:
        self.logging(
            "Debug",
            "Receiving a REST API - Version: %s, Verb: %s, Command: %s, Param: %s"
            %
            (parsed_query[1], Data["Verb"], parsed_query[2], parsed_query[3:]),
        )
        if parsed_query[0] == "rest-zigate" and parsed_query[1] == "1":
            # API Version 1
            self.do_rest(Connection, Data["Verb"], Data["Data"],
                         parsed_query[1], parsed_query[2], parsed_query[3:])
        else:
            Domoticz.Error("Unknown API  %s" % parsed_query)
            headerCode = "400 Bad Request"
            self.sendResponse(Connection, {"Status": headerCode})
        return

    # Finaly we simply has to serve a File.
    webFilename = self.homedirectory + "www" + Data["URL"]
    self.logging("Debug", "webFilename: %s" % webFilename)
    if not os.path.isfile(webFilename):
        webFilename = self.homedirectory + "www" + "/index.html"
        self.logging("Debug", "Redirecting to /index.html")

    # We are ready to send the response
    _response = setupHeadersResponse(cookie)
    if self.pluginconf.pluginConf["enableKeepalive"]:
        _response["Headers"]["Connection"] = "Keep-alive"
    else:
        _response["Headers"]["Connection"] = "Close"
    if not self.pluginconf.pluginConf["enableCache"]:
        _response["Headers"][
            "Cache-Control"] = "no-cache, no-store, must-revalidate"
        _response["Headers"]["Pragma"] = "no-cache"
        _response["Headers"]["Expires"] = "0"
        _response["Headers"]["Accept"] = "*/*"
    else:
        _response["Headers"]["Cache-Control"] = "private"

    self.logging("Debug", "Opening: %s" % webFilename)
    currentVersionOnServer = os.path.getmtime(webFilename)
    _lastmodified = strftime("%a, %d %m %y %H:%M:%S GMT",
                             gmtime(currentVersionOnServer))

    # Check Referrrer
    if "Referer" in Data["Headers"]:
        self.logging("Debug", "Set Referer: %s" % Data["Headers"]["Referer"])
        _response["Headers"]["Referer"] = Data["Headers"]["Referer"]

    # Can we use Cache if exists
    if self.pluginconf.pluginConf["enableCache"]:
        if "If-Modified-Since" in Data["Headers"]:
            lastVersionInCache = Data["Headers"]["If-Modified-Since"]
            self.logging(
                "Debug", "InCache: %s versus Current: %s" %
                (lastVersionInCache, _lastmodified))
            if lastVersionInCache == _lastmodified:
                # No need to send it back
                self.logging(
                    "Debug",
                    "User Caching - file: %s InCache: %s versus Current: %s" %
                    (webFilename, lastVersionInCache, _lastmodified),
                )
                _response["Status"] = "304 Not Modified"
                self.sendResponse(Connection, _response)
                return _response

    if "Ranges" in Data["Headers"]:
        self.logging("Debug", "Ranges processing")
        RangeProcess = Data["Headers"]["Range"]
        fileStartPosition = int(RangeProcess[RangeProcess.find("=") +
                                             1:RangeProcess.find("-")])
        messageFileSize = os.path.getsize(webFilename)
        messageFile = open(webFilename, mode="rb")
        messageFile.seek(fileStartPosition)
        fileContent = messageFile.read(MAX_KB_TO_SEND)
        self.logging(
            "Debug",
            Connection.Address + ":" + Connection.Port +
            " Sent 'GET' request file '" + Data["URL"] + "' from position " +
            str(fileStartPosition) + ", " + str(len(fileContent)) +
            " bytes will be returned",
        )
        _response["Status"] = "200 OK"
        if len(fileContent) == MAX_KB_TO_SEND:
            _response["Status"] = "206 Partial Content"
            _response["Headers"]["Content-Range"] = (
                "bytes " + str(fileStartPosition) + "-" +
                str(messageFile.tell()) + "/" + str(messageFileSize))
        DumpHTTPResponseToLog(_response)
        Connection.Send(_response)
        if not self.pluginconf.pluginConf["enableKeepalive"]:
            Connection.Disconnect()
    else:
        _response["Headers"]["Last-Modified"] = _lastmodified
        with open(webFilename, mode="rb") as webFile:
            _response["Data"] = webFile.read()

        _contentType, _contentEncoding = mimetypes.guess_type(Data["URL"])

        if _contentType:
            _response["Headers"][
                "Content-Type"] = _contentType + "; charset=utf-8"
        if _contentEncoding:
            _response["Headers"]["Content-Encoding"] = _contentEncoding

        _response["Status"] = "200 OK"

        if "Accept-Encoding" in Data["Headers"]:
            self.sendResponse(
                Connection,
                _response,
                AcceptEncoding=Data["Headers"]["Accept-Encoding"])
        else:
            self.sendResponse(Connection, _response)
예제 #20
0
def do_rest(self, Connection, verb, data, version, command, parameters):

    REST_COMMANDS = {
        "bind-lst-cluster": {
            "Name": "bind-lst-cluster",
            "Verbs": {"GET"},
            "function": self.rest_bindLSTcluster
        },
        "bind-lst-device": {
            "Name": "bind-lst-device",
            "Verbs": {"GET"},
            "function": self.rest_bindLSTdevice
        },
        "binding": {
            "Name": "binding",
            "Verbs": {"PUT"},
            "function": self.rest_binding
        },
        "binding-table-req": {
            "Name": "binding",
            "Verbs": {"GET"},
            "function": self.rest_binding_table_req
        },
        "binding-table-disp": {
            "Name": "binding",
            "Verbs": {"GET"},
            "function": self.rest_binding_table_disp
        },
        "binding-group": {
            "Name": "binding-group",
            "Verbs": {"PUT"},
            "function": self.rest_group_binding
        },
        "casaia-list-devices": {
            "Name": "casaia-list-devices",
            "Verbs": {"GET"},
            "function": self.rest_casa_device_list,
        },
        "casaia-update-ircode": {
            "Name": "casaia-list-devices",
            "Verbs": {"PUT"},
            "function": self.rest_casa_device_ircode_update,
        },
        "change-channel": {
            "Name": "change-channel",
            "Verbs": {"PUT"},
            "function": self.rest_change_channel
        },
        "clear-error-history": {
            "Name": "clear-error-history",
            "Verbs": {"GET"},
            "function": self.rest_logErrorHistoryClear,
        },
        "dev-cap": {
            "Name": "dev-cap",
            "Verbs": {"GET"},
            "function": self.rest_dev_capabilities
        },
        "dev-command": {
            "Name": "dev-command",
            "Verbs": {"PUT"},
            "function": self.rest_dev_command
        },
        "device": {
            "Name": "device",
            "Verbs": {"GET"},
            "function": self.rest_Device
        },
        "domoticz-env": {
            "Name": "domoticz-env",
            "Verbs": {"GET"},
            "function": self.rest_domoticz_env
        },
        "help": {
            "Name": "help",
            "Verbs": {"GET"},
            "function": None
        },
        "full-reprovisionning": {
            "Name": "full-reprovisionning",
            "Verbs": {"PUT"},
            "function": self.rest_full_reprovisionning
        },
        "log-error-history": {
            "Name": "log-error-history",
            "Verbs": {"GET"},
            "function": self.rest_logErrorHistory
        },
        "new-hrdwr": {
            "Name": "new-hrdwr",
            "Verbs": {"GET"},
            "function": self.rest_new_hrdwr
        },
        "nwk-stat": {
            "Name": "nwk_stat",
            "Verbs": {"GET", "DELETE"},
            "function": self.rest_nwk_stat
        },
        "ota-firmware-device-list": {
            "Name": "ota-firmware-list",
            "Verbs": {"GET"},
            "function": self.rest_ota_devices_for_manufcode,
        },
        "ota-firmware-list": {
            "Name": "ota-firmware-list",
            "Verbs": {"GET"},
            "function": self.rest_ota_firmware_list
        },
        "ota-firmware-update": {
            "Name": "ota-firmware-update",
            "Verbs": {"PUT"},
            "function": self.rest_ota_firmware_update,
        },
        "permit-to-join": {
            "Name": "permit-to-join",
            "Verbs": {"GET", "PUT"},
            "function": self.rest_PermitToJoin
        },
        "plugin-health": {
            "Name": "plugin-health",
            "Verbs": {"GET"},
            "function": self.rest_plugin_health
        },
        "plugin-restart": {
            "Name": "plugin-restart",
            "Verbs": {"GET"},
            "function": self.rest_plugin_restart
        },
        "plugin-stat": {
            "Name": "plugin-stat",
            "Verbs": {"GET"},
            "function": self.rest_plugin_stat
        },
        "plugin": {
            "Name": "plugin",
            "Verbs": {"GET"},
            "function": self.rest_PluginEnv
        },
        "raw-command": {
            "Name": "raw-command",
            "Verbs": {"PUT"},
            "function": self.rest_raw_command
        },
        "rcv-nw-hrdwr": {
            "Name": "rcv-nw-hrdwr",
            "Verbs": {"GET"},
            "function": self.rest_rcv_nw_hrdwr
        },
        "recreate-widgets": {
            "Name": "recreate-widgets",
            "Verbs": {"PUT"},
            "function": self.rest_recreate_widgets
        },
        "req-nwk-full": {
            "Name": "req-nwk-full",
            "Verbs": {"GET"},
            "function": self.rest_req_nwk_full
        },
        "req-nwk-inter": {
            "Name": "req-nwk-inter",
            "Verbs": {"GET"},
            "function": self.rest_req_nwk_inter
        },
        "req-topologie": {
            "Name": "req-topologie",
            "Verbs": {"GET"},
            "function": self.rest_req_topologie
        },
        "rescan-groups": {
            "Name": "rescan-groups",
            "Verbs": {"GET"},
            "function": self.rest_rescan_group
        },
        "restart-needed": {
            "Name": "restart-needed",
            "Verbs": {"GET"},
            "function": self.rest_restart_needed
        },
        "scan-device-for-grp": {
            "Name": "ScanDevscan-device-for-grpiceForGrp",
            "Verbs": {"PUT"},
            "function": self.rest_scan_devices_for_group,
        },
        "setting-debug": {
            "Name": "setting",
            "Verbs": {"GET", "PUT"},
            "function": self.rest_Settings_with_debug
        },
        "setting": {
            "Name": "setting",
            "Verbs": {"GET", "PUT"},
            "function": self.rest_Settings_wo_debug
        },
        "sw-reset-zigate": {
            "Name": "sw-reset-zigate",
            "Verbs": {"GET"},
            "function": self.rest_reset_zigate
        },
        "topologie": {
            "Name": "topologie",
            "Verbs": {"GET", "DELETE"},
            "function": self.rest_netTopologie
        },
        "unbinding": {
            "Name": "unbinding",
            "Verbs": {"PUT"},
            "function": self.rest_unbinding
        },
        "unbinding-group": {
            "Name": "unbinding-group",
            "Verbs": {"PUT"},
            "function": self.rest_group_unbinding
        },
        "zdevice-name": {
            "Name": "zdevice-name",
            "Verbs": {"GET", "PUT", "DELETE"},
            "function": self.rest_zDevice_name
        },
        "zdevice-raw": {
            "Name": "zdevice-raw",
            "Verbs": {"GET", "PUT"},
            "function": self.rest_zDevice_raw
        },
        "zdevice": {
            "Name": "zdevice",
            "Verbs": {"GET", "DELETE"},
            "function": self.rest_zDevice
        },
        "zgroup-list-available-device": {
            "Name": "zgroup-list-available-device",
            "Verbs": {"GET"},
            "function": self.rest_zGroup_lst_avlble_dev,
        },
        "zgroup": {
            "Name": "device",
            "Verbs": {"GET", "PUT"},
            "function": self.rest_zGroup
        },
        "zigate-erase-PDM": {
            "Name": "zigate-erase-PDM",
            "Verbs": {"GET"},
            "function": self.rest_zigate_erase_PDM
        },
        "zigate-mode": {
            "Name": "zigate-mode",
            "Verbs": {"GET"},
            "function": self.rest_zigate_mode
        },
        "zigate": {
            "Name": "zigate",
            "Verbs": {"GET"},
            "function": self.rest_zigate
        },
    }

    self.logging(
        "Debug", "do_rest - Verb: %s, Command: %s, Param: %s" %
        (verb, command, parameters))

    HTTPresponse = {}

    if command in REST_COMMANDS and verb in REST_COMMANDS[command]["Verbs"]:
        HTTPresponse = setupHeadersResponse()
        if self.pluginconf.pluginConf["enableKeepalive"]:
            HTTPresponse["Headers"]["Connection"] = "Keep-alive"
        else:
            HTTPresponse["Headers"]["Connection"] = "Close"
        HTTPresponse["Headers"][
            "Cache-Control"] = "no-cache, no-store, must-revalidate"
        HTTPresponse["Headers"]["Pragma"] = "no-cache"
        HTTPresponse["Headers"]["Expires"] = "0"
        HTTPresponse["Headers"]["Accept"] = "*/*"

        if command == "help":
            _response = prepResponseMessage(self, setupHeadersResponse())
            _data = {}
            for x in REST_COMMANDS:
                _data[x] = {}
                _data[x]["Verbs"] = []
                for y in REST_COMMANDS[x]["Verbs"]:
                    _data[x]["Verbs"].append(y)
            _response["Data"] = json.dumps(_data)
            HTTPresponse = _response

        elif version == "1" and REST_COMMANDS[command]["function"]:
            HTTPresponse = REST_COMMANDS[command]["function"](verb, data,
                                                              parameters)

        elif version == "2" and REST_COMMANDS[command]["functionv2"]:
            HTTPresponse = REST_COMMANDS[command]["functionv2"](verb, data,
                                                                parameters)

    self.logging("Debug", "==> return HTTPresponse: %s" % (HTTPresponse))
    if HTTPresponse == {} or HTTPresponse is None:
        # We reach here due to failure !
        HTTPresponse = prepResponseMessage(self, setupHeadersResponse())
        HTTPresponse["Status"] = "400 BAD REQUEST"
        HTTPresponse["Data"] = "Unknown REST command: %s" % command
        HTTPresponse["Headers"]["Content-Type"] = "text/plain; charset=utf-8"

    self.logging(
        "Debug",
        "==> sending HTTPresponse: %s to %s" % (HTTPresponse, Connection))
    self.sendResponse(Connection, HTTPresponse)
예제 #21
0
def rest_zGroup(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())

    self.logging("Debug",
                 "rest_zGroup - ListOfGroups = %s" % str(self.groupmgt))

    if verb == "GET":
        if self.groupmgt is None:
            return _response

        ListOfGroups = self.groupmgt.ListOfGroups
        if ListOfGroups is None or len(ListOfGroups) == 0:
            return _response

        if len(parameters) == 0:
            zgroup_lst = []
            for itergrp in ListOfGroups:
                self.logging("Debug", "Process Group: %s" % itergrp)
                zgroup = {}
                zgroup["_GroupId"] = itergrp
                zgroup["GroupName"] = ListOfGroups[itergrp]["Name"]
                zgroup["Devices"] = []
                for itemDevice in ListOfGroups[itergrp]["Devices"]:
                    if len(itemDevice) == 2:
                        dev, ep = itemDevice
                        ieee = self.ListOfDevices[dev]["IEEE"]

                    elif len(itemDevice) == 3:
                        dev, ep, ieee = itemDevice

                    self.logging("Debug", "--> add %s %s %s" % (dev, ep, ieee))
                    _dev = {}
                    _dev["_NwkId"] = dev
                    _dev["Ep"] = ep
                    _dev["IEEE"] = ieee
                    zgroup["Devices"].append(_dev)

                if "WidgetStyle" in ListOfGroups[itergrp]:
                    zgroup["WidgetStyle"] = ListOfGroups[itergrp][
                        "WidgetStyle"]

                if "Cluster" in ListOfGroups[itergrp]:
                    zgroup["Cluster"] = ListOfGroups[itergrp]["Cluster"]

                # Let's check if we don't have an Ikea Remote in the group
                if "Tradfri Remote" in ListOfGroups[itergrp]:
                    self.logging("Debug", "--> add Ikea Tradfri Remote")
                    _dev = {}
                    _dev["_NwkId"] = ListOfGroups[itergrp]["Tradfri Remote"][
                        "Device Addr"]
                    _dev["Unit"] = ListOfGroups[itergrp]["Tradfri Remote"][
                        "Device Id"]
                    _dev["Ep"] = ListOfGroups[itergrp]["Tradfri Remote"]["Ep"]
                    _dev["Color Mode"] = ListOfGroups[itergrp][
                        "Tradfri Remote"]["Color Mode"]
                    zgroup["Devices"].append(_dev)
                zgroup_lst.append(zgroup)
            self.logging("Debug", "zGroup: %s" % zgroup_lst)
            _response["Data"] = json.dumps(zgroup_lst, sort_keys=True)

        elif len(parameters) == 1:
            if parameters[0] in ListOfGroups:
                itemGroup = parameters[0]
                zgroup = {}
                zgroup["_GroupId"] = itemGroup
                zgroup["GroupName"] = ListOfGroups[itemGroup]["Name"]
                zgroup["Devices"] = {}
                for itemDevice in ListOfGroups[itemGroup]["Devices"]:
                    if len(itemDevice) == 2:
                        dev, ep = itemDevice
                        _ieee = self.ListOfDevices[dev]["IEEE"]

                    elif len(itemDevice) == 3:
                        dev, ep, _ieee = itemDevice

                    self.logging("Debug", "--> add %s %s" % (dev, ep))
                    zgroup["Devices"][dev] = ep

                # Let's check if we don't have an Ikea Remote in the group
                if "Tradfri Remote" in ListOfGroups[itemGroup]:
                    self.logging("Log", "--> add Ikea Tradfri Remote")
                    _dev = {}
                    _dev["_NwkId"] = ListOfGroups[itemGroup]["Tradfri Remote"][
                        "Device Addr"]
                    _dev["Ep"] = "01"
                    # zgroup["Devices"].append(_dev)  This looks very bad. Don't know where it is coming from
                    zgroup["Devices"][ListOfGroups[itemGroup]["Tradfri Remote"]
                                      ["Device Addr"]] = "01"
                _response["Data"] = json.dumps(zgroup, sort_keys=True)

        return _response

    if verb == "PUT":
        _response["Data"] = None
        if not self.groupmgt:
            Domoticz.Error("Looks like Group Management is not enabled")
            _response["Data"] = {}
            return _response

        ListOfGroups = self.groupmgt.ListOfGroups
        grp_lst = []
        if len(parameters) == 0:
            data = data.decode("utf8")
            _response["Data"] = {}
            self.groupmgt.process_web_request(json.loads(data))

        # end if len()
    # end if Verb=

    return _response
예제 #22
0
def rest_netTopologie(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())

    _filename = self.pluginconf.pluginConf[
        "pluginReports"] + "NetworkTopology-v3-" + "%02d" % self.hardwareID + ".json"
    self.logging("Debug", "Filename: %s" % _filename)

    if not os.path.isfile(_filename):
        _response["Data"] = json.dumps({}, sort_keys=True)
        return _response

    # Read the file, as we have anyway to do it
    _topo = {}  # All Topo reports
    _timestamps_lst = []  # Just the list of Timestamps
    with open(_filename, "rt") as handle:
        for line in handle:
            if line[0] != "{" and line[-1] != "}":
                continue
            entry = json.loads(line)
            for _ts in entry:
                _timestamps_lst.append(int(_ts))
                _topo[_ts] = [
                ]  # List of Father -> Child relation for one TimeStamp
                reportLQI = entry[_ts]
                _topo[_ts] = extract_report(self, reportLQI)

    if verb == "DELETE":
        if len(parameters) == 0:
            os.remove(_filename)
            action = {}
            action["Name"] = "File-Removed"
            action["FileName"] = _filename
            _response["Data"] = json.dumps(action, sort_keys=True)

        elif len(parameters) == 1:
            timestamp = parameters[0]
            if timestamp in _topo:
                self.logging(
                    "Debug", "Removing Report: %s from %s records" %
                    (timestamp, len(_topo)))
                with open(_filename, "r+") as handle:
                    d = handle.readlines()
                    handle.seek(0)
                    for line in d:
                        if line[0] != "{" and line[-1] != "}":
                            handle.write(line)
                            continue
                        entry = json.loads(line)
                        entry_ts = entry.keys()
                        if len(entry_ts) == 1:
                            if timestamp in entry_ts:
                                self.logging(
                                    "Debug",
                                    "--------> Skiping %s" % timestamp)
                                continue
                        else:
                            continue
                        handle.write(line)
                    handle.truncate()

                action = {}
                action["Name"] = "Report %s removed" % timestamp
                _response["Data"] = json.dumps(action, sort_keys=True)
            else:
                Domoticz.Error("Removing Topo Report %s not found" % timestamp)
                _response["Data"] = json.dumps([], sort_keys=True)
        return _response

    if verb == "GET":
        if len(parameters) == 0:
            # Send list of Time Stamps
            _response["Data"] = json.dumps(_timestamps_lst, sort_keys=True)

        elif len(parameters) == 1:
            timestamp = parameters[0]
            if timestamp in _topo:
                self.logging("Debug", "Topologie sent: %s" % _topo[timestamp])
                _response["Data"] = json.dumps(_topo[timestamp],
                                               sort_keys=True)
            else:
                _response["Data"] = json.dumps([], sort_keys=True)

    return _response
예제 #23
0
def rest_zGroup_lst_avlble_dev(self, verb, data, parameters):

    _response = prepResponseMessage(self, setupHeadersResponse())

    if verb != "GET":
        return _response

    device_lst = []
    _device = {}
    _widget = {}
    _device["_NwkId"] = "0000"
    _device["WidgetList"] = []

    _widget["_ID"] = ""
    _widget["Name"] = ""
    _widget["IEEE"] = "0000000000000000"
    _widget["Ep"] = "01"
    _widget["ZDeviceName"] = "Zigate (Coordinator)"

    if self.zigatedata and "IEEE" in self.zigatedata:
        _widget["IEEE"] = self.zigatedata["IEEE"]
        _device["_NwkId"] = self.zigatedata["Short Address"]

    _device["WidgetList"].append(_widget)
    device_lst.append(_device)

    for x in self.ListOfDevices:
        if x == "0000":
            continue

        if "MacCapa" not in self.ListOfDevices[x]:
            self.logging(
                "Debug",
                "rest_zGroup_lst_avlble_dev - no 'MacCapa' info found for %s!!!!"
                % x)
            continue

        IkeaRemote = False
        if self.pluginconf.pluginConf["GroupOnBattery"] or (
                "Type" in self.ListOfDevices[x]
                and self.ListOfDevices[x]["Type"] == "Ikea_Round_5b"):
            IkeaRemote = True

        if not (self.ListOfDevices[x]["MacCapa"] == "8e" or IkeaRemote):
            self.logging(
                "Debug",
                "rest_zGroup_lst_avlble_dev - %s not a Main Powered device. " %
                x)
            continue

        if "Ep" in self.ListOfDevices[
                x] and "ZDeviceName" in self.ListOfDevices[
                    x] and "IEEE" in self.ListOfDevices[x]:
            _device = {"_NwkId": x, "WidgetList": []}
            for ep in self.ListOfDevices[x]["Ep"]:
                if "Type" in self.ListOfDevices[x] and self.ListOfDevices[x][
                        "Type"] == "Ikea_Round_5b" and ep == "01" and "ClusterType" in self.ListOfDevices[
                            x]["Ep"]["01"]:
                    widgetID = ""
                    for iterDev in self.ListOfDevices[x]["Ep"]["01"][
                            "ClusterType"]:
                        if self.ListOfDevices[x]["Ep"]["01"]["ClusterType"][
                                iterDev] == "Ikea_Round_5b":
                            widgetID = iterDev
                            for widget in self.Devices:
                                if self.Devices[widget].ID == int(widgetID):
                                    _widget = {
                                        "_ID":
                                        self.Devices[widget].ID,
                                        "Name":
                                        self.Devices[widget].Name,
                                        "IEEE":
                                        self.ListOfDevices[x]["IEEE"],
                                        "Ep":
                                        ep,
                                        "ZDeviceName":
                                        self.ListOfDevices[x]["ZDeviceName"],
                                    }

                                    if _widget not in _device["WidgetList"]:
                                        _device["WidgetList"].append(_widget)
                                    break
                            if _device not in device_lst:
                                device_lst.append(_device)
                    continue  # Next Ep

                if not ("0004" in self.ListOfDevices[x]["Ep"][ep]
                        or "ClusterType" in self.ListOfDevices[x]["Ep"][ep]
                        and "ClusterType" in self.ListOfDevices[x]
                        or "0006" in self.ListOfDevices[x]["Ep"][ep]
                        or "0008" in self.ListOfDevices[x]["Ep"][ep]
                        or "0102" in self.ListOfDevices[x]["Ep"][ep]):
                    continue

                if "ClusterType" in self.ListOfDevices[x]["Ep"][ep]:
                    clusterType = self.ListOfDevices[x]["Ep"][ep][
                        "ClusterType"]
                    for widgetID in clusterType:
                        if clusterType[widgetID] not in (
                                "LvlControl",
                                "Switch",
                                "Plug",
                                "SwitchAQ2",
                                "DSwitch",
                                "Button",
                                "DButton",
                                "LivoloSWL",
                                "LivoloSWR",
                                "ColorControlRGB",
                                "ColorControlWW",
                                "ColorControlRGBWW",
                                "ColorControlFull",
                                "ColorControl",
                                "VenetianInverted",
                                "Venetian",
                                "WindowCovering",
                        ):
                            continue

                        for widget in self.Devices:
                            if self.Devices[widget].ID == int(widgetID):
                                _widget = {}
                                _widget["_ID"] = self.Devices[widget].ID
                                _widget["Name"] = self.Devices[widget].Name
                                _widget["IEEE"] = self.ListOfDevices[x]["IEEE"]
                                _widget["Ep"] = ep
                                _widget["ZDeviceName"] = self.ListOfDevices[x][
                                    "ZDeviceName"]
                                if _widget not in _device["WidgetList"]:
                                    _device["WidgetList"].append(_widget)

                elif "ClusterType" in self.ListOfDevices[x]:
                    clusterType = self.ListOfDevices[x]["ClusterType"]

                    for widgetID in clusterType:
                        if clusterType[widgetID] not in (
                                "LvlControl",
                                "Switch",
                                "Plug",
                                "SwitchAQ2",
                                "DSwitch",
                                "Button",
                                "DButton",
                                "LivoloSWL",
                                "LivoloSWR",
                                "ColorControlRGB",
                                "ColorControlWW",
                                "ColorControlRGBWW",
                                "ColorControlFull",
                                "ColorControl",
                                "VenetianInverted",
                                "Venetian",
                                "WindowCovering",
                        ):
                            continue

                        for widget in self.Devices:
                            if self.Devices[widget].ID == int(widgetID):
                                _widget = {}
                                _widget["_ID"] = self.Devices[widget].ID
                                _widget["Name"] = self.Devices[widget].Name
                                _widget["IEEE"] = self.ListOfDevices[x]["IEEE"]
                                _widget["Ep"] = ep
                                _widget["ZDeviceName"] = self.ListOfDevices[x][
                                    "ZDeviceName"]
                                if _widget not in _device["WidgetList"]:
                                    _device["WidgetList"].append(_widget)

        if _device not in device_lst:
            device_lst.append(_device)
    self.logging("Debug", "Response: %s" % device_lst)
    _response["Data"] = json.dumps(device_lst, sort_keys=True)
    return _response