def __init__(self, serial_port=None, system_code=None, config_file=None, *args, **kwargs): super().__init__(*args, **kwargs) self.stick = DuofernStickThreaded(serial_port=args.device, system_code=args.code, config_file_json=args.configfile) self.stick._initialize() self.stick.start() self.prompt = "duofern> "
def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Awesome Light platform.""" # Assign configuration variables. The configuration check takes care they are # present. serial_port = config.get('serial_port') code = config.get('code') configfile = config.get('config_file') if 'duofern' not in hass.data: hass.data['duofern'] = { 'stick': DuofernStickThreaded(serial_port=serial_port, system_code=code, config_file_json=configfile) } hass.data['duofern']['stick'].start() # Setup connection with devices/cloud stick = hass.data["duofern"]['stick'] # Add devices add_devices( DuofernShutter(device['id'], device['name'], stick) for device in stick.config['devices'] if not device['id'].startswith('46'))
def main(): usage=""" Userspace hello example """ + fuse.Fuse.fusage stick = DuofernStickThreaded(serial_port="/dev/duofernstick", config_file_json="./pyduofern-config.json") stick._initialize() stick.start() server = DuofernFs( ShutterStickWrapper(stick), version="%prog " + fuse.__version__, usage=usage, dash_s_do='setsingle' ) server.parse(errex=1) server.main()
def setup(hass, config): """Setup the Awesome Light platform.""" # Assign configuration variables. The configuration check takes care they are # present. from pyduofern.duofern_stick import DuofernStickThreaded newstyle_config = hass.config_entries.async_entries(DOMAIN) if len(newstyle_config) > 0: newstyle_config = newstyle_config[0] if newstyle_config: serial_port = newstyle_config.data['serial_port'] code = newstyle_config.data['code'] configfile = newstyle_config.data['config_file'] elif config.get(DOMAIN) is not None: serial_port = config[DOMAIN].get(CONF_SERIAL_PORT) if serial_port is None: serial_port = "/dev/serial/by-id/usb-Rademacher_DuoFern_USB-Stick_WR04ZFP4-if00-port0" code = config[DOMAIN].get(CONF_CODE, None) if code is None: code = "affe" configfile = config[DOMAIN].get('config_file') hass.data[DOMAIN] = { 'stick': DuofernStickThreaded(serial_port=serial_port, system_code=code, config_file_json=configfile, ephemeral=False), 'devices': {} } hass.data[DOMAIN]['stick'].start() # Setup connection with devices/cloud stick = hass.data["duofern"]['stick'] def start_pairing(call): _LOGGER.warning("start pairing") hass.data[DOMAIN]['stick'].pair(call.data.get('timeout', 60)) def start_unpairing(call): _LOGGER.warning("start pairing") hass.data[DOMAIN]['stick'].unpair(call.data.get('timeout', 60)) hass.services.register(DOMAIN, 'start_pairing', start_pairing, PAIRING_SCHEMA) hass.services.register(DOMAIN, 'start_unpairing', start_unpairing, PAIRING_SCHEMA) def sync_devices(call): stick.sync_devices() _LOGGER.warning(call) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) def clean_config(call): stick.clean_config() stick.sync_devices() hass.services.register(DOMAIN, 'sync_devices', sync_devices) hass.services.register(DOMAIN, 'clean_config', clean_config) def refresh(call): _LOGGER.warning(call) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) return True
class DuofernCLI(Cmd): def __init__(self, serial_port=None, system_code=None, config_file=None, *args, **kwargs): super().__init__(*args, **kwargs) self.stick = DuofernStickThreaded(serial_port=args.device, system_code=args.code, config_file_json=args.configfile) self.stick._initialize() self.stick.start() self.prompt = "duofern> " def emptyline(self): pass def do_pair(self, args): """ Usage: pair <TIMEOUT> Start pairing mode. Pass a timeout in seconds as <TIMEOUT>. Will return after the timeout if no devices start pairing within the given timeout. Example: duofern> pair 10 """ timeout = 10 if len(args) != 0: try: timeout = int(args[0]) except: print( "Please use an integer number to indicate TIMEOUT in seconds" ) print("Starting pairing mode... waiting {} seconds".format( int(timeout))) self.stick.pair(timeout=timeout) time.sleep(args.pairtime + 0.5) self.stick.sync_devices() print("Pairing done, Config file updated.") def do_unpair(self, args): """ Usage: unpair <TIMEOUT> Start pairing mode. Pass a timeout in seconds as <TIMEOUT>. Will return after the timeout if no devices start pairing within the given timeout. Example: duofern> unpair 10 """ timeout = 10 if len(args) != 0: try: timeout = int(args[0]) except: print( "Please use an integer number to indicate TIMEOUT in seconds" ) print("Starting pairing mode... waiting {} seconds".format( int(timeout))) self.stick.unpair(timeout=timeout) time.sleep(args.pairtime + 0.5) self.stick.sync_devices() print("Pairing done, Config file updated.") def do_remote(self, args): code = args[0][0:6] timeout = int(args[1]) self.stick.remote(code, timeout) time.sleep(args.pairtime + 0.5) self.stick.sync_devices() print("Pairing done, Config file updated.") @splitargs @ids_for_names def do_up(self, blinds): """ Usage: up <SHUTTER> [<SHUTTER> <SHUTTER>] Lift one or several shutters. Accepts a list of shutter names sepatated by space. Example: duofern> up Livingroom duofern> up Livingroom Kitchen """ for blind_id in blinds: print("lifting {}".format(blinds[blind_id])) self.stick.command(blind_id, "up") @splitargs @ids_for_names def do_down(self, blinds): """ Usage: up <SHUTTER> [<SHUTTER> <SHUTTER>...] Lower one or several shutters. Accepts a list of shutter names sepatated by space. Example: duofern> up Livingroom duofern> up Livingroom Kitchen """ for blind_id in blinds: print("lowering {}".format(blinds[blind_id])) self.stick.command(blind_id, "down") @splitargs def do_rename(self, args): """ Usage: rename <NAME> <NEW_NAME> Rename an actor. Write changes to config file when done. Example: duofern> rename 13f897 kitchen_west """ id = [ device['id'] for device in self.stick.config['devices'] if device['name'] == args[0] ] if len(id) == 0: print("Please enter a valid device name for renaming.") self.stick.set_name(id[0], args[1]) print("Set name for {} to {}".format(id[0], args[0])) def refresh(self, args): """ Usage: refresh Refresh config file with current changes. example: duofern> refresh """ self.stick.sync_devices() @splitargs @ids_for_names def do_on(self, blinds): """ Usage: off <SWITCH1> [<SWITCH2> <SWITCH3>] Switch on one or several switch actors. Accepts a list of actor names. Example: duofern> off Livingroom duofern> off Livingroom Kitchen """ for blind_id in blinds: print("lifting {}".format(blinds[blind_id])) self.stick.command(blind_id, "up") @splitargs @ids_for_names def do_off(self, blinds): """ Usage: off <SWITCH1> [<SWITCH2> <SWITCH3>] Switch off one or several switch actors. Accepts a list of actor names. Example: duofern> off Livingroom duofern> off Livingroom Kitchen """ for blind_id in blinds: print("lifting {}".format(blinds[blind_id])) self.stick.command(blind_id, "up")
logging.basicConfig(format=' %(asctime)s: %(message)s', level=logging.DEBUG) else: logging.basicConfig(format=' %(asctime)s: %(message)s', level=logging.INFO) if args.code is not None: assert len(args.code) == 4, "System code must be a 4 digit hex code" try: bytearray.fromhex(args.code) except: print("System code must be a 4 digit hex code") exit(1) stick = DuofernStickThreaded(serial_port=args.device, system_code=args.code, config_file_json=args.configfile) if args.set_name is not None: assert len(args.set_name[0]) == 6 and re.match("^[0-9a-f]+$", args.set_name[0], re.IGNORECASE), \ "id for renaming must be a valid 6 digit hex ID not {}".format(args.set_name[0]) stick.set_name(args.set_name[0], args.set_name[1]) stick.sync_devices() print("\nThe following devices are configured:\n") print("\n".join([ "id: {:6} name: {}".format(device['id'], device['name']) for device in stick.config['devices'] ])) print("\n")
def setup(hass, config): """Setup the Awesome Light platform.""" # Assign configuration variables. The configuration check takes care they are # present. from pyduofern.duofern_stick import DuofernStickThreaded newstyle_config = hass.config_entries.async_entries(DOMAIN) if len(newstyle_config) > 0: newstyle_config = newstyle_config[0] if newstyle_config: serial_port = newstyle_config.data['serial_port'] code = newstyle_config.data['code'] configfile = newstyle_config.data['config_file'] elif config.get(DOMAIN) is not None: serial_port = config[DOMAIN].get(CONF_SERIAL_PORT) if serial_port is None: serial_port = "/dev/serial/by-id/usb-Rademacher_DuoFern_USB-Stick_WR04ZFP4-if00-port0" code = config[DOMAIN].get(CONF_CODE, None) if code is None: code = "affe" configfile = config[DOMAIN].get('config_file') hass.data[DOMAIN] = { 'stick': DuofernStickThreaded(serial_port=serial_port, system_code=code, config_file_json=configfile, ephemeral=False), 'devices': {} } # Setup connection with devices/cloud stick = hass.data[DOMAIN]['stick'] def start_pairing(call): _LOGGER.warning("start pairing") hass.data[DOMAIN]['stick'].pair(call.data.get('timeout', 60)) def start_unpairing(call): _LOGGER.warning("start pairing") hass.data[DOMAIN]['stick'].unpair(call.data.get('timeout', 60)) hass.services.register(DOMAIN, 'start_pairing', start_pairing, PAIRING_SCHEMA) hass.services.register(DOMAIN, 'start_unpairing', start_unpairing, PAIRING_SCHEMA) def sync_devices(call): stick.sync_devices() _LOGGER.warning(call) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) def clean_config(call): stick.clean_config() stick.sync_devices() hass.services.register(DOMAIN, 'sync_devices', sync_devices) hass.services.register(DOMAIN, 'clean_config', clean_config) def refresh(call): _LOGGER.warning(call) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) for _component in DUOFERN_COMPONENTS: discovery.load_platform(hass, _component, DOMAIN, {}, config) def update_callback(id, key, value): if id is not None: try: device = hass.data[DOMAIN]['devices'][id] # Get device by id if not device.should_poll: # Only trigger update if this entity is not polling try: device.schedule_update_ha_state( True) # Trigger update on the updated entity except AssertionError: _LOGGER.warning( "Update callback called before HA is ready" ) # Trying to update before HA is ready except KeyError: _LOGGER.warning("Update callback called on unknown device id" ) # Ignore invalid device ids stick.add_updates_callback(update_callback) time.sleep( 5 ) # Wait for 5 seconds so HA can get our entities ready so we don't miss any updates (there are probably nicer ways to do this) stick.start() # Start the stick after 5 seconds return True
parser.add_argument('--pair-time', help='time to wait for pairing requests in seconds', metavar="seconds", default=60, type=int) args = parser.parse_args(sys.argv[1:]) logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) config_file = tempfile.NamedTemporaryFile(delete=False) config_file.write(b'{}') config_file.close() try: stick = DuofernStickThreaded(serial_port=args.device, system_code=args.code, config_file_json=config_file.name) stick._initialize() stick.daemon = False stick.start() if args.pair: stick.pair(timeout=args.pair_time) time.sleep(args.pairtime + 0.5) else: app.run(debug=args.debug is True, host=args.listen, port=args.port) except KeyboardInterrupt: pass except Exception as error: print(error) finally: