def learn_command(ip_address, command_name, host_ip): broadcast_address = "255.255.255.255" if host_ip == 'localhost': host_ip = None else: broadcast_address = host_ip[:host_ip.rfind('.') + 1] + '255' print(f'broadcast ip is: {broadcast_address}') parser = argparse.ArgumentParser(fromfile_prefix_chars='@') parser.add_argument( "--timeout", type=int, default=2, help="timeout to wait for receiving discovery responses") parser.add_argument("--ip", default=host_ip, help="ip address to use in the discovery") parser.add_argument("--dst-ip", default=broadcast_address, help="destination ip address to use in the discovery") args = parser.parse_args() print("Discovering...") devices = broadlink.discover(timeout=args.timeout, local_ip_address=args.ip, discover_ip_address=args.dst_ip) for device in devices: if device.auth(): if device.host[0] == ip_address: # found a match print("###########################################") print('Found a match') print("# broadlink_cli --type {} --host {} --mac {}".format( hex(device.devtype), device.host[0], ''.join(format(x, '02x') for x in device.mac))) device.enter_learning() print("Learning...") start = time.time() while time.time() - start < TIMEOUT: time.sleep(1) try: data = device.check_data() except (ReadError, StorageError): continue else: break else: print("No data received...") # TODO handle better return Exception('No data received...') # exit(1) learned = format_durations(to_microseconds(bytearray(data))) learned = ''.join(format(x, '02x') for x in bytearray(data)) # if durations \ # somerthing = ''.join(format(x, '02x') for x in bytearray(data)) print("###########################################") print("Learned!") print(learned) # we need to find the device and add a command that we just learned mac_address = ''.join(format(x, '02x') for x in device.mac) file_name = mac_address + '.json' script_dir = os.path.dirname(__file__) file_path = os.path.join(script_dir, './config/') file_with_path = file_path + file_name if os.path.exists(file_with_path): # we need to merge print('File exists') with open(file_with_path) as existing_file: data = json.load(existing_file) if data and data['mac']: my_device = { "ip": device.host[0], "mac": ':'.join( mac_address[i:i + 2] for i in range(0, len(mac_address), 2)), "model": device.model, "manufacturer": device.manufacturer, "commands": [{ "id": str(uuid.uuid4()), "name": command_name, "data": learned }], "name": data['name'], "temperature": data['temperature'], "humidity": data['humidity'] } # we have a mac address in the file, should be a valid file # merge new data into old merged_device = always_merger.merge( my_device, data) write_json_file(file_with_path, merged_device) return merged_device else: # not a vlid mac, we need to just write data print('Not a valid mac address') else: print("Error authenticating with device : {}".format(device.host))
def discover_blasters(timeout): return list( filter(lambda blaster: blaster.get_type().lower() == "rm2", broadlink.discover(timeout=timeout)))
import broadlink import ipdb from my_credits import ( WIFI_SSID, WIFI_PASSWORD, WIFI_SECIRITY_MODE, ) from commands import ( SAMSUNG_TV_POWER, SAMSUNG_TV_ADD_SOUND, SAMSUNG_TV_REDUCE_SOUND, SUMSUNG_TV_NEXT_CNANNEL, SUMSUNG_TV_PREVIOUS_CNANNEL, ) broadlink.setup(WIFI_SSID, WIFI_PASSWORD, WIFI_SECIRITY_MODE) try: print(f"Broadlink {WIFI_SSID} {WIFI_PASSWORD} {WIFI_SECIRITY_MODE}") device = broadlink.discover(timeout=10)[0] device.auth() except IndexError: print("Broadlink is turned off") ipdb.set_trace()
def output(): devices = broadlink.discover(timeout=10) print(devices) return "ho gaya"
def get_device(cf): device_type = cf.get('device_type', 'lookup') if device_type == 'lookup': local_address = cf.get('local_address', None) lookup_timeout = cf.get('lookup_timeout', 20) devices = broadlink.discover(timeout=lookup_timeout) if local_address is None else \ broadlink.discover(timeout=lookup_timeout, local_ip_address=local_address) if len(devices) == 0: logging.error('No Broadlink device found') sys.exit(2) if len(devices) > 1: logging.error('More than one Broadlink device found (' + ', '.join([ d.type + '/' + d.host[0] + '/' + ':'.join(format(s, '02x') for s in d.mac[::-1]) for d in devices ]) + ')') sys.exit(2) return configure_device(devices[0], topic_prefix) elif device_type == 'multiple_lookup': local_address = cf.get('local_address', None) lookup_timeout = cf.get('lookup_timeout', 20) devices = broadlink.discover(timeout=lookup_timeout) if local_address is None else \ broadlink.discover(timeout=lookup_timeout, local_ip_address=local_address) if len(devices) == 0: logging.error('No Broadlink devices found') sys.exit(2) mqtt_multiple_prefix_format = cf.get('mqtt_multiple_subprefix_format', None) devices_dict = {} for device in devices: mqtt_subprefix = mqtt_multiple_prefix_format.format( type=device.type, host=device.host[0], mac='_'.join(format(s, '02x') for s in device.mac[::-1]), mac_nic='_'.join(format(s, '02x') for s in device.mac[2::-1])) device = configure_device(device, topic_prefix + mqtt_subprefix) devices_dict[mqtt_subprefix] = device return devices_dict elif device_type == 'test': return configure_device(TestDevice(cf), topic_prefix) else: host = (cf.get('device_host'), 80) mac = bytearray.fromhex(cf.get('device_mac').replace(':', ' ')) if device_type == 'rm': device = broadlink.rm(host=host, mac=mac, devtype=0x2712) elif device_type == 'rm4': device = broadlink.rm4(host=host, mac=mac, devtype=0x51da) elif device_type == 'sp1': device = broadlink.sp1(host=host, mac=mac, devtype=0) elif device_type == 'sp2': device = broadlink.sp2(host=host, mac=mac, devtype=0x2711) elif device_type == 'a1': device = broadlink.a1(host=host, mac=mac, devtype=0x2714) elif device_type == 'mp1': device = broadlink.mp1(host=host, mac=mac, devtype=0x4EB5) elif device_type == 'dooya': device = broadlink.dooya(host=host, mac=mac, devtype=0x4E4D) elif device_type == 'bg1': device = broadlink.bg1(host=host, mac=mac, devtype=0x51E3) else: logging.error('Incorrect device configured: ' + device_type) sys.exit(2) return configure_device(device, topic_prefix)
def discover_devices(host_ip): broadcast_address = "255.255.255.255" if host_ip == 'localhost': host_ip = None else: broadcast_address = host_ip[:host_ip.rfind('.') + 1] + '255' print(f'broadcast ip is: {broadcast_address}') device_list = [] parser = argparse.ArgumentParser(fromfile_prefix_chars='@') parser.add_argument( "--timeout", type=int, default=2, help="timeout to wait for receiving discovery responses") parser.add_argument("--ip", default=host_ip, help="ip address to use in the discovery") parser.add_argument("--dst-ip", default=broadcast_address, help="destination ip address to use in the discovery") args = parser.parse_args() print(f'args: {args}') print("Discovering...") devices = broadlink.discover(timeout=args.timeout, local_ip_address=args.ip, discover_ip_address=args.dst_ip) print(f'devices {devices}') for device in devices: print(f'found {devices}') if device.auth(): # devices.append(device) temperature = None humidity = None print("###########################################") print(device.type) print("# broadlink_cli --type {} --host {} --mac {}".format( hex(device.devtype), device.host[0], ''.join(format(x, '02x') for x in device.mac))) print( "Device file data (to be used with --device @filename in broadlink_cli) : " ) try: print("sensors = {}".format(device.check_sensors())) sensors = device.check_sensors() if sensors: temperature = sensors['temperature'] humidity = sensors['humidity'] except (AttributeError, StorageError): pass print("") mac_address = ''.join(format(x, '02x') for x in device.mac) my_device = { "ip": device.host[0], "mac": ':'.join(mac_address[i:i + 2] for i in range(0, len(mac_address), 2)), "model": device.model, "manufacturer": device.manufacturer, "commands": [], "name": '', } file_name = mac_address + '.json' script_dir = os.path.dirname(__file__) file_path = os.path.join(script_dir, './config/') file_with_path = file_path + file_name if os.path.exists(file_with_path): # we need to merge # this is so ugly print('File exists, need to merge') with open(file_with_path) as existing_file: data = json.load(existing_file) if data and data['mac']: # we have a mac address in the file, should be a valid file # merge new data into old my_device = { "ip": device.host[0], "mac": ':'.join(mac_address[i:i + 2] for i in range(0, len(mac_address), 2)), "model": device.model, "manufacturer": device.manufacturer, "commands": data['commands'] or [], "name": data['name'] or '', "temperature": temperature, "humidity": humidity } device_list.append(my_device) merged_device = always_merger.merge(data, my_device) unique_commands = [] for i in range(len(my_device['commands'])): if my_device['commands'][i] not in my_device[ 'commands'][i + 1:]: unique_commands.append( my_device['commands'][i]) merged_device['commands'] = unique_commands write_json_file(file_with_path, merged_device) else: # not a vlid mac, we need to just write data write_json_file(file_with_path, my_device) else: # just write print('File does not exist, creating') write_json_file(file_with_path, my_device) device_list.append(my_device) else: print("Error authenticating with device : {}".format(device.host)) return device_list
def discover_blasters(timeout): return [ blaster for blaster in broadlink.discover(timeout=timeout) if blaster.get_type().lower() in ("rm2", "rm4") ]
def _get_broadlink_devices(self): self.devices = broadlink.discover(timeout=7) print(self.devices) for d in self.devices: d.auth()
decode_hex = codecs.getdecoder("hex_codec") return str(base64.b64encode(decode_hex(learned)[0]))[2:-1] + "==" # Gemnerate list of commands. This way the command learning logic doesnt have to be in nested loops. # It also allows easy acess to the next command before the next loop iteration improving user experience. # It will also make it easier to add preset modes support to the JSON file later. def gen_cmd_list(data, mode_types, header_simple_cmds=["off"], footer_simple_cmds=[]): return header_simple_cmds + [dict(zip(mode_types, cmd)) for cmd in product(*data)] + footer_simple_cmds def gen_cmd_desc(cmd): return " ".join([f"{name}: {value};" for name, value in cmd.items()]) while len(devices := broadlink.discover(timeout=5, discover_ip_address=input("broadlink controller IP adress: "))) < 1: while (cont := input("No device found. Do you wish to try again?(y/n)").lower()) not in {"y", "yes", "n", "no"}: print("Invalid Answer") if cont.lower() in {"n", "no"}: sys.exit() device = devices[0] if device.is_locked: print("Device is locked please unlock it using broadlink app") sys.exit() if not device.auth(): print("Error authenticating with device") sys.exit() host = device.host[0] print(f"Connected to {host}") list_m("\nTool Modes", ["Create new codes file", "Add swing to existing file"])
async def rmmini_discovery(): devices = broadlink.discover(timeout=10)
devicetype = int(config['rmmini3']['type'], 0) host = config['rmmini3']['rm_ip'] mac = bytearray.fromhex(config['rmmini3']['rm_mac']) except KeyError as e: logging.error("RM Mini 3 settings not found in config file") sys.exit(2) dev = broadlink.gendevice(devicetype, (host, 80), mac) try: dev.auth() logging.info("Successfully initialized RM Mini 3") except broadlink.exceptions.DeviceOfflineError as e: logging.error("The RM2 device at %s is offline" % host) no_device = True logging.info("Trying to find RM2 device elsewhere on network") devices = broadlink.discover(5) for d in devices: if d.auth(): if d.type == 'RM2': logging.info( "Found RM2 device host %s, mac %s" % (d.host[0], ':'.join(format(x, '02x') for x in d.mac))) logging.info( "Update config.ini file with above info for faster startup next time" ) dev = d no_device = False if no_device: logging.error("No RM2 device found on network, exiting.") sys.exit(2)
def main(): try: conf = Config() except Exception as e: print("Cannot load configuration from file %s: %s" % (CONFIG, str(e))) sys.exit(2) jobs = [] pipes = [] founddevices = {} def on_message(client, pipes, msg): topic = msg.topic.replace(conf.get('mqtt_topic_prefix', '/broadlink'), '') cmd = topic.split('/') devicemac = cmd[1] command = cmd[3] if cmd[2] == 'cmd': print("Received command %s for device %s" % (command, devicemac)) try: for (ID, pipe) in pipes: if ID == devicemac: print('send to pipe %s' % ID) pipe.send((command, msg.payload)) except: print("Unexpected error:", sys.exc_info()[0]) raise def on_disconnect(client, empty, rc): print("Disconnect, reason: " + str(rc)) print("Disconnect, reason: " + str(client)) client.loop_stop() time.sleep(10) def on_kill(mqttc, jobs): mqttc.loop_stop() for j in jobs: j.join() def on_connect(client, userdata, flags, rc): client.publish(conf.get('mqtt_topic_prefix', '/broadlink'), 'Connect') print("Connect, reason: " + str(rc)) def on_log(mosq, obj, level, string): print(string) mqttc = mqtt.Client(conf.get('mqtt_clientid', 'broadlink') + '-%s' % os.getpid(), clean_session=conf.get('mqtt_clean_session', False), userdata=pipes) mqttc.on_message = on_message mqttc.on_connect = on_connect mqttc.on_disconnect = on_disconnect #mqttc.on_log = on_log mqttc.will_set(conf.get('mqtt_topic_prefix', '/broadlink'), payload="Disconnect", qos=conf.get('mqtt_qos', 0), retain=False) mqttc.reconnect_delay_set(min_delay=3, max_delay=30) if conf.get('tls') == True: mqttc.tls_set(conf.get('ca_certs'), conf.get('certfile'), conf.get('keyfile'), tls_version=conf.get('tls_version'), ciphers=None) if conf.get('tls_insecure'): mqttc.tls_insecure_set(True) mqttc.username_pw_set(conf.get('mqtt_username'), conf.get('mqtt_password')) mqttc.connect(conf.get('mqtt_broker', 'localhost'), int(conf.get('mqtt_port', '1883')), 60) mqttc.subscribe(conf.get('mqtt_topic_prefix', '/broadlink') + '/+/cmd/#', qos=conf.get('mqtt_qos', 0)) atexit.register(on_kill, mqttc, jobs) run = True while run: try: for idx, j in enumerate(jobs): if not j.is_alive(): try: print("Killing job.") j.join() except: print("Error killing job.") pass try: print("Deleting pipe from pipes array") for idy, (ID, pipe) in enumerate(pipes): if ID == founddevices[j.pid]: del pipes[idy] except: print("Error deleting pipe from pipes array") try: print("Deleting device from founddevices array.") del founddevices[j.pid] except: print("Error deleting device from founddevices array.") pass try: print("Deleting job from jobs array.") del jobs[idx] except: print("Error deleting job from jobs array.") pass print("broadlink discover") devices = broadlink.discover(timeout=conf.get('lookup_timeout', 5)) for device in devices: divicemac = ''.join(format(x, '02x') for x in device.mac) if divicemac not in founddevices.values(): transportPipe, MasterPipe = Pipe() pipes.append((divicemac, MasterPipe)) print("found: {} {}".format( device.host[0], ''.join(format(x, '02x') for x in device.mac))) p = ReadDevice(transportPipe, divicemac, device, conf) jobs.append(p) p.start() founddevices[p.pid] = divicemac time.sleep(2) mqttc.user_data_set(pipes) mqttc.loop_stop() print("Reconnect") mqttc.loop_start() time.sleep(conf.get('rediscover_time', 600)) except KeyboardInterrupt: run = False except Exception as e: run = False unhandeledException(e) except SignalException_SIGKILL: run = False mqttc.loop_stop() for j in jobs: j.join() return
args = parser.parse_args() if not os.path.exists(args.config): with open(args.config, 'w'): pass # create file data = {} with open(args.config, 'r') as f: try: data = json.load(f) except: pass # if fails, just continue because file might be empty if not args.display: print('Connecting to device...') device = broadlink.discover(local_ip_address='0.0.0.0') if not device: print('Could not find device') exit(1) device.auth() print('Connected.') done = False learned_frequency = False def learn(): global learned_frequency
#!/usr/bin/python import broadlink import time import argparse parser = argparse.ArgumentParser(fromfile_prefix_chars='@'); parser.add_argument("--timeout", type=int, default=5, help="timeout to wait for receiving discovery responses") args = parser.parse_args() print "discover" devices = broadlink.discover(timeout=args.timeout) #print devices for device in devices: if device.auth(): print "###########################################" # print device print device.type print "# broadlink_cli --type 0x2712 --host {} --mac {}".format(device.host[0], ''.join(format(x, '02x') for x in device.mac)) print "Device file data (to be used with --device @filename in broadlink_cli) : " print "0x2712 {} {}".format(device.host[0], ''.join(format(x, '02x') for x in device.mac)) print "temperature = {}".format(device.check_temperature()) print "" else: print "Error authenticating with device : {}".format(device.host)
def send_command(ip_address, command_id, host_ip): broadcast_address = "255.255.255.255" if host_ip == 'localhost': host_ip = None else: broadcast_address = host_ip[:host_ip.rfind('.') + 1] + '255' print(f'broadcast ip is: {broadcast_address}') parser = argparse.ArgumentParser(fromfile_prefix_chars='@') parser.add_argument( "--timeout", type=int, default=2, help="timeout to wait for receiving discovery responses") parser.add_argument("--ip", default=host_ip, help="ip address to use in the discovery") parser.add_argument("--dst-ip", default=broadcast_address, help="destination ip address to use in the discovery") args = parser.parse_args() print("Discovering...") devices = broadlink.discover(timeout=args.timeout, local_ip_address=args.ip, discover_ip_address=args.dst_ip) for device in devices: if device.auth(): if device.host[0] == ip_address: # found a match print("###########################################") print('Found a match') print("# broadlink_cli --type {} --host {} --mac {}".format( hex(device.devtype), device.host[0], ''.join(format(x, '02x') for x in device.mac))) # we need to find the device and add a command that we just learned mac_address = ''.join(format(x, '02x') for x in device.mac) file_name = mac_address + '.json' script_dir = os.path.dirname(__file__) file_path = os.path.join(script_dir, './config/') file_with_path = file_path + file_name if os.path.exists(file_with_path): # we need to merge print('File exists') with open(file_with_path) as existing_file: data = json.load(existing_file) existing_command = list( filter(lambda x: x['id'] == command_id, data['commands'])) if data and data[ 'mac'] and existing_command and existing_command[ 0] and existing_command[0]['id']: device.send_data( bytearray.fromhex(''.join( existing_command[0]['data']))) print( "###########################################") print("command sent!") command_status = { "success": True, "command": existing_command } return command_status else: # not a vlid mac, we need to just write data print('No command with that id exists') command_status = { "success": False, "commands": existing_command } return command_status else: print("Error authenticating with device : {}".format(device.host))
def process_broadlinks(self): res = False self.broadlinkObjects = {} self.adbase.log("Setting up Broadlink Devices") try: devices = broadlink.discover(5, self.args.get("local_ip")) except: self.adbase.log("Logged an error in errorlog", level="WARNING") self.adbase.error(traceback.format_exc()) num = len(devices) if num > 0: # if it found more than 1 device on the network self.adbase.log(f"Found {num} Broadlink Devices on the Network") else: self.adbase.log( f"Coundn't find any Broadlink Device on the Network", level="WARNING") try: b_namespace = self.broadlinks.get( "namespace", "default") #get broadlink namespace for device in devices: device.auth() #first get device authentication device_mac = re.findall('..?', device.mac.hex()) #device_mac.reverse() device_mac = ":".join(device_mac) for bl, bl_settings in self.broadlinks.items(): b_mac = bl_settings.get("mac").lower() if b_mac == None: raise ValueError( "No Device MAC Address given, please provide MAC Address" ) if b_mac != device_mac: continue b_friendly_name = bl_settings.get( "friendly_name", bl.replace("_", " ")) #get device friendly name self.adbase.set_namespace(b_namespace) b_device_name = b_friendly_name.lower().replace(" ", "_") b_device_domain = bl_settings.get("entity_domain", "sensor") (b_ip, b_port) = device.host b_type = device.devtype entity_id = f"{b_device_domain}.{b_device_name}" self.broadlinkObjects[ entity_id] = device #store broadlink object self.broadlinkErrors[entity_id] = 0 self.entities[entity_id] = {} self.entities[entity_id]["attributes"] = { "friendly_name": b_friendly_name, "mac": b_mac, "ip_address": b_ip, "port": b_port, "device_type": b_type } self.entities[entity_id]["use_temp_as_attribute"] = False if bl_settings.get("use_temp_as_attribute", False) is True: self.entities[entity_id]["attributes"][ "temperature"] = "unavailable" self.entities[entity_id]["use_temp_attribute"] = True attr_delay = bl_settings["use_temp_as_attribute"].get( "update_frequency", 60) runtime = datetime.datetime.now() + datetime.timedelta( seconds=2) self.adbase.run_every(self.update_temperature, runtime, attr_delay, device_entity_id=entity_id, entity_id=entity_id) self.adbase.set_state( entity_id, state="on", attributes=self.entities[entity_id]["attributes"]) if "use_sensor_for_temperature" in bl_settings: sensor_delay = bl_settings[ "use_sensor_for_temperature"].get( "update_frequency", 60) friendly_name = bl_settings[ "use_sensor_for_temperature"].get( "friendly_name", b_friendly_name) unit_of_measurement = bl_settings[ "use_sensor_for_temperature"].get( "unit_of_measurement", "C") runtime = datetime.datetime.now() + datetime.timedelta( seconds=2) sensor_entity_id = bl_settings[ "use_sensor_for_temperature"].get( "name", f"sensor.{b_friendly_name}_temperature") self.entities[entity_id][ "temp_sensor"] = sensor_entity_id self.entities[entity_id]["temp_sensor_attributes"] = {} self.entities[entity_id]["temp_sensor_attributes"][ "friendly_name"] = friendly_name self.entities[entity_id]["temp_sensor_attributes"][ "unit_of_measurement"] = unit_of_measurement self.adbase.run_every(self.update_temperature, runtime, sensor_delay, device_entity_id=entity_id, entity_id=sensor_entity_id) except: self.adbase.log("Logged an error in errorlog", level="WARNING") self.adbase.error(traceback.format_exc()) if self.entities != {}: self.adbase.fire_event("Broadlink_Setup", entities=self.entities) self.adbase.log("Completed Broadlink Device setup") res = True return res
def delete_command(ip_address, command_id, host_ip): broadcast_address = "255.255.255.255" if host_ip == 'localhost': host_ip = None else: broadcast_address = host_ip[:host_ip.rfind('.') + 1] + '255' print(f'broadcast ip is: {broadcast_address}') parser = argparse.ArgumentParser(fromfile_prefix_chars='@') parser.add_argument( "--timeout", type=int, default=2, help="timeout to wait for receiving discovery responses") parser.add_argument("--ip", default=host_ip, help="ip address to use in the discovery") parser.add_argument("--dst-ip", default=broadcast_address, help="destination ip address to use in the discovery") args = parser.parse_args() print("Discovering...") devices = broadlink.discover(timeout=args.timeout, local_ip_address=args.ip, discover_ip_address=args.dst_ip) for device in devices: if device.auth(): if device.host[0] == ip_address: # found a match print("###########################################") print('Found a match') print("# broadlink_cli --type {} --host {} --mac {}".format( hex(device.devtype), device.host[0], ''.join(format(x, '02x') for x in device.mac))) mac_address = ''.join(format(x, '02x') for x in device.mac) file_name = mac_address + '.json' script_dir = os.path.dirname(__file__) file_path = os.path.join(script_dir, './config/') file_with_path = file_path + file_name if os.path.exists(file_with_path): # we can update it print('File exists, need update commands') with open(file_with_path) as existing_file: data = json.load(existing_file) if data and data['mac'] and data['commands'] and data[ 'commands'][0]: # we have some commands remaining_commands = list( filter(lambda x: x['id'] != command_id, data['commands'])) updated_device = { "ip": data['ip'], "mac": data['mac'], "model": data['model'], "manufacturer": data['manufacturer'], "commands": remaining_commands, "name": data['name'], "temperature": data['temperature'], "humidity": data['humidity'] } write_json_file(file_with_path, updated_device) return updated_device else: print("Error authenticating with device : {}".format(device.host))
import broadlink as blk d = blk.hello("192.168.0.98") # Device IP address. print(d) d.hello() devices = blk.discover(timeout=10, local_ip_address="192.168.0.150") for device in devices: print(f'device.enter_learning: {device.enter_learning}') if device.auth(): device.enter_learning()
def execute_command(SentCommand, DeviceName='', ReKeyCommand=False, AlternativeIPAddress='', AlternativePort='', AlternativeMACAddress='', AlternativeTimeout=''): if SentCommand == '': print('Command name parameter is mandatory') return 2 if SentCommand == 'DISCOVER': print('Scanning network for Broadlink devices ... ') mydevices = broadlink.discover(timeout=5) print(('Found ' + str(len(mydevices)) + ' broadlink device(s)')) time.sleep(1) for index, item in enumerate(mydevices): mydevices[index].auth() m = re.match(r"\('([0-9.]+)', ([0-9]+)", str(mydevices[index].host)) ipadd = m.group(1) port = m.group(2) macadd = str(''.join( format(x, '02x') for x in mydevices[index].mac[::-1])) macadd = macadd[:2] + ":" + macadd[2:4] + ":" + macadd[ 4:6] + ":" + macadd[6:8] + ":" + macadd[8:10] + ":" + macadd[10:12] print(('Device ' + str(index + 1) + ':\nIPAddress = ' + ipadd + '\nPort = ' + port + '\nMACAddress = ' + macadd)) return if (DeviceName != '') and ((AlternativeIPAddress != '') or (AlternativePort != '') or (AlternativeMACAddress != '') or (AlternativeTimeout != '')): print( 'Device name parameter can not be used in conjunction with IP Address/Port/MAC Address/Timeout parameters' ) return 2 if (((AlternativeIPAddress != '') or (AlternativePort != '') or (AlternativeMACAddress != '') or (AlternativeTimeout != '')) and ((AlternativeIPAddress == '') or (AlternativePort == '') or (AlternativeMACAddress == '') or (AlternativeTimeout == ''))): print( 'IP Address, Port, MAC Address and Timeout parameters can not be used separately' ) return 2 if DeviceName != '': if SettingsFile.has_section(DeviceName): if SettingsFile.has_option(DeviceName, 'IPAddress'): DeviceIPAddress = SettingsFile.get(DeviceName, 'IPAddress') else: DeviceIPAddress = '' if SettingsFile.has_option(DeviceName, 'Port'): DevicePort = SettingsFile.get(DeviceName, 'Port') else: DevicePort = '' if SettingsFile.has_option(DeviceName, 'MACAddress'): DeviceMACAddress = SettingsFile.get(DeviceName, 'MACAddress') else: DeviceMACAddress = '' if SettingsFile.has_option(DeviceName, 'Timeout'): DeviceTimeout = SettingsFile.get(DeviceName, 'Timeout') else: DeviceTimeout = '' else: print('Device does not exist in BlackBeanControl.ini') return 2 if (DeviceName != '') and (DeviceIPAddress == ''): print( 'IP address must exist in BlackBeanControl.ini for the selected device' ) return 2 if (DeviceName != '') and (DevicePort == ''): print( 'Port must exist in BlackBeanControl.ini for the selected device') return 2 if (DeviceName != '') and (DeviceMACAddress == ''): print( 'MAC address must exist in BlackBeanControl.ini for the selected device' ) return 2 if (DeviceName != '') and (DeviceTimeout == ''): print( 'Timeout must exist in BlackBeanControl.ini for the selected device' ) return 2 if DeviceName != '': RealIPAddress = DeviceIPAddress elif AlternativeIPAddress != '': RealIPAddress = AlternativeIPAddress else: RealIPAddress = Settings.IPAddress if RealIPAddress == '': print( 'IP address must exist in BlackBeanControl.ini or it should be entered as a command line parameter' ) return 2 if DeviceName != '': RealPort = DevicePort elif AlternativePort != '': RealPort = AlternativePort else: RealPort = Settings.Port if RealPort == '': print( 'Port must exist in BlackBeanControl.ini or it should be entered as a command line parameter' ) return 2 else: RealPort = int(RealPort) if DeviceName != '': RealMACAddress = DeviceMACAddress elif AlternativeMACAddress != '': RealMACAddress = AlternativeMACAddress else: RealMACAddress = Settings.MACAddress if RealMACAddress == '': print( 'MAC address must exist in BlackBeanControl.ini or it should be entered as a command line parameter' ) return 2 else: RealMACAddress = netaddr.EUI(RealMACAddress) if DeviceName != '': RealTimeout = DeviceTimeout elif AlternativeTimeout != '': RealTimeout = AlternativeTimeout else: RealTimeout = Settings.Timeout if RealTimeout == '': print( 'Timeout must exist in BlackBeanControl.ini or it should be entered as a command line parameter' ) return 2 else: RealTimeout = int(RealTimeout) RM3Device = broadlink.rm((RealIPAddress, RealPort), RealMACAddress) RM3Device.auth() if ReKeyCommand: if SettingsFile.has_option('Commands', SentCommand): CommandFromSettings = SettingsFile.get('Commands', SentCommand) if CommandFromSettings[0:4] != '2600': RM3Key = RM3Device.key RM3IV = RM3Device.iv DecodedCommand = binascii.unhexlify(CommandFromSettings) AESEncryption = AES.new(str(RM3Key), AES.MODE_CBC, str(RM3IV)) EncodedCommand = AESEncryption.encrypt(str(DecodedCommand)) FinalCommand = EncodedCommand[0x04:] EncodedCommand = binascii.hexlify(FinalCommand).decode("ascii") BlackBeanControlIniFile = open( path.join(Settings.ApplicationDir, 'BlackBeanControl.ini'), 'w') SettingsFile.set('Commands', SentCommand, EncodedCommand) SettingsFile.write(BlackBeanControlIniFile) BlackBeanControlIniFile.close() sys.exit() else: print("Command appears to already be re-keyed.") return 2 else: print("Command not found in ini file for re-keying.") return 2 if SettingsFile.has_option('Commands', SentCommand): CommandFromSettings = SettingsFile.get('Commands', SentCommand) else: CommandFromSettings = '' if CommandFromSettings != '': DecodedCommand = binascii.unhexlify(CommandFromSettings) RM3Device.send_data(DecodedCommand) else: RM3Device.enter_learning() time.sleep(RealTimeout) LearnedCommand = RM3Device.check_data() if LearnedCommand is None: print('Command not received') sys.exit() print(LearnedCommand) # EncodedCommand = LearnedCommand.encode('hex') EncodedCommand = binascii.hexlify(LearnedCommand).decode("ascii") print(EncodedCommand) if EncodedCommand: BlackBeanControlIniFile = open( path.join(Settings.ApplicationDir, 'BlackBeanControl.ini'), 'w') SettingsFile.set('Commands', SentCommand, EncodedCommand) SettingsFile.write(BlackBeanControlIniFile) BlackBeanControlIniFile.close() print('Set command {0}'.format(SentCommand))
parser = argparse.ArgumentParser(fromfile_prefix_chars='@') parser.add_argument("--timeout", type=int, default=5, help="timeout to wait for receiving discovery responses") parser.add_argument("--ip", default=None, help="ip address to use in the discovery") parser.add_argument("--dst-ip", default="255.255.255.255", help="destination ip address to use in the discovery") args = parser.parse_args() print("Discovering...") devices = broadlink.discover(timeout=args.timeout, local_ip_address=args.ip, discover_ip_address=args.dst_ip) for device in devices: if device.auth(): print("###########################################") print(device.type) print("# broadlink_cli --type {} --host {} --mac {}".format( hex(device.devtype), device.host[0], ''.join(format(x, '02x') for x in device.mac))) print( "Device file data (to be used with --device @filename in broadlink_cli) : " ) print("{} {} {}".format(hex(device.devtype), device.host[0], ''.join(format(x, '02x') for x in device.mac))) try: print("temperature = {}".format(device.check_temperature()))
if __name__ == '__main__': if len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] in ("-h", "--help")): print(f'\nUsage: {sys.argv[0]} <device_ip_address> <timeout>') print(f' <device_ip_address> is required') print(f' <timeout> is optional argument (5 seconds by default)') print(f'Usage example: {sys.argv[0]} 192.168.0.42') sys.exit() host = sys.argv[1] timeout = sys.argv[2] if len(sys.argv) > 2 else 5 print('Scanning network for available devices...') devices = broadlink.discover(timeout=int(timeout)) if not devices: print('No devices found in network, aborting') print('* hint: try to ping your device before start this script') sys.exit() else: print(f'Found {len(devices)} device(s)') device = None for dev in devices: if dev.host[0] == host: print(f'Connecting to: {host}...') device = dev device.auth() print('connected.')
for idx, j in enumerate(jobs): if not j.is_alive(): try: j.join() except: pass try: del founddevices[j.pid] except: pass try: del jobs[idx] except: pass print "broadlink discover" devices = broadlink.discover(timeout=conf.get('lookup_timeout', 5)) for device in devices: divicemac = ''.join(format(x, '02x') for x in device.mac) if divicemac not in founddevices.values(): transportPipe, MasterPipe = Pipe() pipes.append((divicemac, MasterPipe)) print "found: {} {}".format(device.host[0], ''.join(format(x, '02x') for x in device.mac)) p = ReadDevice(transportPipe, divicemac, device, conf) jobs.append(p) p.start() founddevices[p.pid] = divicemac time.sleep(2) mqttc.user_data_set(pipes) mqttc.loop_stop() print "Reconnect"
logging.debug("Done") else: logging.warn("No command received") def replay(device, file): logging.debug("Replaying command from file " + file) with open(file, 'rb') as f: ir_packet = f.read() device.send_data(ir_packet.decode('hex')) if __name__ == '__main__': local_address = cf.get('local_address', None) lookup_timeout = cf.get('lookup_timeout', 20) devices = broadlink.discover(timeout=lookup_timeout) if local_address is None else \ broadlink.discover(timeout=lookup_timeout, local_ip_address=local_address) if len(devices) == 0: logging.error('No Broadlink device found') sys.exit(2) if len(devices) > 1: logging.error('More than one Broadlink device found (' + ', '.join([d.host for d in devices]) + ')') sys.exit(2) device = devices[0] device.auth() logging.debug('Connected to %s Broadlink device at %s' % (device.type, device.host)) clientid = cf.get('mqtt_clientid', 'broadlink-%s' % os.getpid())
#!/usr/bin/python #Script to locate Broadlink devices on local network by Graeme Brown Dec 23 2016 #These must be set up using the Broadlink app first! import broadlink import time print "************************************************" print "Using python library created by Matthew Garrett" print "https://github.com/mjg59/python-broadlink" print "************************************************" print "Scanning network for Broadlink devices...." mydevices = broadlink.discover(timeout=5) print "Found " + str(len(mydevices )) + " broadlink devices" time.sleep(1) print "..............." for index, item in enumerate(mydevices): mydevices[index].auth() ipadd = mydevices[index].host ipadd = str(ipadd) print "Device " + str(index + 1) +" Host address = " + ipadd[1:19] macadd = ''.join(format(x, '02x') for x in mydevices[index].mac[::-1]) macadd = str(macadd) mymacadd = macadd[:2] + " " + macadd[2:4] + " " + macadd[4:6] + " " + macadd[6:8] + " " + macadd[8:10] + " " + macadd[10:12] print "Device " + str(index + 1) +" MAC address = " + mymacadd
import time from datetime import datetime import binascii import argparse import math import json """ print("************************************************") print("Using python library created by Matthew Garrett") print("https://github.com/mjg59/python-broadlink") print("************************************************") print("Scanning network for Broadlink devices....") """ mydevices = broadlink.discover(timeout=5) #print("Found " + str(len(mydevices )) + " broadlink devices") time.sleep(1) #print("...............") #dataJson = "{ \"search\" : [" dataJson = "[" for index, item in enumerate(mydevices): mydevices[index].auth() ipadd = mydevices[index].host ipadd = str(ipadd) s = str(mydevices[index].host) start = s.find('(\'') + 2
def setting(self, SSID, password, security=3): broadlink.setup(SSID, password, security) return broadlink.discover( timeout=5) #if not found return empty list []
def readSettingsFile(): global devices global DeviceByName global RestrictAccess global LearnFrom global OverwriteProtected global GlobalPassword global GlobalTimeout global settingsFile # A few defaults serverPort = 8080 Autodetect = False OverwriteProtected = True listen_address = '0.0.0.0' broadcast_address = '255.255.255.255' settingsFile = configparser.ConfigParser() settingsFile.optionxform = str settingsFile.read(settings.settingsINI) Dev = settings.Dev GlobalTimeout = settings.GlobalTimeout DiscoverTimeout = settings.DiscoverTimeout # Override them if settingsFile.has_option('General', 'password'): GlobalPassword = settingsFile.get('General', 'password').strip() if settingsFile.has_option('General', 'serverPort'): serverPort = int(settingsFile.get('General', 'serverPort')) if settingsFile.has_option('General', 'serverAddress'): listen_address = settingsFile.get('General', 'serverAddress') if listen_address.strip() == '': listen_address = '0.0.0.0' if settingsFile.has_option('General', 'restrictAccess'): RestrictAccess = settingsFile.get('General', 'restrictAccess').strip() if settingsFile.has_option('General', 'learnFrom'): LearnFrom = settingsFile.get('General', 'learnFrom').strip() if settingsFile.has_option('General', 'allowOverwrite'): OverwriteProtected = False if settingsFile.has_option('General', 'broadcastAddress'): broadcast = settingsFile.get('General', 'broadcastAddress') if broadcast_address.strip() == '': broadcast_address = '255.255.255.255' if settingsFile.has_option('General', 'Autodetect'): try: DiscoverTimeout = int( settingsFile.get('General', 'Autodetect').strip()) except: DiscoverTimeout = 5 Autodetect = True settingsFile.remove_option('General', 'Autodetect') # Device list DeviceByName = {} if not settings.DevList: Autodetect = True if Autodetect == True: print("Beginning device auto-detection ... ") # Try to support multi-homed broadcast better try: devices = broadlink.discover(DiscoverTimeout, listen_address, broadcast_address) except: devices = broadlink.discover(DiscoverTimeout, listen_address) backupSettings() try: broadlinkControlIniFile = open( path.join(settings.applicationDir, 'settings.ini'), 'w') for device in devices: try: device.hostname = socket.gethostbyaddr(device.host[0])[0] if "." in device.hostname: device.hostname = device.hostname.split('.')[0] except: device.hostname = "Broadlink" + device.type.upper() if device.hostname in DeviceByName: device.hostname = "%s-%s" % ( device.hostname, str(device.host).split('.')[3]) DeviceByName[device.hostname] = device if not settingsFile.has_section(device.hostname): settingsFile.add_section(device.hostname) settingsFile.set(device.hostname, 'IPAddress', str(device.host[0])) hexmac = ':'.join(["%02x" % (x) for x in reversed(device.mac)]) settingsFile.set(device.hostname, 'MACAddress', hexmac) settingsFile.set(device.hostname, 'Device', hex(device.devtype)) settingsFile.set(device.hostname, 'Timeout', str(device.timeout)) settingsFile.set(device.hostname, 'Type', device.type.upper()) device.auth() print("%s: Found %s on %s (%s) type: %s" % (device.hostname, device.type, device.host, hexmac, hex(device.devtype))) settingsFile.write(broadlinkControlIniFile) broadlinkControlIniFile.close() except StandardError as e: print("Error writing settings file: %s" % e) restoreSettings() else: devices = [] if settings.DevList: for devname in settings.DevList: if Dev[devname, 'Type'] == 'RM' or Dev[devname, 'Type'] == 'RM2': device = broadlink.rm((Dev[devname, 'IPAddress'], 80), Dev[devname, 'MACAddress'], Dev[devname, 'Device']) if Dev[devname, 'Type'] == 'MP1': device = broadlink.mp1((Dev[devname, 'IPAddress'], 80), Dev[devname, 'MACAddress'], Dev[devname, 'Device']) if Dev[devname, 'Type'] == 'SP1': device = broadlink.sp1((Dev[devname, 'IPAddress'], 80), Dev[devname, 'MACAddress'], Dev[devname, 'Device']) if Dev[devname, 'Type'] == 'SP2': device = broadlink.sp2((Dev[devname, 'IPAddress'], 80), Dev[devname, 'MACAddress'], Dev[devname, 'Device']) if Dev[devname, 'Type'] == 'A1': device = broadlink.a1((Dev[devname, 'IPAddress'], 80), Dev[devname, 'MACAddress'], Dev[devname, 'Device']) if Dev[devname, 'Type'] == 'HYSEN': device = broadlink.hysen((Dev[devname, 'IPAddress'], 80), Dev[devname, 'MACAddress'], Dev[devname, 'Device']) if Dev[devname, 'Type'] == 'S1C': device = broadlink.S1C((Dev[devname, 'IPAddress'], 80), Dev[devname, 'MACAddress'], Dev[devname, 'Device']) if Dev[devname, 'Type'] == 'DOOYA': device = broadlink.dooya((Dev[devname, 'IPAddress'], 80), Dev[devname, 'MACAddress'], Dev[devname, 'Device']) device.timeout = Dev[devname, 'Timeout'] if not devname in DeviceByName: device.hostname = devname device.auth() devices.append(device) print("%s: Read %s on %s (%s)" % (devname, device.type, str(device.host[0]), device.mac)) DeviceByName[devname] = device return { "port": serverPort, "listen": listen_address, "timeout": GlobalTimeout }
'lastButtonDown'] if (timeSinceLastButtonDown < DOUBLE_CLICK_THRESHOLD) and ( timeSinceLastButtonDown > DOUBLE_CLICK_MINIMUM): print 'double click time %s' % timeSinceLastButtonDown userdata['lastButtonDown'] = None roonPlayPause() else: print 'double click rejected with delta %s' % timeSinceLastButtonDown userdata['lastButtonDown'] = thisButtonDown else: userdata['lastButtonDown'] = thisButtonDown if __name__ == "__main__": try: broadlinkDevice = broadlink.discover(timeout=5)[0] broadlinkDevice.auth() logging.info('Connected to Broadlink device.') except: logging.info('No broadlink devices found') broadlinkDevice = None global mqttClient global tvIsOn tvIsOn = False userData = { "lastButtonDown": None, "lastVolumeUp": None, "lastVolumeDown": None } mqttClient = mqtt.Client(userdata=userData) mqttClient.on_connect = on_connect