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)
예제 #2
0
 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()
예제 #3
0
    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()
예제 #4
0
    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
예제 #5
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"]
예제 #6
0
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()
예제 #7
0
 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)
예제 #8
0
 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)
예제 #10
0
 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
예제 #11
0
 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
예제 #12
0
 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
예제 #13
0
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()
예제 #14
0
 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
예제 #15
0
 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())
예제 #16
0
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()
예제 #17
0
 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)
예제 #18
0
 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")
예제 #19
0
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()
예제 #20
0
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()
예제 #21
0
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
예제 #22
0
    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()
예제 #23
0
 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()
예제 #24
0
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')
예제 #25
0
 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)
예제 #26
0
 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)
예제 #27
0
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:
예제 #28
0
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())
예제 #29
0
 def __init__(self):
     self._ba = bytearray(32)
     self._evdis = asyncio.Event()  # Discard event
예제 #30
0
    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())