示例#1
0
def discover(bridge_config, new_lights):
    logging.debug("tasmota: <discover> invoked!")

    device_ips = check_output("nmap  " + getIpAddress() + "/24 -p80 --open -n | grep report | cut -d ' ' -f5", shell=True).decode('utf-8').rstrip("\n").split("\n")
    del device_ips[-1] #delete last empty element in list
    for ip in device_ips:
        try:
            logging.debug ( "tasmota: probing ip " + ip)
            response = requests.get ("http://" + ip + "/cm?cmnd=Status%200", timeout=3)
            if response.status_code == 200:
                device_data = json.loads(response.text)
                #logging.debug(pretty_json(device_data))
                if ("StatusSTS" in device_data) and ("Color" in device_data["StatusSTS"]):

                    logging.debug("tasmota: " + ip + " is a Tasmota device ")
                    logging.debug ("tasmota: Hostname: " + device_data["StatusNET"]["Hostname"] )
                    logging.debug ("tasmota: Mac:      " + device_data["StatusNET"]["Mac"] )

                    properties = {"rgb": True, "ct": False, "ip": ip, "name": device_data["StatusNET"]["Hostname"], "id": device_data["StatusNET"]["Mac"], "mac": device_data["StatusNET"]["Mac"]}
                    device_exist = False
                    for light in bridge_config["lights_address"].keys():
                        if bridge_config["lights_address"][light]["protocol"] == "tasmota" and  bridge_config["lights_address"][light]["id"] == properties["id"]:
                            device_exist = True
                            bridge_config["lights_address"][light]["ip"] = properties["ip"]
                            logging.debug("tasmota: light id " + properties["id"] + " already exist, updating ip...")
                            break
                    if (not device_exist):
                        light_name = "Tasmota id " + properties["id"][-8:] if properties["name"] == "" else properties["name"]
                        logging.debug("tasmota: Add Tasmota: " + properties["id"])
                        modelid = "Tasmota"
                        new_light_id = nextFreeId(bridge_config, "lights")
                        bridge_config["lights"][new_light_id] = {"state": light_types[modelid]["state"], "type": light_types[modelid]["type"], "name": light_name, "uniqueid": "4a:e0:ad:7f:cf:" + str(random.randrange(0, 99)) + "-1", "modelid": modelid, "manufacturername": "Tasmota", "swversion": light_types[modelid]["swversion"]}
                        new_lights.update({new_light_id: {"name": light_name}})
                        bridge_config["lights_address"][new_light_id] = {"ip": properties["ip"], "id": properties["id"], "protocol": "tasmota"}

        except Exception as e:
            logging.debug("tasmota: ip " + ip + " is unknow device, " + str(e))
