Пример #1
0
 def write_object_stub(self, fp, object_expr: object, obj_name: str,
                       indent: str):
     if object_expr in self.problematic:
         return
     items, errors = self.get_obj_attributes(object_expr)
     for name, rep, typ, obj in sorted(items, key=lambda x: x[0]):
         if name.startswith("__"):
             continue
         resetWDT()
         sleep_us(1)
         if typ in ["<class 'function'>", "<class 'bound_method'>"]:
             s = indent + "def " + name + "():\n"
             s += indent + "    pass\n\n"
             fp.write(s)
         elif typ in ["<class 'str'>", "<class 'int'>", "<class 'float'>"]:
             s = indent + name + " = " + rep + "\n"
             fp.write(s)
         elif typ == "<class 'type'>" and indent == "":
             s = "\n" + indent + "class " + name + ":\n"
             s += indent + "    ''\n"
             fp.write(s)
             self.write_object_stub(fp, obj,
                                    "{0}.{1}".format(obj_name,
                                                     name), indent + "    ")
         else:
             fp.write(indent + name + " = None\n")
     del items
     del errors
     try:
         del name, rep, typ, obj
     except (OSError, KeyError):
         pass
Пример #2
0
    def write_object_stub(self, fp, object_expr: object, obj_name: str,
                          indent: str):
        "Write a module/object stub to an open file. Can be called recursive."
        if object_expr in self.problematic:
            self._log.warning(
                "SKIPPING problematic module:{}".format(object_expr))
            return

        self._log.debug("DUMP    : {}".format(object_expr))
        items, errors = self.get_obj_attributes(object_expr)

        if errors:
            self._log.error(errors)

        for name, rep, typ, obj in sorted(items, key=lambda x: x[0]):
            if name.startswith("__"):
                #skip internals
                continue

            # allow the scheduler to run on LoBo based FW
            resetWDT()
            sleep_us(1)

            self._log.debug("DUMPING {}{}{}:{}".format(indent, object_expr,
                                                       name, typ))

            if typ in ["<class 'function'>", "<class 'bound_method'>"]:
                s = indent + "def " + name + "():\n"  #todo: add self, and optional params
                s += indent + "    pass\n\n"
                fp.write(s)
                self._log.debug('\n' + s)

            elif typ in ["<class 'str'>", "<class 'int'>", "<class 'float'>"]:
                s = indent + name + " = " + rep + "\n"
                fp.write(s)
                self._log.debug('\n' + s)
            #new class
            elif typ == "<class 'type'>" and indent == "":
                # full expansion only on toplevel
                # stub style : Empty comment ... + hardcoded 4 spaces
                s = "\n" + indent + "class " + name + ":\n"  # What about superclass?
                s += indent + "    ''\n"

                fp.write(s)
                self._log.debug('\n' + s)

                self._log.debug("# recursion..")
                self.write_object_stub(fp, obj,
                                       "{0}.{1}".format(obj_name,
                                                        name), indent + "    ")
            else:
                # keep only the name
                fp.write(indent + name + " = None\n")
        del items
        del errors
        try:
            del name, rep, typ, obj  # pylint: disable=undefined-loop-variable
        except (OSError, KeyError):  #lgtm [py/unreachable-statement]
            pass
Пример #3
0
 async def task_check_software_updates(self, once=False):
     while True:
         machine.resetWDT()
         if check_software_update():
             schedule_software_update()
         machine.resetWDT()
         if once:
             break
         await uasyncio.sleep(3600)
Пример #4
0
 async def bg_leds(self):
     while True:
         machine.resetWDT()
         if self._network._wlan:
             await self.blink(("status", ),
                              1 if self._network._wlan.mode == AP_IF else 2,
                              100)
         elif self._network.gsm:
             await self.blink(("status", ),
                              4 if self._network.online() else 3, 100)
         await uasyncio.sleep(2)
         gc.collect()
Пример #5
0
 def off(self):
     if self.gsm:
         import gsm
         machine.resetWDT()
         gsm.stop()
         if self._gsm_pwr_key:
             self._gsm_pwr_key.value(0)
         if self._gsm_rst:
             self._gsm_rst.value(0)
         #if self._gsm_pwr:
         #    self._gsm_pwr.value(0)
         if self._gsm_modem_on:
             for uart_pin_type in ('tx', 'rx'):
                 machine.Pin(self._conf['gsm_modem'][uart_pin_type],
                             machine.Pin.OUT,
                             value=0)
             self._gsm_modem_on.value(0)
