async def main(): global ev ev = asyncio.Event() server = await asyncio.start_server(handle_connection, "0.0.0.0", PORT) multitest.next() async with server: await asyncio.wait_for(ev.wait(), 10)
def __init__(self, participants, func=None, args=()): self._participants = participants self._count = participants self._func = func self._args = args self._res = None self._evt = asyncio.Event()
def __init__(self, spi, cs, dc, rst, busy, landscape=True, asyn=False): self._spi = spi self._cs = cs # Pins self._dc = dc self._rst = rst # Active low. self._busy = busy # Active low on IL0373 self._lsc = landscape self._asyn = asyn # ._as_busy is set immediately on start of task. Cleared # when busy pin is logically false (physically 1). self._as_busy = False self._updated = asyncio.Event() # Public bound variables required by nanogui. # Dimensions in pixels as seen by nanogui (landscape mode). self.width = 296 if landscape else 128 self.height = 128 if landscape else 296 # Other public bound variable. # Special mode enables demos written for generic displays to run. self.demo_mode = False self._buffer = bytearray(self.height * self.width // 8) self._mvb = memoryview(self._buffer) mode = framebuf.MONO_VLSB if landscape else framebuf.MONO_HLSB super().__init__(self._buffer, self.width, self.height, mode) self.init()
def __init__(self, freq=25, timer_id=default_timer_id, max_scheduled=2, refresh_cb=None, asynchronous=False): if self.is_running(): raise RuntimeError("Event loop is already running!") if not lv.is_initialized(): lv.init() event_loop._current_instance = self self.delay = 1000 // freq self.refresh_cb = refresh_cb self.asynchronous = asynchronous if self.asynchronous: if not uasyncio_available: raise RuntimeError( "Cannot run asynchronous event loop. uasyncio is not available!" ) self.refresh_event = uasyncio.Event() self.refresh_task = uasyncio.create_task(self.async_refresh()) self.timer_task = uasyncio.create_task(self.async_timer()) else: self.timer = Timer(timer_id) self.task_handler_ref = self.task_handler # Allocation occurs here self.timer.init(mode=Timer.PERIODIC, period=self.delay, callback=self.timer_cb) self.max_scheduled = max_scheduled self.scheduled = 0
async def scan_for_response(self, expected_type: int, name: str, timeout: float = 1.5) -> "Optional[DNSRecord]": def matching_record( dns_response: DNSResponse) -> "Optional[DNSRecord]": for record in dns_response.records: if record.record_type == expected_type and record.name == name: return record result = {"data": None, "event": uasyncio.Event()} async def scan_response(dns_response: DNSResponse) -> None: record = matching_record(dns_response) if record is None: return None result["data"] = record result["event"].set() loop = uasyncio.get_event_loop() loop.create_task(set_after_timeout(result["event"], timeout)) async def is_match(dns_response: DNSResponse) -> bool: return matching_record(dns_response) is not None self.add_callback(scan_response, is_match, timeout) await result["event"].wait() return result["data"]
async def do_usec(minutes): tick = Message() print('Setting up GPS.') gps = await us_setup(tick) print('Waiting for time data.') await gps.ready() max_us = 0 min_us = 0 sd = 0 nsamples = 0 count = 0 terminate = asyncio.Event() asyncio.create_task(killer(terminate, minutes)) while not terminate.is_set(): await tick.wait() usecs = tick.value() tick.clear() err = 1000000 - usecs count += 1 print('Timing discrepancy is {:4d}μs {}'.format( err, '(skipped)' if count < 3 else '')) if count < 3: # Discard 1st two samples from statistics continue # as these can be unrepresentative max_us = max(max_us, err) min_us = min(min_us, err) sd += err * err nsamples += 1 # SD: apply Bessel's correction for infinite population sd = int(math.sqrt(sd / (nsamples - 1))) print( 'Timing discrepancy is: {:5d}μs max {:5d}μs min. Standard deviation {:4d}μs' .format(max_us, min_us, sd)) gps.close()
def __init__(self, r1, r2): self.r1 = r1 self.r2 = r2 self.myevent = asyncio.Event() asyncio.create_task(self.action()) r1.add_listener(self.callback) r2.add_listener(self.callback)
def __init__(self, pin, pull=None, released_component=None, double_pressed_component=None, double_pressed_method="on", long_pressed_component=None, long_pressed_method="on", suppress=False, **kwargs): """ Basic functionality for push is to toggle a device. Double press and long press are just extended functionality. :param pin: pin number or name :param pull: None for no pullup or pull_down, otherwise value of pull configuration :param released_component: component name of component to be turned on when button pressed :param double_pressed_component: component name of component to be turned on when button double pressed :param double_pressed_method: string of the method of the component that is to be called :param long_pressed_component: component name of component to be turned on when button long pressed :param long_pressed_method: string of the method of the component that is to be called :param suppress: Suppress calling release function after double click and long press. Will delay release function by 300ms if double click is used. """ self._component = released_component self._event = asyncio.Event() # Synchronous method _event.set() to prevent queue overflows from pressing button too often super().__init__(pin, pull, None, "off", self._event, "set", double_pressed_component, double_pressed_method, long_pressed_component, long_pressed_method, suppress, **kwargs) asyncio.create_task(self._watcher())
async def tcp_server(): global ev ev = asyncio.Event() server = await asyncio.start_server(handle_connection, "0.0.0.0", PORT) print("server running") multitest.next() async with server: await asyncio.wait_for(ev.wait(), 5)
def getStateChangeEvent(self): """ Returns an event that gets triggered on every state change :return: Event """ if self._event is None: self._event = asyncio.Event() return self._event
def getReadingsEvent(self): """ Returns an event that gets triggered on every read :return: Event """ if self._event is None: self._event = asyncio.Event() return self._event
async def wait(self): if not self.lock.locked(): raise RuntimeError('Condition wait with lock not acquired.') ev = asyncio.Event() self.events.append(ev) self.lock.release() await ev.wait() await self.lock.acquire() assert ev not in self.events, 'condition wait assertion fail' return True # CPython compatibility
async def main(): ev = asyncio.Event() tasks = [ asyncio.create_task(task1(0)), asyncio.create_task(task2(2, ev)), asyncio.create_task(task1(1)), asyncio.create_task(task2(3, ev)), ] await tasks[1] ev.set()
def __init__(self, *args, **kwargs): d = defaults # d is the config dict: initially populate with default values for arg in args: d.update(arg) # Hardware and network configs d.update(kwargs) # d is now populated. self.user_start = d['user_start'] shan = d['status_handler'] self.s_han = (default_status_handler, ()) if shan is None else shan # coro self.crash_han = d['crash_handler'] self.wifi_han = d['wifi_handler'] self.init_str = buildinit(d) self.keepalive = d['keepalive'] self._evtrun = asyncio.Event() self.verbose = d['verbose'] # Watchdog timeout for ESP8266 (ms). wdog = d['timeout'] * 1000 # SynCom string mode self.channel = SynCom(False, d['sckin'], d['sckout'], d['srx'], d['stx'], d['reset'], wdog, True, self.verbose) if 'led' in d: asyncio.create_task(heartbeat(d['led'])) # Start the SynCom instance. This will run self.start(). If an error # occurs self.quit() is called which returns to Syncom's start() method. # This waits on ._die before forcing a failure on the ESP8266 and re-running # self.start() to perform a clean restart. asyncio.create_task(self.channel.start(self.start, self._die)) self.subs = {} # (callback, qos, args) indexed by topic self.publock = asyncio.Lock() self.puback = asyncio.Event() self.evttim = asyncio.Event() self.evtwifi = asyncio.Event() # Only specify network on first run self.first_run = True self._time = 0 # NTP time. Invalid. # ESP8266 returns seconds from 2000 because I believed the docs. # Maintainers change the epoch on a whim. # Calculate ofsets in CPython using datetime.date: # (date(2000, 1, 1) - date(1970, 1, 1)).days * 24*60*60 epoch = {2000 : 0, 1970 : 946684800} # Offset to add. self._epoch_fix = epoch[gmtime(0)[0]] # Find offset on current platform
def __init__(self, func=None, args=(), duration=1000): self._func = func self._args = args self._durn = duration # Default duration self._retn = None # Return value of launched callable self._tend = None # Stop time (absolute ms). self._busy = False self._trig = asyncio.ThreadSafeFlag() self._tout = asyncio.Event() # Timeout event self.wait = self._tout.wait # Allow: await wait_ms.wait() self._ttask = self._fake # Timer task asyncio.create_task(self._run())
async def do_drift(minutes): print('Setting up GPS.') gps = await setup() print('Waiting for time data.') await gps.ready() terminate = asyncio.Event() asyncio.create_task(killer(terminate, minutes)) print('Setting RTC.') await gps.set_rtc() print('Measuring drift.') change = await drift_test(terminate, gps) ush = int(60 * change / minutes) spa = int(ush * 365 * 24 / 1000000) print('Rate of change {}μs/hr {}secs/year'.format(ush, spa)) gps.close()
def __init__(self, verbose): self.verbose = verbose led = Pin(2, Pin.OUT, value=1) # Optional LED # Pushbutton on Cockle board from shrimping.it self.switch = Switch(Pin(0, Pin.IN)) self.switch.close_func(lambda _: self.must_send.set()) self.switch.open_func(lambda _: self.must_send.set()) self.must_send = asyncio.Event() self.cl = client.Client('tx', local.SERVER, local.PORT, local.SSID, local.PW, local.TIMEOUT, verbose=verbose, led=led)
async def _keep_alive(self, proto): rt_ms = self._c["response_time"] * 1000 try: while proto.isconnected(): dt = ticks_diff(ticks_ms(), proto.last_ack) if dt > rt_ms: # it's time for another ping... self._unacked_pids[PING_PID] = [asyncio.Event(), None] await asyncio.wait_for(self._ping_n_wait(proto), self._c["response_time"]) dt = ticks_diff(ticks_ms(), proto.last_ack) sleep_time = rt_ms - dt if sleep_time < rt_ms / 4: # avoid sending pings too frequently sleep_time = rt_ms / 4 await asyncio.sleep_ms(sleep_time) except Exception: await self._reconnect(proto, "keepalive")
async def do_time(minutes): fstr = '{}ms Time: {:02d}:{:02d}:{:02d}:{:06d}' print('Setting up GPS.') gps = await setup() print('Waiting for time data.') await gps.ready() print('Setting RTC.') await gps.set_rtc() terminate = asyncio.Event() asyncio.create_task(killer(terminate, minutes)) while not terminate.is_set(): await asyncio.sleep(1) # In a precision app, get the time list without allocation: t = gps.get_t_split() print(fstr.format(gps.get_ms(), t[0], t[1], t[2], t[3])) gps.close()
async def log_data(data): global f_lock evt = asyncio.Event() # Event to wait for thread completion. def fwriter(): try: with open(dfl.DATA_DIR + '/' + dailyfile(), 'a') as f: f.write('{}\r\n'.format(data)) log(data) except Exception as err: log(type(err).__name__, err, type='e') evt.set() async with f_lock: _thread.start_new_thread(fwriter, ()) await asyncio.sleep_ms(10) await evt.wait() evt.clear()
async def main(): refresh(ssd, True) # Clear display await ssd.wait() print('Ready') evt = asyncio.Event() asyncio.create_task(meter(evt)) asyncio.create_task(multi_fields(evt)) asyncio.create_task(compass(evt)) while True: # Normal procedure before refresh, but 10s sleep should mean it always returns immediately await ssd.wait() refresh(ssd) # Launches ._as_show() await ssd.updated() # Content has now been shifted out so coros can update # framebuffer in background evt.set() evt.clear() await asyncio.sleep(10) # Allow for slow refresh
def __init__(self, server_ip: str, base_topic: str, ssid: str, wifi_pw: str) -> None: mqtt_as.config['server'] = server_ip mqtt_as.config['ssid'] = ssid mqtt_as.config['wifi_pw'] = wifi_pw mqtt_as.config['subs_cb'] = self.callback mqtt_as.config['connect_coro'] = self.conn_han self.base_topic = base_topic self.unique_id = ubinascii.hexlify(machine.unique_id()).decode('utf-8') mqtt_as.MQTTClient.DEBUG = True # Optional: print diagnostic messages self.client: mqtt_as.MQTTClient = mqtt_as.MQTTClient(mqtt_as.config) self._data_available = asyncio.Event( ) # Triggered by put, tested by get self.topics: Dict[ str, Optional[Dict]] = dict() # sensor name -> state_topic to publish self.callbacks: Dict[str, Callable[..., None]] = dict()
def __init__(self, spi, cs, dc, rst, busy, landscape=False, asyn=False): self._spi = spi self._cs = cs # Pins self._dc = dc self._rst = rst self._busy = busy self._lsc = landscape self._asyn = asyn self._as_busy = False # Set immediately on start of task. Cleared when busy pin is logically false (physically 1). self._updated = asyncio.Event() # Dimensions in pixels. Waveshare code is portrait mode. # Public bound variables required by nanogui. self.width = 264 if landscape else 176 self.height = 176 if landscape else 264 self.demo_mode = False # Special mode enables demos to run self._buffer = bytearray(self.height * self.width // 8) self._mvb = memoryview(self._buffer) mode = framebuf.MONO_VLSB if landscape else framebuf.MONO_HLSB super().__init__(self._buffer, self.width, self.height, mode) self.init()
class App: data = None if upython: trig_send = Event() else: trig_send = asyncio.Event() def __init__(self, loop, client_id): self.client_id = client_id # This instance talks to this client self.conn = None # Connection instance loop.create_task(self.start(loop)) async def start(self, loop): my_id = self.client_id print('Client {} Awaiting connection.'.format(my_id)) # Wait for all clients to connect self.conn = await server.wait_all(my_id) print('Message from {}: all peers are connected.'.format(my_id)) if my_id == 'tx': # Client is sending loop.create_task(self.reader()) else: loop.create_task(self.writer()) async def reader(self): print('Started reader') while True: line = await self.conn.readline() # Pause in event of outage App.data = json.loads(line) print('Got', App.data, 'from remote', self.client_id) App.trig_send.set() async def writer(self): print('Started writer') data = None while True: await App.trig_send.wait() App.trig_send.clear() data = App.data await self.conn.write(json.dumps(data), False) # Reduce latency print('Sent', data, 'to remote', self.client_id, '\n')
async def subscribe(self, topic, qos=0): _qos_check(qos) pid = self._newpid() self._unacked_pids[pid] = [asyncio.Event(), None] while True: while self._proto is None: await asyncio.sleep(_CONN_DELAY) try: proto = self._proto await self._proto.subscribe(topic, qos, pid) actual_qos = await self._await_pid(pid) if actual_qos == qos: return elif actual_qos == 0x80: raise OSError(-2, "refused") else: raise OSError(-2, "qos mismatch") except OSError as e: if e.args[0] == -2: raise OSError(-1, "subscribe failed: " + e.args[1]) await self._reconnect(proto, "sub", e)
async def publish(self, topic, msg, retain=False, qos=0, sync=True): dup = 0 pid = self._newpid() if qos else None message = MQTTMessage(topic, msg, retain, qos, pid) while True: # print("pub begin for pid=%s" % pid) # first we need a connection while self._proto is None: await asyncio.sleep(_CONN_DELAY) proto = self._proto try: # now publish the new packet on the same connection # print("pub->%s qos=%d pid=%s" % (message.topic, message.qos, message.pid)) await proto.publish(message, dup) if qos == 0: return # the following is atomic with the above publish self._unacked_pids[pid] = [asyncio.Event(), None] if not sync: # async packet, need to wait 'til self._prev_pub becomes available while self._prev_pub is not None: # only False on the first async pub... ppid = self._prev_pub.pid if ppid is not None: # print("pub pid=%d awaiting prev_pid=%d" % (pid, ppid)) await self._await_pid(ppid) if self._prev_pub.pid == ppid: # no-one has snatched the slot yet: our turn! # print("pub pid=%d is now prev" % pid) break self._prev_pub = message self._prev_pub_proto = proto else: # sync packet await self._await_pid(message.pid) return except OSError as e: await self._reconnect(proto, "pub", e)
async def pass_through(device, uart, fw): cancel = asyncio.Event() # Task cancellation event. device.init_uart() dreader = asyncio.StreamReader(device.uart) dwriter = asyncio.StreamWriter(device.uart, {}) mwriter = asyncio.StreamWriter(uart, {}) async def send(dwriter, fw): b = bytearray() while True: await fw if fw.value() == ESC: cancel.set() else: print(fw.value().decode(), end='') b.append(ord(fw.value())) if fw.value() == b'\r': await dwriter.awrite(b) b = bytearray() fw.clear() await asyncio.sleep(0) async def recv(dreader, mwriter): while True: res = await dreader.readline() if res is not None: await mwriter.awrite(res) await asyncio.sleep(0) send_ = asyncio.create_task(send(dwriter, fw)) recv_ = asyncio.create_task(recv(dreader, mwriter)) await cancel.wait() send_.cancel() recv_.cancel() return '''while True:
class Screen: current_screen = None tft = None objtouch = None is_shutdown = asyncio.Event() @classmethod def setup(cls, tft, objtouch): cls.objtouch = objtouch cls.tft = tft # get_tft() when called from user code, ensure greyed_out status is updated. @classmethod def get_tft(cls, greyed_out=False): cls.tft.usegrey(greyed_out) return cls.tft @classmethod def set_grey_style(cls, *, desaturate=True, factor=2): cls.tft.dim(factor) cls.tft.desaturate(desaturate) if Screen.current_screen is not None: # Can call before instantiated for obj in Screen.current_screen.displaylist: if obj.visible and obj.greyed_out(): obj.redraw = True # Redraw static content obj.draw_border() obj.show() @classmethod def show(cls): for obj in cls.current_screen.displaylist: if obj.visible: # In a buttonlist only show visible button obj.redraw = True # Redraw static content obj.draw_border() obj.show() @classmethod def change(cls, cls_new_screen, *, forward=True, args=[], kwargs={}): init = cls.current_screen is None if init: Screen() # Instantiate a blank starting screen else: # About to erase an existing screen for entry in cls.current_screen.tasklist: if entry[1]: # To be cancelled on screen change entry[0].cancel() cs_old = cls.current_screen cs_old.on_hide() # Optional method in subclass if forward: if isinstance(cls_new_screen, ClassType): new_screen = cls_new_screen(*args, **kwargs) # Instantiate new screen else: raise ValueError( 'Must pass Screen class or subclass (not instance)') new_screen.parent = cs_old cs_new = new_screen else: cs_new = cls_new_screen # An object, not a class cls.current_screen = cs_new cs_new.on_open() # Optional subclass method cs_new._do_open(cs_old) # Clear and redraw cs_new.after_open() # Optional subclass method if init: try: asyncio.run(Screen.monitor()) # Starts and ends uasyncio finally: asyncio.new_event_loop() gc.collect() @classmethod async def monitor(cls): await cls.is_shutdown.wait() cls.is_shutdown.clear() for entry in cls.current_screen.tasklist: entry[0].cancel() await asyncio.sleep_ms(0) # Allow subclass to cancel tasks cls.tft.clrSCR() cls.current_screen = None # Ensure another demo can run @classmethod def back(cls): parent = cls.current_screen.parent if parent is not None: cls.change(parent, forward=False) @classmethod def addobject(cls, obj): if cls.current_screen is None: raise OSError('You must create a Screen instance') if isinstance(obj, Touchable): cls.current_screen.touchlist.append(obj) cls.current_screen.displaylist.append(obj) @classmethod def shutdown(cls): cls.is_shutdown.set() def __init__(self): self.touchlist = [] self.displaylist = [] self.tasklist = [] # Allow instance to register tasks for shutdown self.modal = False if Screen.current_screen is None: # Initialising class and task asyncio.create_task(self._touchtest()) # One task only asyncio.create_task(self._garbage_collect()) Screen.current_screen = self self.parent = None async def _touchtest(self): # Singleton task tests all touchable instances touch_panel = Screen.objtouch while True: await asyncio.sleep_ms(0) if touch_panel.ready: x, y = touch_panel.get_touch_async() for obj in Screen.current_screen.touchlist: if obj.visible and not obj.greyed_out(): obj._trytouch(x, y) elif not touch_panel.touched: for obj in Screen.current_screen.touchlist: if obj.was_touched: obj.was_touched = False # Call _untouched once only obj.busy = False obj._untouched() def _do_open(self, old_screen): # Aperture overrides show_all = True tft = Screen.get_tft() # If opening a Screen from an Aperture just blank and redraw covered area if old_screen.modal: show_all = False x0, y0, x1, y1 = old_screen._list_dims() tft.fill_rectangle(x0, y0, x1, y1, tft.getBGColor()) # Blank to screen BG for obj in [ z for z in self.displaylist if z.overlaps(x0, y0, x1, y1) ]: if obj.visible: obj.redraw = True # Redraw static content obj.draw_border() obj.show() # Normally clear the screen and redraw everything else: tft.clrSCR() Screen.show() def on_open(self): # Optionally implemented in subclass return def after_open(self): # Optionally implemented in subclass return def on_hide(self): # Optionally implemented in subclass return def reg_task(self, task, on_change=False): # May be passed a coro or a Task if isinstance(task, type_coro): task = asyncio.create_task(task) self.tasklist.append([task, on_change]) async def _garbage_collect(self): while True: await asyncio.sleep_ms(100) gc.collect() gc.threshold(gc.mem_free() // 4 + gc.mem_alloc())
def __init__(self): self._ba = bytearray(32) self._evdis = asyncio.Event() # Discard event
def __init__(self, my_id, server, port=8123, ssid='', pw='', timeout=2000, conn_cb=None, conn_cb_args=None, verbose=False, led=None, wdog=False): self._my_id = '{}{}'.format(my_id, '\n') # Ensure >= 1 newline self._server = server self._ssid = ssid self._pw = pw self._port = port self._to = timeout # Client and server timeout self._tim_ka = timeout // 4 # Keepalive interval self._concb = conn_cb self._concbargs = () if conn_cb_args is None else conn_cb_args self._verbose = verbose self._led = led if wdog: if platform == 'pyboard': self._wdt = machine.WDT(0, 20000) def wdt(): def inner(feed=0): # Ignore control values if not feed: self._wdt.feed() return inner self._feed = wdt() else: def wdt(secs=0): timer = machine.Timer(-1) timer.init(period=1000, mode=machine.Timer.PERIODIC, callback=lambda t: self._feed()) cnt = secs run = False # Disable until 1st feed def inner(feed=WDT_CB): nonlocal cnt, run, timer if feed == 0: # Fixed timeout cnt = secs run = True elif feed < 0: # WDT control/callback if feed == WDT_CANCEL: timer.deinit() # Permanent cancellation elif feed == WDT_CB and run: # Timer callback and is running. cnt -= 1 if cnt <= 0: machine.reset() return inner self._feed = wdt(20) else: self._feed = lambda x: None self._sta_if = network.WLAN(network.STA_IF) ap = network.WLAN(network.AP_IF) # create access-point interface ap.active(False) # deactivate the interface self._sta_if.active(True) gc.collect() if platform == 'esp8266': import esp # Improve connection integrity at cost of power consumption. esp.sleep_type(esp.SLEEP_NONE) self._evfail = asyncio.Event() # Set by any comms failure self._evok = asyncio.Event() # Set by 1st successful read self._s_lock = asyncio.Lock() # For internal send conflict. self._w_lock = asyncio.Lock() # For .write rate limit self._last_wr = utime.ticks_ms() self._lineq = Queue(20) # 20 entries self.connects = 0 # Connect count for test purposes/app access self._sock = None self._acks_pend = ASetByte() # ACKs which are expected to be received gc.collect() asyncio.create_task(self._run())