示例#2
0
def discover(bridge_config, new_lights):
    logging.debug("ESPHome: <discover> invoked!")

    device_ips = check_output(
        "nmap  " + getIpAddress() +
        "/24 -p80 --open -n | grep report | cut -d ' ' -f5",
        shell=True).decode('utf-8').rstrip("\n").split("\n")
    del device_ips[-1]  # delete last empty element in list
    for ip in device_ips:
        try:
            logging.debug("ESPHome: probing ip " + ip)
            response = requests.get("http://" + ip + "/text_sensor/light_id",
                                    timeout=3)
            device = json.loads(response.text)['state'].split(
                ';')  # get device data
            mac = device[1]
            device_name = device[2]
            ct_boost = device[3]
            rgb_boost = device[4]
            if response.status_code == 200 and device[
                    0] == "esphome_diyhue_light":
                logging.debug("ESPHome: Found " + device_name + " at ip " + ip)
                white_response = requests.get("http://" + ip +
                                              "/light/white_led",
                                              timeout=3)
                color_response = requests.get("http://" + ip +
                                              "/light/color_led",
                                              timeout=3)
                dim_response = requests.get("http://" + ip +
                                            "/light/dimmable_led",
                                            timeout=3)
                toggle_response = requests.get("http://" + ip +
                                               "/light/toggle_led",
                                               timeout=3)

                if (white_response.status_code != 200
                        and color_response.status_code != 200
                        and dim_response != 200 and toggle_response != 200):
                    logging.debug(
                        "ESPHome: Device has improper configuration! Exiting.")
                    raise
                elif (white_response.status_code == 200
                      and color_response.status_code == 200):
                    logging.debug("ESPHome: " + device_name +
                                  " is a RGBW ESPHome device")
                    white_device_data = json.loads(white_response.text)
                    color_device_data = json.loads(color_response.text)
                    properties = {
                        "rgb": True,
                        "ct": True,
                        "ip": ip,
                        "name": device_name,
                        "id": mac,
                        "mac": mac,
                        "ct_boost": ct_boost,
                        "rgb_boost": rgb_boost
                    }
                    esphome_model = "ESPHome-RGBW"
                    modelid = "LCT015"
                elif (white_response.status_code == 200):
                    logging.debug("ESPHome: " + device_name +
                                  " is a CT ESPHome device")
                    white_device_data = json.loads(white_response.text)
                    properties = {
                        "rgb": False,
                        "ct": True,
                        "ip": ip,
                        "name": device_name,
                        "id": mac,
                        "mac": mac,
                        "ct_boost": ct_boost,
                        "rgb_boost": rgb_boost
                    }
                    esphome_model = "ESPHome-CT"
                    modelid = "LWB010"
                elif (color_response.status_code == 200):
                    logging.debug("ESPHome: " + device_name +
                                  " is a RGB ESPHome device")
                    color_device_data = json.loads(color_response.text)
                    properties = {
                        "rgb": True,
                        "ct": False,
                        "ip": ip,
                        "name": device_name,
                        "id": mac,
                        "mac": mac,
                        "ct_boost": ct_boost,
                        "rgb_boost": rgb_boost
                    }
                    esphome_model = "ESPHome-RGB"
                    modelid = "ESPHome-RGB"
                elif (dim_response.status_code == 200):
                    logging.debug("ESPHome: " + device_name +
                                  " is a Dimmable ESPHome device")
                    dim_device_data = json.loads(dim_response.text)
                    properties = {
                        "rgb": False,
                        "ct": False,
                        "ip": ip,
                        "name": device_name,
                        "id": mac,
                        "mac": mac,
                        "ct_boost": ct_boost,
                        "rgb_boost": rgb_boost
                    }
                    esphome_model = "ESPHome-Dimmable"
                    modelid = "ESPHome-Dimmable"
                elif (toggle_response.status_code == 200):
                    logging.debug("ESPHome: " + device_name +
                                  " is a Toggle ESPHome device")
                    toggle_device_data = json.loads(toggle_response.text)
                    properties = {
                        "rgb": False,
                        "ct": False,
                        "ip": ip,
                        "name": device_name,
                        "id": mac,
                        "mac": mac,
                        "ct_boost": ct_boost,
                        "rgb_boost": rgb_boost
                    }
                    esphome_model = "ESPHome-Toggle"
                    modelid = "ESPHome-Toggle"

                device_exist = False
                for light in bridge_config["lights_address"].keys():
                    if bridge_config["lights_address"][light][
                            "protocol"] == "esphome" and bridge_config[
                                "lights_address"][light]["id"] == properties[
                                    "id"]:
                        device_exist = True
                        bridge_config["lights_address"][light][
                            "ip"] = properties["ip"]
                        bridge_config["lights_address"][light][
                            "ct_boost"] = properties["ct_boost"]
                        bridge_config["lights_address"][light][
                            "rgb_boost"] = properties["rgb_boost"]
                        logging.debug(
                            "ESPHome: light id " + properties["id"] +
                            " already exists, updating device data...")
                        break
                if (not device_exist):
                    light_name = "ESPHome id " + \
                        properties["id"][-8:] if properties["name"] == "" else properties["name"]
                    logging.debug("ESPHome: Adding ESPHome " +
                                  properties["id"])
                    new_light_id = nextFreeId(bridge_config, "lights")
                    bridge_config["lights"][new_light_id] = {}
                    bridge_config["lights"][new_light_id][
                        "state"] = light_types[modelid]["state"]
                    bridge_config["lights"][new_light_id][
                        "type"] = light_types[modelid]["type"]
                    bridge_config["lights"][new_light_id]["name"] = light_name
                    bridge_config["lights"][new_light_id]["modelid"] = modelid
                    bridge_config["lights"][new_light_id][
                        "manufacturername"] = light_types[modelid][
                            "manufacturername"]
                    bridge_config["lights"][new_light_id][
                        "swversion"] = light_types[modelid]["swversion"]
                    bridge_config["lights"][new_light_id][
                        "config"] = light_types[modelid]["config"]
                    bridge_config["lights"][new_light_id]["uniqueid"] = mac
                    if modelid == "LCT015":
                        bridge_config["lights"][new_light_id][
                            "capabilities"] = light_types[modelid][
                                "capabilities"]
                        bridge_config["lights"][new_light_id][
                            "streaming"] = light_types[modelid]["streaming"]
                    #new_lights.update({new_light_id: {"name": light_name}})
                    bridge_config["lights_address"][new_light_id] = {}
                    bridge_config["lights_address"][new_light_id][
                        "ip"] = properties["ip"]
                    bridge_config["lights_address"][new_light_id][
                        "id"] = properties["id"]
                    bridge_config["lights_address"][new_light_id][
                        "protocol"] = "esphome"
                    bridge_config["lights_address"][new_light_id][
                        "rgb_boost"] = rgb_boost
                    bridge_config["lights_address"][new_light_id][
                        "ct_boost"] = ct_boost
                    bridge_config["lights_address"][new_light_id][
                        "esphome_model"] = esphome_model

        except Exception as e:
            logging.debug("ESPHome: ip " + ip + " is unknown device, " +
                          str(e))