Пример #6
0
    def gsm_start(self, apn_settings):
        import gsm
        gsm.debug(True)  # see more logs, investigate issues, etc.

        gsm.start(tx=self._conf['gsm_modem']['tx'],
                  rx=self._conf['gsm_modem']['rx'],
                  **apn_settings)

        sys.stdout.write('Waiting for AT command response...')
        for retry in range(20):
            machine.resetWDT()
            if gsm.atcmd('AT'):
                return True
            else:
                sys.stdout.write('.')
                utime.sleep(5)
        else:
            sys.stdout.write("Modem not responding!")
            machine.reset()
Пример #7
0
 async def post(self, url, data):
     while self._srv_req_pending:
         await uasyncio.sleep_ms(50)
     machine.resetWDT()
     rsp = None
     result = None
     try:
         LOG.info("url: %s\ndata: %s" % (url, data))
         rsp = urequests.post(url, json=data)
         machine.resetWDT()
         if rsp.status_code != 200:
             self.log_exception(None, url, data, rsp.status_code)
             rsp.close()
             rsp = None
         self._srv_last_contact = utime.time()
     except Exception as exc:
         self.log_exception(exc, url, data)
     finally:
         self._srv_req_pending = False
         machine.resetWDT()
     if rsp:
         try:
             result = ujson.load(rsp.raw)
         except Exception as exc:
             LOG.exc(exc, 'Server response reading error')
             print(rsp.raw.read())
         finally:
             rsp.close()
             rsp = None
     LOG.info("return: %s" % result)
     return result
Пример #8
0
 async def srv_post(self, url, data, retry=False):
     if self.busy:
         return False
     data['device_id'] = self.id['id']
     data['token'] = self.id['token']
     manage_memory()
     machine.resetWDT()
     result = await self._http.post(self.server_uri + url, data)
     if retry:
         while not result:
             machine.resetWDT()
             result = await self._http.post(self.server_uri + url, data)
     machine.resetWDT()
     manage_memory()
     return result
Пример #9
0
def perform_software_update():
    global HTTP_CLIENT
    if not HTTP_CLIENT:
        HTTP_CLIENT = HttpClient()
    machine.WDT()
    manage_memory()
    version_data = load_version()
    device_type = get_device_type()
    srv_url = updates_url()
    srv_index = load_srv_json('index', srv_url=srv_url)
    machine.resetWDT()
    srv_versions = load_srv_json('devices', srv_url=srv_url)
    machine.resetWDT()
    if srv_index:
        for path, entry in srv_index.items():
            if 'devices_types' in entry and 'base' not in entry[
                    'devices_types'] and device_type not in entry[
                        'devices_types']:
                continue
            if path in version_data['files'] and version_data['files'][
                    path] == entry['hash']:
                continue
            local_path = entry['path'] if 'path' in entry else path
            print(local_path)
            ensure_file_path(local_path)
            file_url = srv_url + 'software/' + path
            print(file_url)
            while version_data['files'].get(path) != entry['hash']:
                if HTTP_CLIENT.get_to_file(file_url, 'file_buf'):
                    try:
                        uos.remove(local_path)
                    except OSError:
                        pass
                    uos.rename('file_buf', local_path)
                    if version_data['hash']:
                        version_data['hash'] = None
                    version_data['files'][path] = entry['hash']
                    save_version(version_data)
                    print('complete')
        machine.resetWDT()
        version_data['hash'] = srv_versions[device_type]
        version_data['update'] = False
        save_version(version_data)
    machine.reset()
Пример #10
0
async def wdt_feed():
    await uasyncio.sleep(10)
    machine.resetWDT()
Пример #11
0
    def __init__(self):
        self._conf = {}
        conf = load_json('conf.json')
        if conf:
            for conf_item in ('wlan_enabled_switch', 'gsm_modem'):
                if conf_item in conf:
                    self._conf[conf_item] = conf[conf_item]
        self._wlan = None
        self._wlan_enabled_switch = None
        self.gsm = False
        self._gsm_settings = {}
        enable_wlan = False
        if self._conf.get('wlan_enabled_switch'):
            self._wlan_enabled_switch = machine.Pin(
                self._conf['wlan_enabled_switch'],
                handler=wlan_enabled_switch_handler,
                trigger=machine.Pin.IRQ_FALLING)
            enable_wlan = self._wlan_enabled_switch.value()
            machine.RTC().wake_on_ext0(self._wlan_enabled_switch, 1)
        if not enable_wlan and self._conf.get('gsm_modem'):
            import gsm
            self._gsm_modem_on = None
            if self._conf['gsm_modem'].get('on'):
                self._gsm_modem_on = machine.Pin(self._conf['gsm_modem']['on'],
                                                 machine.Pin.OUT,
                                                 value=1)
            if self._conf['gsm_modem'].get('on_rev'):
                self._gsm_modem_on = machine.Pin(
                    self._conf['gsm_modem']['on_rev'],
                    machine.Pin.OUT,
                    value=0)
            self.gsm = True
            self._gsm_settings = load_json('gsm_settings.json') or {}
            gsm_apns = load_json('gsm_apns.json')
            apn_settings = {}

            self._gsm_pwr = machine.Pin(self._conf['gsm_modem']['pwr'], machine.Pin.INOUT, value=0)\
                if self._conf['gsm_modem'].get('pwr') else None
            if self._gsm_pwr:
                utime.sleep(2)


            self._gsm_rst = machine.Pin(self._conf['gsm_modem']['rst'], machine.Pin.OUT, value=1)\
                if self._conf['gsm_modem'].get('rst') else None

            self._gsm_pwr_key = machine.Pin(self._conf['gsm_modem']['pwr_key'], machine.Pin.OUT)\
                if self._conf['gsm_modem'].get('pwr_key') else None
            self.gsm_pwr_key_cycle()

            if not self._gsm_settings.get('network'):
                self.gsm_start({'apn': ''})
                machine.resetWDT()

                network_cmd = gsm.atcmd('AT+COPS?',
                                        timeout=1000,
                                        response='OK')
                network_name = [
                    key for key in gsm_apns.keys() if key in network_cmd
                ]
                if network_name:
                    self._gsm_settings['network'] = network_name[0]
                    save_json(self._gsm_settings, 'gsm_settings.json')
                    gsm.stop()
                else:
                    LOG.info('Network apn data not found. Trying empty apn.')

            if self._gsm_settings.get('network'):
                apn_settings = gsm_apns[self._gsm_settings['network']]

            if apn_settings:
                self.gsm_start(apn_settings)

            machine.resetWDT()
            self.gsm_connect()
            machine.resetWDT()
        else:
            self._wlan = WlanController()
Пример #12
0
    def write_object_stub(self,
                          fp,
                          object_expr: object,
                          obj_name: str,
                          indent: str,
                          in_class: int = 0):
        "Write a module/object stub to an open file. Can be called recursive."
        gc.collect()
        if object_expr in self.problematic:
            self._log.warning(
                "SKIPPING problematic module:{}".format(object_expr))
            return

        # self._log.debug("DUMP    : {}".format(object_expr))
        items, errors = self.get_obj_attributes(object_expr)

        if errors:
            self._log.error(errors)

        for item_name, item_repr, item_type_txt, item_instance in items:
            # name_, repr_(value), type as text, item_instance
            # do not create stubs for these primitives
            if item_name in [
                    "classmethod", "staticmethod", "BaseException", "Exception"
            ]:
                continue

            # allow the scheduler to run on LoBo based FW
            resetWDT()
            sleep_us(1)

            # Class expansion only on first 3 levels (bit of a hack)
            if item_type_txt == "<class 'type'>" and len(
                    indent) <= _MAX_CLASS_LEVEL * 4:
                self._log.debug("{0}class {1}:".format(indent, item_name))
                superclass = ""
                is_exception = item_name.endswith(
                    "Exception") or item_name.endswith("Error")
                if is_exception:
                    superclass = "Exception"
                s = "\n{}class {}({}):\n".format(indent, item_name, superclass)
                s += indent + "    ''\n"
                if not is_exception:
                    # Add __init__
                    s += indent + "    def __init__(self, *argv, **kwargs) -> None:\n"
                    s += indent + "        ''\n"
                    s += indent + "        ...\n"
                fp.write(s)
                # self._log.debug("\n" + s)

                self._log.debug("# recursion over class {0}".format(item_name))
                self.write_object_stub(
                    fp,
                    item_instance,
                    "{0}.{1}".format(obj_name, item_name),
                    indent + "    ",
                    in_class + 1,
                )
            # Class Methods and functions
            elif "method" in item_type_txt or "function" in item_type_txt or item_name == "__init__":
                self._log.debug(
                    "# def {1} function or method, type = '{0}'".format(
                        item_type_txt, item_name))
                # module Function or class method
                # will accept any number of params
                # return type Any
                ret = "Any"
                first = ""
                # Self parameter only on class methods/functions
                if in_class > 0:
                    first = "self, "
                    # __init__ returns None
                    if item_name == "__init__":
                        ret = "None"
                # class method - add function decoration
                if "bound_method" in item_type_txt or "bound_method" in item_repr:
                    s = "{}@classmethod\n".format(indent)
                    s += "{}def {}(cls, *args) -> {}:\n".format(
                        indent, item_name, ret)
                else:
                    s = "{}def {}({}*args) -> {}:\n".format(
                        indent, item_name, first, ret)
                # s += indent + "    ''\n" # EMPTY DOCSTRING
                s += indent + "    ...\n\n"
                fp.write(s)
                self._log.debug("\n" + s)
            # constants of known types & values
            elif item_type_txt == "<class 'module'>":
                # Skip imported modules
                # fp.write("# import {}\n".format(item_name))
                pass

            elif item_type_txt.startswith("<class '"):

                t = item_type_txt[8:-2]
                s = ""

                if t in ["str", "int", "float", "bool", "bytearray", "bytes"]:
                    # known type: use actual value
                    s = "{0}{1} = {2} # type: {3}\n".format(
                        indent, item_name, item_repr, t)
                elif t in ["dict", "list", "tuple"]:
                    # dict, list , tuple: use empty value
                    ev = {"dict": "{}", "list": "[]", "tuple": "()"}
                    s = "{0}{1} = {2} # type: {3}\n".format(
                        indent, item_name, ev[t], t)
                else:
                    # something else
                    if not t in ["object", "set", "frozenset"]:
                        # Possibly default others to item_instance object ?
                        # https://docs.python.org/3/tutorial/classes.html#item_instance-objects
                        t = "Any"
                    # Requires Python 3.6 syntax, which is OK for the stubs/pyi
                    s = "{0}{1} : {2} ## {3} = {4}\n".format(
                        indent, item_name, t, item_type_txt, item_repr)
                fp.write(s)
                self._log.debug("\n" + s)
            else:
                # keep only the name
                self._log.debug(
                    "# all other, type = '{0}'".format(item_type_txt))
                fp.write("# all other, type = '{0}'\n".format(item_type_txt))

                fp.write(indent + item_name + " # type: Any\n")

        del items
        del errors
        try:
            del item_name, item_repr, item_type_txt, item_instance  # pylint: disable=undefined-loop-variable
        except (OSError, KeyError,
                NameError):  # lgtm [py/unreachable-statement]
            pass
Пример #13
0
    def start(self):
        WDT(True)
        self.ntp_sync()
        if self.deepsleep():
            loop = uasyncio.get_event_loop()
            for module_type in self.modules:
                if module_type == 'rtc':
                    loop.run_until_complete(
                        self.modules['rtc'].adjust_time(once=True))
                    machine.resetWDT()
                elif module_type == 'climate':
                    loop.run_until_complete(
                        self.modules['climate'].read(once=True))
                    machine.resetWDT()
                    if self.online():
                        loop.run_until_complete(
                            self.post_sensor_data(once=True))
                        machine.resetWDT()
                    if self.modules['climate'].light:
                        loop.run_until_complete(
                            self.modules['climate'].adjust_light(once=True))
                        machine.resetWDT()
                if self.online():
                    if self.id.get('updates'):
                        loop.run_until_complete(self.check_updates(once=True))
                        machine.resetWDT()
                    if not self.id.get('disable_software_updates'):
                        loop.run_until_complete(
                            self.task_check_software_updates(once=True))
                        machine.resetWDT()
                if self.deepsleep():
                    if self._network:
                        self._network.off()
                    machine.deepsleep(self.deepsleep() * 60000)

        self.start_async()
Пример #14
0
    def __init__(self, network_controller):
        LOG.info("LenferDevice init")
        self._schedule = None
        self._network = network_controller
        self.mode = None
        self.status = {
            "wlan": None,
            "factory_reset": False,
            "wlan_switch": False,
            "ssid_failure": False,
            "ssid_delay": False,
            "srv_req_pending": False
        }
        self.log_queue = []
        self.busy = False
        self._conf = load_json('conf.json')
        self.settings = load_json('settings.json')
        self._http = HttpClient()
        if not self.settings:
            self.load_def_settings()
        if self.settings.get('mode'):
            self.mode = self.settings['mode']

        if self._conf.get('wlan_switch'):
            self._wlan_switch_button = Pin(self._conf['wlan_switch'],
                                           Pin.IN,
                                           Pin.PULL_UP,
                                           handler=self.wlan_switch_irq,
                                           trigger=Pin.IRQ_FALLING)

        if self._conf.get('factory_reset'):
            self._factory_reset_button = Pin(self._conf['factory_reset'],
                                             Pin.IN,
                                             handler=self.factory_reset_irq,
                                             trigger=Pin.IRQ_FALLING
                                             | Pin.IRQ_RISING)

        self.modules = {}
        self.i2c = [
            I2C(scl=Pin(i2c_conf['scl']), sda=Pin(i2c_conf['sda']))
            for i2c_conf in self._conf['i2c']
        ]
        LOG.info('I2C init')

        self.leds = {
            led: Pin(pin_no, Pin.OUT)
            for led, pin_no in self._conf['leds'].items()
        }
        self.id = load_json('id.json')
        if 'debug' in self.id and self.id['debug']:
            self.server_uri = SERVER_URI_DEV
        else:
            self.server_uri = SERVER_URI
        for led in self.leds.values():
            led.value(0)

        self.schedule = Schedule()
        manage_memory()
        machine.resetWDT()

        if 'rtc' in self._conf['modules'] and self.module_enabled(
                self._conf['modules']['rtc']):
            try:
                from timers import RtcController
                self.modules['rtc'] = RtcController(
                    self, self._conf['modules']['rtc'])
                self.modules['rtc'].get_time(set_rtc=True)
                LOG.info('RTC init')

            except Exception as exc:
                LOG.exc(exc, 'RTC initialization error')
            machine.resetWDT()
            manage_memory()
        if 'climate' in self._conf['modules'] and self.module_enabled(
                self._conf['modules']['climate']):
            try:
                from climate import ClimateController
                self.modules['climate'] = ClimateController(
                    self, self._conf['modules']['climate'])
                LOG.info('ClimateController init')

            except Exception as exc:
                LOG.exc(exc, 'Climate initialization error')
                if self._conf['modules']['climate'].get('obligatory'):
                    LOG.error(
                        'Obligatory module initialization fail -- machine reset'
                    )
                    machine.reset()
            machine.resetWDT()
            manage_memory()
        if 'power_monitor' in self._conf['modules'] and self.module_enabled(
                self._conf['modules']['power_monitor']):
            try:
                from power_monitor_controller import PowerMonitor
                self.modules['power_monitor'] = PowerMonitor(
                    self, self._conf['modules']['power_monitor'])
                LOG.info('PowerMonitor init')

            except Exception as exc:
                LOG.exc(exc, 'PowerMonitor initialization error')
                if self._conf['modules']['power_monitor'].get('obligatory'):
                    LOG.error(
                        'Obligatory module initialization fail -- machine reset'
                    )
                    machine.reset()
            machine.resetWDT()
            manage_memory()

        if 'feeder' in self._conf['modules'] and self.module_enabled(
                self._conf['modules']['feeder']):
            try:
                from feeder import FeederController
                self.modules['feeder'] = FeederController(
                    self, self._conf['modules']['feeder'])
                LOG.info('Feeder init')
            except Exception as exc:
                LOG.exc(exc, 'Feeder initialization error')
            machine.resetWDT()
            manage_memory()

        if 'gate' in self._conf['modules'] and self.module_enabled(
                self._conf['modules']['gate']):
            try:
                from gate_controller import GateController
                self.modules['gate'] = GateController(
                    self, self._conf['modules']['gate'])
                LOG.info('Gate init')
            except Exception as exc:
                LOG.exc(exc, 'Gate initialization error')
            machine.resetWDT()
            manage_memory()

        if 'relay_switch' in self._conf['modules'] and self.module_enabled(
                self._conf['modules']['relay_switch']):
            try:
                from relay_switch import RelaySwitchController
                self.modules['relay_switch'] = RelaySwitchController(
                    self, self._conf['modules']['relay_switch'])
                LOG.info('Relay init')
            except Exception as exc:
                LOG.exc(exc, 'RelaySwitch initialization error')
            machine.resetWDT()
            manage_memory()

        LOG.info(self.modules)