示例#1
0
    def __init__(self, dir: str, dev_eui: str):
        # The session file is written once when a the device registers successfully.
        self.SessionSFile = StructFile.StructFile(dir + '/session_' + dev_eui,
                                                  self.SESSION_DATA_FMT)
        # The frame count file is written whenever an uplink message is sent.
        self.FrameCountSFile = StructFile.StructFile(dir + '/fcnt_' + dev_eui,
                                                     self.FCNT_DATA_FMT)

        try:
            self.FrameCounter = self.FrameCountSFile.ReadData(0)[0]
            Log.info("FrameCounter: {}".format(self.FrameCounter))
        except TypeError:
            Log.info("No LoRaWAN framecounter present.")
            self.FrameCounter = 0

        try:
            self.DevAddr, self.AppSKey, self.NwkSKey = self.SessionSFile.ReadData(0)
            self.DevAddr = list(self.DevAddr)
            self.AppSKey = list(self.AppSKey)
            self.NwkSKey = list(self.NwkSKey)

            Log.info("LoRaWAN session info loaded.")
            Log.debug("NwSKey: {} | AppSKey: {} | DevAddr: {}".format(
                self.NwkSKey, self.AppSKey, self.DevAddr))
        except TypeError:
            self.FrameCounter = 0
            self.DevAddr = None
            self.AppSKey = None
            self.NwkSKey = None
            Log.info("No LoRaWAN session present.")
示例#2
0
    def __init__(self, file, data_fmt, capacity):
        Log.info(
            "Creating NvQueue with path: {}, capacity: {}, format: {}".format(
                file, capacity, data_fmt))
        self.Queue = StructFile.StructFile(file, data_fmt, NvQueue.META_FMT)

        meta = self.Queue.ReadMeta()
        # If no metadata is present in the queue file, reset the metadata and write
        # it to the file.
        if meta is None:
            Log.info("No metadata present, initializing queue.")
            self.Capacity = capacity
            self._MetaReset()
            self._MetaUpdate()
        else:
            Log.info("Existing metadata found.")
            Log.debug(str(meta))
            self.Capacity = meta[NvQueue.META_STRUCT_CAP]
            self.Count = meta[NvQueue.META_STRUCT_CNT]
            self.ReadOffset = meta[NvQueue.META_STRUCT_R_OFF]
            self.WriteOffset = meta[NvQueue.META_STRUCT_W_OFF]

            # If the read capacity differs from the capacity argument, update it.
            if self.Capacity is not capacity:
                Log.info("Capacity changed, updating metadata.")
                self.Capacity = capacity
                self._MetaUpdate()
示例#3
0
 def test_ConstructorWithUserMeta(self):
     user_meta_fmt = "<II"
     os.remove(test_StructFile.TEST_FILE)
     sf = StructFile.StructFile(test_StructFile.TEST_FILE,
                                test_StructFile.TEST_FMT, user_meta_fmt)
     self.assertEqual(sf.DataSize,
                      ustruct.calcsize(test_StructFile.TEST_FMT))
     file_exists = TestUtil.FileExists(test_StructFile.TEST_FILE)
     self.assertTrue(file_exists)
示例#4
0
    def test_WriteReadMeta(self):
        user_meta_fmt = "<HH"
        os.remove(test_StructFile.TEST_FILE)
        sf = StructFile.StructFile(test_StructFile.TEST_FILE,
                                   test_StructFile.TEST_FMT, user_meta_fmt)
        w_meta = (3, 4)

        sf.WriteMeta(*w_meta)
        r_meta = sf.ReadMeta()

        self.assertEqual(r_meta, w_meta)
示例#5
0
 def __init__(self, dir: str, prefix: str, file_limit: int):
     file_path = dir + self.COUNT_FILE_NAME
     self.SFile = StructFile.StructFile(file_path, self.COUNT_FILE_FMT)
     self.Last = 0
     self.First = 0
     self.LineCount = 0
     self.Max = file_limit
     self.Dir = dir
     self.Prefix = prefix
     self.File = None
     count_data = self.SFile.ReadData(0)
     if count_data is not None:
         self.Last = count_data[self.COUNT_DATA_LAST]
         self.First = count_data[self.COUNT_DATA_FIRST]
         self.LineCount = count_data[self.COUNT_DATA_LINES]
         print("[LogFileMngr] First: {} | Last: {} | LineCount: {}".format(
             self.Last, self.First, self.LineCount))
示例#6
0
 def test_ReadMetaNotAvailable(self):
     user_meta_fmt = "<HH"
     os.remove(test_StructFile.TEST_FILE)
     sf = StructFile.StructFile(test_StructFile.TEST_FILE,
                                test_StructFile.TEST_FMT, user_meta_fmt)
     self.assertEqual(sf.ReadMeta(), None)
示例#7
0
 def test_ReloadExistingFileAtConstruction(self):
     w_data = (1, 2)
     self.Sf.WriteData(0, *w_data)
     sf_copy = StructFile.StructFile(test_StructFile.TEST_FILE,
                                     test_StructFile.TEST_FMT)
示例#8
0
 def setUp(arg):
     test_StructFile.Sf = StructFile.StructFile(test_StructFile.TEST_FILE,
                                                test_StructFile.TEST_FMT)
示例#9
0
 def BeforeSleep():
     ExtLogging.Stop()
     StructFile.ResetLogger()
示例#10
0
    def Setup(self):

        for dir in self.DIR_TREE.values():
            try:
                uos.mkdir(dir)
            except OSError:
                print("Cannot create directory '{}'".format(dir))

        # Configure the ExtLogging class.
        ExtLogging.ConfigGlobal(level=ExtLogging.DEBUG,
                                stream=None,
                                dir=self.DIR_TREE[self.DIR_LOG],
                                file_prefix="log_",
                                line_limit=1000,
                                file_limit=10)

        StructFile.SetLogger(ExtLogging.Create("SFile"))

        self.Log = ExtLogging.Create("Main")

        self.Log.info("Device ID: {}".format(DeviceId.DeviceId()))

        Version(self.DIR_TREE[self.DIR_SYS], self.VER_MAJOR, self.VER_MINOR,
                self.VER_PATCH)

        rst_reason = ResetReason.ResetReason()
        self.Log.debug("Reset reason: {}".format(
            ResetReason.ResetReasonToString(rst_reason)))

        # Create driver instances.
        self.DummySensorDriver = DummySensor(self.DummySamples)

        self.InternalTemp = InternalTemp()

        # TODO: Enable actual sensor drivers.
        # self.TempSensorDriver = Mcp9700Temp(temp_pin_nr=Pins.CFG_HW_PIN_TEMP,
        #                                     en_supply_obj=Supply(Pins.CFG_HW_PIN_TEMP_EN, 3.3, 300))
        #
        # self.VBatSensorDriver = VoltageSensor(pin_nr=Pins.CFG_HW_PIN_VBAT_LVL,
        #                                       en_supply_obj=Supply(Pins.CFG_HW_PIN_VBAT_LVL_EN, 3.3, 300))

        if self.NETWORK is self.KPN:
            self.LoraProtocol = LoraProtocol(
                self.KpnLoraConfig, directory=self.DIR_TREE[self.DIR_LORA])
        elif self.NETWORK is self.TTN:
            self.LoraProtocol = LoraProtocol(
                self.TtnLoraConfig, directory=self.DIR_TREE[self.DIR_LORA])
            if self.NETWORK_REG is self.ABP:
                self.LoraProtocol.Params.StoreSession(self.DevAddr,
                                                      self.AppSKey,
                                                      self.NwkSKey)
        else:
            raise Exception("No valid network LoRa selected.")

        self.DummySensor = Sensor.Sensor(self.DIR_TREE[self.DIR_SENSOR],
                                         "Dummy",
                                         self.FILTER_DEPTH,
                                         self.DummySensorDriver,
                                         samples_per_update=3,
                                         dec_round=True,
                                         store_data=True)

        self.TempSensor = Sensor.Sensor(
            self.DIR_TREE[self.DIR_SENSOR],
            "Temp",
            self.FILTER_DEPTH,
            self.
            InternalTemp,  # TODO: Replace InternalTemp driver with TempSensorDriver
            samples_per_update=2,
            dec_round=True,
            store_data=True)

        # self.BatteryVoltageSensor = Sensor.Sensor(self.DIR_TREE[self.DIR_SENSOR],
        #                                           "BatLvl",
        #                                           self.FILTER_DEPTH,
        #                                           self.VBatSensorDriver,
        #                                           samples_per_update=2,
        #                                           dec_round=False,
        #                                           store_data=True)

        self.MsgEx = MessageExchange(directory=self.DIR_TREE[self.DIR_MSG],
                                     proto_obj=self.LoraProtocol,
                                     send_retries=self.RETRIES,
                                     msg_size_max=self.LoraProtocol.Mtu,
                                     msg_send_limit=self.SEND_LIMIT)

        # Create the registration info spec and Registration service.
        # Link the Registration service to the Message Exchange service. The Message Exchange
        # service will activate the Registration service when it connects to the LoRa network.
        self.RegistrationInfo = RegistrationInfo()
        self.Registration = Registration(self.MsgEx, self.RegistrationInfo)
        self.MsgEx.AttachConnectionStateObserver(self.Registration)

        self.Scheduler = ServiceScheduler(
            deepsleep_threshold_sec=self.DEEPSLEEP_THRESHOLD_SEC,
            # deep_sleep_obj=PowerManager.PowerManager(),
            directory=self.DIR_TREE[self.DIR_SYS])

        # Set service dependencies.
        # There are no hard dependencies between the services.

        # Register all services to the scheduler.
        self.Scheduler.ServiceRegister(self.DummySensor)
        self.Scheduler.ServiceRegister(self.TempSensor)
        # self.Scheduler.ServiceRegister(self.BatteryVoltageSensor)
        self.Scheduler.ServiceRegister(self.MsgEx)
        self.Scheduler.ServiceRegister(self.Registration)

        Message.SetParser(CborParser())
        MessageTemplate.SectionsSet(Metadata.MSG_SECTION_META,
                                    Metadata.MSG_SECTION_DATA)
        MessageTemplate.MetadataTemplateSet(Metadata.Metadata,
                                            Metadata.MetadataFuncs)

        # Create message specifications.
        self.MoistReport = MoistureSensorReport()
        self.BatteryReport = BatterySensorReport()
        self.TempReport = TemperatureSensorReport()

        # Create MessageFormatters and couple them with their message specs.
        moist_report_meta = {
            Metadata.MSG_META_TYPE: self.MoistReport.Type,
            Metadata.MSG_META_SUBTYPE: self.MoistReport.Subtype,
        }
        self.MoistFmt = MessageFormatter(self.MsgEx,
                                         MessageFormatter.SEND_ON_CHANGE,
                                         self.MoistReport, moist_report_meta)

        battery_report_meta = {
            Metadata.MSG_META_TYPE: self.BatteryReport.Type,
            Metadata.MSG_META_SUBTYPE: self.BatteryReport.Subtype,
        }
        self.BatteryFmt = MessageFormatter(self.MsgEx,
                                           MessageFormatter.SEND_ON_CHANGE,
                                           self.BatteryReport,
                                           battery_report_meta)

        temp_report_meta = {
            Metadata.MSG_META_TYPE: self.TempReport.Type,
            Metadata.MSG_META_SUBTYPE: self.TempReport.Subtype,
        }
        self.TempFmt = MessageFormatter(self.MsgEx,
                                        MessageFormatter.SEND_ON_CHANGE,
                                        self.TempReport, temp_report_meta)

        # Register message specs for exchange.
        self.MsgEx.RegisterMessageType(self.MoistReport)
        self.MsgEx.RegisterMessageType(self.BatteryReport)
        self.MsgEx.RegisterMessageType(self.TempReport)
        self.MsgEx.RegisterMessageType(self.RegistrationInfo)

        # Create observers for the sensor data.
        self.MoistObserver = self.MoistFmt.CreateObserver(
            MoistureSensorReport.DATA_KEY_MEASUREMENTS)
        self.BatteryObserver = self.BatteryFmt.CreateObserver(
            BatterySensorReport.DATA_KEY_MEASUREMENTS)
        self.TempObserver = self.TempFmt.CreateObserver(
            TemperatureSensorReport.DATA_KEY_MEASUREMENTS)

        # Link the observers to the sensors.
        self.DummySensor.ObserverAttachNewSample(self.MoistObserver)
        self.TempSensor.ObserverAttachNewSample(self.TempObserver)

        self.Scheduler.RegisterCallbackBeforeDeepSleep(MainApp.BeforeSleep)

        # Set intervals for all services.
        self.MsgEx.SvcIntervalSet(self.MsgExInterval)
        self.MsgEx.DefaultIntervalSet(self.MsgExInterval)
        self.DummySensor.SvcIntervalSet(self.MoistReadInterval)
        self.TempSensor.SvcIntervalSet(self.SensorReadInterval)

        # Activate the Message Exchange to attempt to connect to the LoRa network
        # if no LoRaWAN session exists yet.
        if self.LoraProtocol.HasSession() is False:
            self.MsgEx.SvcActivate()

        # self.BatteryObserver.Update(100)

        self.Log.info("Finished initialization.")