示例#3
0
def discover(bridge_config, new_lights):
    logging.debug("shelly: <discover> invoked!")

    device_ips = check_output(
        "nmap  " + getIpAddress() +
        "/24 -p80 --open -n | grep report | cut -d ' ' -f5",
        shell=True).decode('utf-8').rstrip("\n").split("\n")
    del device_ips[-1]  # delete last empty element in list
    for ip in device_ips:
        logging.debug("shelly: found ip: " + ip)
        try:
            logging.debug("shelly: probing ip " + ip)
            response = requests.get("http://" + ip + "/shelly", timeout=5)
            if response.status_code == 200:
                device_data = json.loads(response.text)
                if device_data["type"] == "SHSW-1":

                    logging.debug("shelly: " + ip + " is a shelly device ")
                    shelly_response = requests.get("http://" + ip + "/status",
                                                   timeout=5)
                    shelly_data = json.loads(shelly_response.text)
                    logging.debug("shelly: ip: " +
                                  shelly_data["wifi_sta"]["ip"])
                    logging.debug("shelly: Mac:      " + shelly_data["mac"])

                    properties = {
                        "ip": ip,
                        "name": ip,
                        "id": shelly_data["mac"],
                        "mac": shelly_data["mac"]
                    }
                    device_exist = False
                    for light in bridge_config["lights_address"].keys():
                        if bridge_config["lights_address"][light]["protocol"] == "shelly" and \
                                bridge_config["lights_address"][light]["id"] == properties["id"]:
                            device_exist = True
                            bridge_config["lights_address"][light][
                                "ip"] = properties["ip"]
                            logging.debug("shelly: light id " +
                                          properties["id"] +
                                          " already exist, updating ip...")
                            break
                    if (not device_exist):
                        light_name = "shelly id " + properties["id"][
                            -8:] if properties["name"] == "" else properties[
                                "name"]
                        logging.debug("shelly: Add shelly: " +
                                      properties["id"])
                        modelid = "Shelly"
                        new_light_id = nextFreeId(bridge_config, "lights")
                        bridge_config["lights"][new_light_id] = {
                            "state":
                            light_types[modelid]["state"],
                            "type":
                            light_types[modelid]["type"],
                            "name":
                            light_name,
                            "uniqueid":
                            "4a:e0:ad:7f:cf:" + str(random.randrange(0, 99)) +
                            "-1",
                            "modelid":
                            modelid,
                            "manufacturername":
                            "Shelly",
                            "swversion":
                            light_types[modelid]["swversion"]
                        }
                        new_lights.update({new_light_id: {"name": light_name}})
                        bridge_config["lights_address"][new_light_id] = {
                            "ip": properties["ip"],
                            "id": properties["id"],
                            "protocol": "shelly"
                        }

        except Exception as e:
            logging.debug("shelly: ip " + ip + " is unknow device, " + str(e))
示例#4
0
def parse_arguments():
    argumentDict = {
        "BIND_IP": '',
        "HOST_IP": '',
        "HTTP_PORT": '',
        "HTTPS_PORT": '',
        "FULLMAC": '',
        "MAC": '',
        "DEBUG": False,
        "DOCKER": False,
        "IP_RANGE_START": '',
        "IP_RANGE_END": '',
        "DECONZ": '',
        "scanOnHostIP": False,
        "disableOnlineDiscover": '',
        "noLinkButton": False,
        "noServeHttps": False
    }
    ap = argparse.ArgumentParser()

    # Arguements can also be passed as Environment Variables.
    ap.add_argument("--debug",
                    action='store_true',
                    help="Enables debug output")
    ap.add_argument("--bind-ip", help="The IP address to listen on", type=str)
    ap.add_argument("--config_path",
                    help="Set certificate and config files location",
                    type=str)
    ap.add_argument("--docker",
                    action='store_true',
                    help="Enables setup for use in docker container")
    ap.add_argument("--ip",
                    help="The IP address of the host system (Docker)",
                    type=str)
    ap.add_argument("--http-port",
                    help="The port to listen on for HTTP (Docker)",
                    type=int)
    ap.add_argument("--https-port",
                    help="The port to listen on for HTTPS (Docker)",
                    type=int)
    ap.add_argument("--mac",
                    help="The MAC address of the host system (Docker)",
                    type=str)
    ap.add_argument("--no-serve-https",
                    action='store_true',
                    help="Don't listen on port 443 with SSL")
    ap.add_argument(
        "--ip-range",
        help="Set IP range for light discovery. Format: <START_IP>,<STOP_IP>",
        type=str)
    ap.add_argument(
        "--scan-on-host-ip",
        action='store_true',
        help="Scan the local IP address when discovering new lights")
    ap.add_argument(
        "--deconz",
        help=
        "Provide the IP address of your Deconz host. 127.0.0.1 by default.",
        type=str)
    ap.add_argument(
        "--no-link-button",
        action='store_true',
        help=
        "DANGEROUS! Don't require the link button to be pressed to pair the Hue app, just allow any app to connect"
    )
    ap.add_argument("--disable-online-discover",
                    help="Disable Online and Remote API functions")

    args = ap.parse_args()

    if args.scan_on_host_ip:
        argumentDict["scanOnHostIP"] = True

    if args.no_link_button:
        argumentDict["noLinkButton"] = True

    if args.no_serve_https:
        argumentDict["noServeHttps"] = True

    if args.debug or get_environment_variable('DEBUG', True):
        argumentDict["DEBUG"] = True

    config_path = '/opt/hue-emulator/config'
    if args.config_path:
        config_path = args.config_path
    elif get_environment_variable('CONFIG_PATH'):
        config_path = get_environment_variable('CONFIG_PATH')
    argumentDict["CONFIG_PATH"] = config_path

    bind_ip = '0.0.0.0'
    if args.bind_ip:
        bind_ip = args.bind_ip
    elif get_environment_variable('BIND_IP'):
        bind_ip = get_environment_variable('BIND_IP')
    argumentDict["BIND_IP"] = bind_ip

    if args.ip:
        host_ip = args.ip
    elif get_environment_variable('IP'):
        host_ip = get_environment_variable('IP')
    elif bind_ip != '0.0.0.0':
        host_ip = bind_ip
    else:
        host_ip = getIpAddress()
    argumentDict["HOST_IP"] = host_ip

    if args.http_port:
        host_http_port = args.http_port
    elif get_environment_variable('HTTP_PORT'):
        host_http_port = int(get_environment_variable('HTTP_PORT'))
    else:
        host_http_port = 80
    argumentDict["HTTP_PORT"] = host_http_port

    if args.https_port:
        host_https_port = args.https_port
    elif get_environment_variable('HTTPS_PORT'):
        host_https_port = int(get_environment_variable('HTTPS_PORT'))
    else:
        host_https_port = 443
    argumentDict["HTTPS_PORT"] = host_https_port

    logging.info("Using Host %s:%s" % (host_ip, host_http_port))

    if args.mac:
        dockerMAC = args.mac  # keeps : for cert generation
        mac = str(args.mac).replace(":", "")
    elif get_environment_variable('MAC'):
        dockerMAC = get_environment_variable('MAC').strip('\u200e')
        mac = str(dockerMAC).replace(":", "")
    else:
        dockerMAC = check_output(
            "cat /sys/class/net/$(ip -o addr | grep %s | awk '{print $2}')/address"
            % host_ip,
            shell=True).decode('utf-8')[:-1]
        mac = str(dockerMAC).replace(":", "")

    if args.docker or get_environment_variable('DOCKER', True):
        docker = True
    else:
        docker = False
    argumentDict["FULLMAC"] = dockerMAC
    argumentDict["MAC"] = mac
    argumentDict["DOCKER"] = docker
    logging.info("Host MAC given as " + mac)

    if args.ip_range or get_environment_variable('IP_RANGE'):
        if args.ip_range:
            ranges = args.ip_range
        else:
            ranges = get_environment_variable('IP_RANGE')
        ranges = ranges.split(',')
        if ranges[0] and int(ranges[0]) >= 0:
            ip_range_start = int(ranges[0])
        else:
            ip_range_start = 0

        if ranges[1] and int(ranges[1]) > 0:
            ip_range_end = int(ranges[1])
        else:
            ip_range_end = 255
    elif get_environment_variable(
            'IP_RANGE_START') and get_environment_variable('IP_RANGE_END'):
        ip_range_start = get_environment_variable('IP_RANGE_START')
        ip_range_end = get_environment_variable('IP_RANGE_END')
    else:
        ip_range_start = 0
        ip_range_end = 255
    argumentDict["IP_RANGE_START"] = ip_range_start
    argumentDict["IP_RANGE_END"] = ip_range_end
    logging.info("IP range for light discovery: " + str(ip_range_start) + "-" +
                 str(ip_range_end))

    if args.deconz:
        deconz_ip = args.deconz
    elif get_environment_variable('DECONZ'):
        deconz_ip = get_environment_variable('DECONZ')
    else:
        deconz_ip = "127.0.0.1"
    argumentDict["DECONZ"] = deconz_ip
    logging.info("Deconz IP given as " + deconz_ip)

    if args.disable_online_discover or get_environment_variable(
            'disableonlinediscover'):
        disableOnlineDiscover = True
        logging.info("Online Discovery/Remote API Disabled!")
    else:
        disableOnlineDiscover = False
        logging.info("Online Discovery/Remote API Enabled!")
    argumentDict["disableOnlineDiscover"] = disableOnlineDiscover

    if argumentDict['noServeHttps']:
        logging.info("HTTPS Port Disabled")

    return argumentDict