def __init__(self, accessory, port, address=None, persist_file="accessory.state", encoder=None): """ :param accessory: The `Accessory` to be managed by this driver. The `Accessory` must have the standalone AID (`pyhap.accessory.STANDALONE_AID`). If the AID of the `Accessory` is None, the standalone AID will be assigned to it. Also, if the mac of the `Accessory` is None, a randomly-generated one will be assigned to it. :type accessory: Accessory :param port: The local port on which the accessory will be accessible. In other words, this is the port of the HAPServer. :type port: int :param address: The local address on which the accessory will be accessible. In other words, this is the address of the HAPServer. If not given, the driver will try to select an address. :type address: str :param persist_file: The file name in which the state of the accessory will be persisted. This uses `expandvars`, so may contain `~` to refer to the user's home directory. :type persist_file: str :param encoder: The encoder to use when persisting/loading the Accessory state. :type encoder: AccessoryEncoder """ if accessory.aid is None: accessory.aid = STANDALONE_AID elif accessory.aid != STANDALONE_AID: raise ValueError("Top-level accessory must have the standalone AID.") if accessory.mac is None: accessory.mac = util.generate_mac() self.accessory = accessory self.address = address or util.get_local_address() self.http_server = HAPServer((self.address, port), self) self.http_server_thread = None self.advertiser = Zeroconf() self.port = port self.persist_file = os.path.expanduser(persist_file) self.encoder = encoder or AccessoryEncoder() if os.path.exists(self.persist_file): logger.info("Loading Accessory state from `%s`", self.persist_file) self.load() else: logger.info("Storing Accessory state in `%s`", self.persist_file) self.persist() self.topics = {} # topic: set of (address, port) of subscribed clients self.topic_lock = threading.Lock() # for exclusive access to the topics self.event_queue = queue.Queue() # (topic, bytes) self.send_event_thread = None # the event dispatch thread self.sent_events = 0 self.accumulated_qsize = 0 self.accessory.set_broker(self) self.mdns_service_info = None self.srp_verifier = None self.run_sentinel = None self.accessory_thread = None
def convert(fromfile, tofile): print("Unpickling...") with open(fromfile, "rb") as fp: acc = pickle.load(fp) print("Persiting new state...") with open(tofile, "w") as fp: AccessoryEncoder().persist(fp, acc) print("Done!")
def __init__(self, *, address=None, port=51234, persist_file='accessory.state', pincode=None, encoder=None, loader=None, loop=None, mac=None, listen_address=None, advertised_address=None, interface_choice=None, zeroconf_instance=None): """ Initialize a new AccessoryDriver object. :param pincode: The pincode that HAP clients must prove they know in order to pair with this `Accessory`. Defaults to None, in which case a random pincode is generated. The pincode has the format "xxx-xx-xxx", where x is a digit. :type pincode: bytearray :param port: The local port on which the accessory will be accessible. In other words, this is the port of the HAPServer. :type port: int :param address: The local address on which the accessory will be accessible. In other words, this is the address of the HAPServer. If not given, the driver will try to select an address. :type address: str :param persist_file: The file name in which the state of the accessory will be persisted. This uses `expandvars`, so may contain `~` to refer to the user's home directory. :type persist_file: str :param encoder: The encoder to use when persisting/loading the Accessory state. :type encoder: AccessoryEncoder :param mac: The MAC address which will be used to identify the accessory. If not given, the driver will try to select a MAC address. :type mac: str :param listen_address: The local address on the HAPServer will listen. If not given, the value of the address parameter will be used. :type listen_address: str :param advertised_address: The address of the HAPServer announced via mDNS. This can be used to announce an external address from behind a NAT. If not given, the value of the address parameter will be used. :type advertised_address: str :param interface_choice: The zeroconf interfaces to listen on. :type InterfacesType: [InterfaceChoice.Default, InterfaceChoice.All] :param zeroconf_instance: A Zeroconf instance. When running multiple accessories or bridges a single zeroconf instance can be shared to avoid the overhead of processing the same data multiple times. """ if loop is None: if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() else: loop = asyncio.new_event_loop() executor_opts = {'max_workers': None} if sys.version_info >= (3, 6): executor_opts['thread_name_prefix'] = 'SyncWorker' self.executor = ThreadPoolExecutor(**executor_opts) loop.set_default_executor(self.executor) else: self.executor = None self.loop = loop self.accessory = None self.http_server_thread = None if zeroconf_instance is not None: self.advertiser = zeroconf_instance elif interface_choice is not None: self.advertiser = Zeroconf(interfaces=interface_choice) else: self.advertiser = Zeroconf() self.persist_file = os.path.expanduser(persist_file) self.encoder = encoder or AccessoryEncoder() self.topics = {} # topic: set of (address, port) of subscribed clients self.topic_lock = threading.Lock( ) # for exclusive access to the topics self.loader = loader or Loader() self.aio_stop_event = asyncio.Event(loop=loop) self.stop_event = threading.Event() self.event_queue = ( queue.SimpleQueue() if hasattr(queue, "SimpleQueue") else queue.Queue() # pylint: disable=no-member ) self.send_event_thread = None # the event dispatch thread self.sent_events = 0 self.accumulated_qsize = 0 self.safe_mode = False self.mdns_service_info = None self.srp_verifier = None address = address or util.get_local_address() advertised_address = advertised_address or address self.state = State(address=advertised_address, mac=mac, pincode=pincode, port=port) listen_address = listen_address or address network_tuple = (listen_address, self.state.port) self.http_server = HAPServer(network_tuple, self)
def __init__( self, *, address=None, port=51234, persist_file="accessory.state", pincode=None, encoder=None, loader=None, loop=None, mac=None, listen_address=None, advertised_address=None, interface_choice=None, zeroconf_instance=None ): if loop is None: if sys.platform == "win32": loop = asyncio.ProactorEventLoop() else: loop = asyncio.new_event_loop() executor_opts = {"max_workers": None} if sys.version_info >= (3, 6): executor_opts["thread_name_prefix"] = "SyncWorker" self.executor = ThreadPoolExecutor(**executor_opts) loop.set_default_executor(self.executor) self.tid = threading.current_thread() else: self.tid = threading.main_thread() self.executor = None self.loop = loop self.accessory = None if zeroconf_instance is not None: self.advertiser = zeroconf_instance elif interface_choice is not None: self.advertiser = Zeroconf(interfaces=interface_choice) else: self.advertiser = Zeroconf() self.persist_file = os.path.expanduser(persist_file) self.encoder = encoder or AccessoryEncoder() self.topics = {} # topic: set of (address, port) of subscribed clients self.loader = loader or Loader() self.aio_stop_event = asyncio.Event(loop=loop) self.stop_event = threading.Event() self.safe_mode = False self.mdns_service_info = None self.srp_verifier = None address = address or util.get_local_address() advertised_address = advertised_address or address self.state = State( address=advertised_address, mac=mac, pincode=pincode, port=port ) listen_address = listen_address or address network_tuple = (listen_address, self.state.port) self.http_server = Server(network_tuple, self)
def __init__(self, *, address=None, port=51234, persist_file='accessory.state', pincode=None, encoder=None, loader=None, loop=None): """ Initialize a new AccessoryDriver object. :param pincode: The pincode that HAP clients must prove they know in order to pair with this `Accessory`. Defaults to None, in which case a random pincode is generated. The pincode has the format "xxx-xx-xxx", where x is a digit. :type pincode: bytearray :param port: The local port on which the accessory will be accessible. In other words, this is the port of the HAPServer. :type port: int :param address: The local address on which the accessory will be accessible. In other words, this is the address of the HAPServer. If not given, the driver will try to select an address. :type address: str :param persist_file: The file name in which the state of the accessory will be persisted. This uses `expandvars`, so may contain `~` to refer to the user's home directory. :type persist_file: str :param encoder: The encoder to use when persisting/loading the Accessory state. :type encoder: AccessoryEncoder """ if sys.platform == 'win32': self.loop = loop or asyncio.ProactorEventLoop() else: self.loop = loop or asyncio.new_event_loop() executer_opts = {'max_workers': None} if sys.version_info >= (3, 6): executer_opts['thread_name_prefix'] = 'SyncWorker' self.executer = ThreadPoolExecutor(**executer_opts) self.loop.set_default_executor(self.executer) self.accessory = None self.http_server_thread = None self.advertiser = Zeroconf() self.persist_file = os.path.expanduser(persist_file) self.encoder = encoder or AccessoryEncoder() self.topics = {} # topic: set of (address, port) of subscribed clients self.topic_lock = threading.Lock( ) # for exclusive access to the topics self.loader = loader or Loader() self.aio_stop_event = asyncio.Event(loop=self.loop) self.stop_event = threading.Event() self.event_queue = queue.Queue() # (topic, bytes) self.send_event_thread = None # the event dispatch thread self.sent_events = 0 self.accumulated_qsize = 0 self.mdns_service_info = None self.srp_verifier = None self.accessory_thread = None self.state = State(address=address, pincode=pincode, port=port) network_tuple = (self.state.address, self.state.port) self.http_server = HAPServer(network_tuple, self)