def test_PublishLogMessages(self): log_test_a = ["a", "info message a", "error message a"] log_test_b = ["b", "info message b", "error message b"] # Message definition msg_spec = LogMessage() # Create a Messaging Endpoint and a MessageFormatAdapter. ep = Endpoint() adapt = MessageFormatAdapter(ep, MessageFormatAdapter.SEND_ON_COMPLETE, msg_spec) # Create a stream for the msg field. log_stream = adapt.CreateStream(LogMessage.DATA_KEY_MSG, ExtLogging.WRITES_PER_LOG) # Configure the ExtLogging class. ExtLogging.ConfigGlobal(level=ExtLogging.INFO, stream=log_stream) # Create ExtLogger instances. log_a = ExtLogging.LoggerGet(log_test_a[0]) log_b = ExtLogging.LoggerGet(log_test_b[0]) # Register the log message type and topic. self.MsgEx.RegisterMessageType(msg_spec) # Initialize the Messaging Service on the first run self.MsgEx.SvcInit() log_a.info(log_test_a[1]) log_a.error(log_test_a[2]) log_b.info(log_test_b[1]) log_b.error(log_test_b[2]) # Run the Service again to publish the messages. self.MsgEx.SvcRun() utime.sleep(1) # Run the Service again to receive the message. self.MsgEx.SvcRun() # Receive both published log messages. recv_msg = ep.MessageGet(msg_spec.Type, msg_spec.Subtype) print("Received message: {}".format(recv_msg)) recv_msg = ep.MessageGet(msg_spec.Type, msg_spec.Subtype) print("Received message: {}".format(recv_msg))
def __init__(self, directory, proto_obj, send_retries, msg_size_max, msg_send_limit=5): if msg_size_max > proto_obj.Mtu: raise MessageExchangeExceptionMessageSize(msg_size_max, proto_obj.Mtu) # Initialize the MessageExchangeService class. super().__init__() # Configure the max size of a single message. Determines buffer sizes. MessageTemplate.Configure(msg_size_max) # Configure the MessageBuffer and Message classes. MessageBuffer.Configure(directory) # Create a generic send buffer for all outgoing messages. self.SendMessageBuffer = MessageBuffer( 'send', -1, -1, MessageExchange.SEND_BUFFER_SIZE) self.MessageMappings = set() self.Protocol = proto_obj self.SendRetries = send_retries self.SendLimit = msg_send_limit self.ConnectionState = Subject() self.ConnectionState.State = False self.ServiceInit = False self.NewMessage = False # Set to True by the receive callback on a received message. self.Log = ExtLogging.Create("MsgEx") MessageExchange._Instance = self
def test_LoggingToFileMaxLines(self): file = "extlog" name = "test" text = "hi" file_limit = 2 line_limit = 10 ExtLogging.ConfigGlobal(level=ExtLogging.INFO, stream=TestStream(), dir=self.DIR, file_prefix=file, line_limit=line_limit, file_limit=file_limit, print_enabled=True, timestamp_enabled=True) log = ExtLogging.Create(name) print(log) for f in range(0, file_limit): for l in range(0, line_limit): log.info(text + str(l)) ExtLogging.Mngr.PrintList() file_list = ExtLogging.Mngr.List() print(file_list) count = ExtLogging.Mngr.Count() self.assertEqual(count, file_limit) for i in range(0, count): print("[UT] Checking file: {}".format(file_list[i])) f = open(file_list[i], 'r') for l in range(0, line_limit): exc_occurred = False try: line = f.readline() print("[UT] Read line: {}".format(line)) except OSError: exc_occurred = True self.assertFalse(exc_occurred) self.assertTrue(text in line) self.assertTrue(name in line) self.assertTrue("[" in line) f.close()
class Message: Msg = None _StreamBuffer = None _Parser = None Log = ExtLogging.Create("Msg") @staticmethod def SetParser(parser_obj): Message._Parser = parser_obj Message.Log.debug("Parser set: {}".format(Message._Parser)) @staticmethod def Message(): return Message.Msg @staticmethod def Stream(): return Message._StreamBuffer @staticmethod def Serialize(data_dict, meta_dict=None): # Create a message from the template. Message.Msg = MessageTemplate() Message.Msg = Message.Msg.Msg Message.Log.debug( "Serializing message with metadata: {} | data: {}".format( meta_dict, data_dict)) # Close the previous stream if there is one. if Message._StreamBuffer is not None: Message._StreamBuffer.close() Message._StreamBuffer = uio.BytesIO(MessageTemplate.MsgSizeMax) # If metadata was given, check for matching keys and copy the values. if meta_dict is not None: for key in Message.Msg[MessageTemplate.MSG_SECTION_META].keys(): if key in meta_dict.keys(): Message.Msg[ MessageTemplate.MSG_SECTION_META][key] = meta_dict[key] # Copy the data dictionary. Message.Msg[MessageTemplate.MSG_SECTION_DATA] = data_dict # Serialize the message using the parser. Message._Parser.Dumps(Message.Msg, Message._StreamBuffer) return Message._StreamBuffer @staticmethod def Deserialize(msg_str): try: Message.Msg = Message._Parser.Loads(msg_str) except ValueError: Message.Log.error("Invalid format: {}".format(msg_str)) return Message.Msg @staticmethod def Print(): Message.Log.info(Message.Msg)
def __init__(self, msg_ex_obj, reg_info_spec): """ Registration object, implements the RegistrationService and Observer classes. :param msg_ex_obj: MessageExchange object :type msg_ex_obj: <MessageExchange> :param reg_info_spec: Registration info specification :type reg_info_spec: <<MessageSpecification>RegistrationInfo> """ super().__init__() self.MsgEx = msg_ex_obj self.RegInfoSpec = reg_info_spec self.Version = Version.Instance() self.Log = ExtLogging.Create("Reg") return
def __init__(self, directory: str, name: str, filter_depth: int, sensor_driver_obj, samples_per_update: int = 1, dec_round: bool = True, store_data: bool = True): """ :param directory: :type directory: :param name: :type name: :param filter_depth: :type filter_depth: :param sensor_driver_obj: :type sensor_driver_obj: :param samples_per_update: :type samples_per_update: :param dec_round: :type dec_round: :param store_data: :type store_data: """ if samples_per_update > 1 and store_data is False: raise SensorExceptionInvalidConfig( "store_data must be True if samples_per_update > 1") # Initialize the SensorService class super().__init__(name) self.SensorDriver = sensor_driver_obj self.SamplesPerUpdate = samples_per_update self.Filter = AvgFilter.AvgFilter(filter_depth, dec_round) if store_data is True: self.SampleQueue = NvQueue.NvQueue(directory + '/' + name, Sensor.SAMPLE_FMT, Sensor.FILE_SAMPLES_MAX) self.NewSample = Subject() self.NewSample.State = list() self.StoreData = store_data self.Log = ExtLogging.Create("Sensor-{}".format(name))
def SetupScanMode(self): self.Notifyer = Notifyer(self.RgbLed) # Set service dependencies. self.Time.SvcDependencies( {self.NetCon: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_RUN}) self.MoistSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) self.Notifyer.SvcDependencies( {self.MoistSensor: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_RUN}) self.TempSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) self.LightSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) self.MsgEx.SvcDependencies({ self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN, self.NetCon: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_INIT, self.TempSensor: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN, self.LightSensor: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN }) # Register all services to the scheduler. self.Scheduler.ServiceRegister(self.Time) self.Scheduler.ServiceRegister(self.NetCon) self.Scheduler.ServiceRegister(self.MsgEx) self.Scheduler.ServiceRegister(self.MoistSensor) self.Scheduler.ServiceRegister(self.Notifyer) self.Scheduler.ServiceRegister(self.LightSensor) self.Scheduler.ServiceRegister(self.TempSensor) # Create message specifications. self.TempMsgSpec = SensorReportTemp() self.MoistMsgSpec = SensorReportMoist() self.LightMsgSpec = SensorReportLight() self.LogMsgSpec = LogMessage() # Create MessageFormatAdapters and couple them with their message specs. self.TempAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.TempMsgSpec) self.MoistAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.MoistMsgSpec) self.LightAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.LightMsgSpec) self.LogAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.LogMsgSpec) # Register message specs for exchange. self.MsgEx.RegisterMessageType(self.TempMsgSpec) self.MsgEx.RegisterMessageType(self.MoistMsgSpec) self.MsgEx.RegisterMessageType(self.LightMsgSpec) self.MsgEx.RegisterMessageType(self.LogMsgSpec) # Create observers for the sensor data. self.TempObserver = self.TempAdapt.CreateObserver( SensorReportTemp.DATA_KEY_SENSOR_REPORT_SAMPLES, self.SamplesPerMessage) self.MoistObserver = self.MoistAdapt.CreateObserver( SensorReportMoist.DATA_KEY_SENSOR_REPORT_SAMPLES, self.SamplesPerMessage) self.LightObserver = self.LightAdapt.CreateObserver( SensorReportLight.DATA_KEY_SENSOR_REPORT_SAMPLES, self.SamplesPerMessage) # Set the notification ranges and colors. moist_th_range = NotificationRange(self.MOIST_RANGE_MIN, self.MOIST_RANGE_MAX) moist_color_map = { RgbLed.RGB_COLOR_RED: NotificationRange(self.MOIST_RANGE_MAX, self.MOIST_RANGE_MIN), RgbLed.RGB_COLOR_BLUE: NotificationRange(self.MOIST_RANGE_MIN, self.MOIST_RANGE_MAX) } self.MoistNotif = Notification(moist_th_range, moist_color_map, self.MOIST_NOTIF_PRIO, self.MOIST_NOTIF_TIME) self.Notifyer.NotificationRegister(self.MoistNotif) # Link the observers to the sensors. self.TempSensor.ObserverAttachNewSample(self.TempObserver) self.MoistSensor.ObserverAttachNewSample(self.MoistObserver) self.MoistSensor.ObserverAttachNewSample(self.MoistNotif) self.LightSensor.ObserverAttachNewSample(self.LightObserver) # Create a stream for the log messages. self.LogStream = self.LogAdapt.CreateStream( LogMessage.DATA_KEY_LOG_MSG, ExtLogging.WRITES_PER_LOG) # Configure the ExtLogging class. ExtLogging.ConfigGlobal(level=ExtLogging.INFO, stream=self.LogStream) # Set service modes. self.MsgEx.SvcMode = Service.MODE_RUN_ONCE self.TempSensor.SvcMode = Service.MODE_RUN_ONCE self.LightSensor.SvcMode = Service.MODE_RUN_ONCE # Set intervals for periodic services. self.MoistSensor.SvcIntervalSet(self.MoistSensorReadInterval) self.Notifyer.SvcIntervalSet(self.NotificationInterval)
def SetupCalibMode(self): # Set service dependencies. self.Time.SvcDependencies( {self.NetCon: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_RUN}) self.MsgEx.SvcDependencies({ self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN, self.NetCon: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_INIT }) self.MoistSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) # Register all services to the scheduler. self.Scheduler.ServiceRegister(self.Time) self.Scheduler.ServiceRegister(self.NetCon) self.Scheduler.ServiceRegister(self.MsgEx) self.Scheduler.ServiceRegister(self.MoistSensor) # Create message specifications. self.MoistCalibLowMsgSpec = SensorReportMoistCalibLow() self.MoistCalibHighMsgSpec = SensorReportMoistCalibHigh() self.LogMsgSpec = LogMessage() # Create MessageFormatAdapters and couple them with their message specs. self.MoistCalibLowAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.MoistCalibLowMsgSpec) self.MoistCalibHighAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.MoistCalibHighMsgSpec) self.LogAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.LogMsgSpec) # Register message specs for exchange. self.MsgEx.RegisterMessageType(self.MoistCalibLowMsgSpec) self.MsgEx.RegisterMessageType(self.MoistCalibHighMsgSpec) self.MsgEx.RegisterMessageType(self.LogMsgSpec) self.CalibObserver = CalibrationObserver() self.CalibLowStream = self.MoistCalibLowAdapt.CreateStream( SensorReportMoistCalibLow.DATA_KEY_SENSOR_REPORT_SAMPLES, self.SamplesPerMessage) self.CalibHighStream = self.MoistCalibHighAdapt.CreateStream( SensorReportMoistCalibHigh.DATA_KEY_SENSOR_REPORT_SAMPLES, self.SamplesPerMessage) # Link the observers to the sensors. self.MoistSensor.ObserverAttachNewSample(self.CalibObserver) # Create a stream for the log messages. self.LogStream = self.LogAdapt.CreateStream( LogMessage.DATA_KEY_LOG_MSG, ExtLogging.WRITES_PER_LOG) # Configure the ExtLogging class. ExtLogging.ConfigGlobal(level=ExtLogging.INFO, stream=self.LogStream) # Set service modes. self.MsgEx.SvcMode = Service.MODE_RUN_ONCE # Set intervals for periodic services. self.MoistSensor.SvcIntervalSet(self.MoistSensorReadInterval) return
from upyiot.comm.Messaging.Protocol.MessagingProtocol import MessagingProtocol from upyiot.comm.Messaging.MessageExchange import MessageExchange from upyiot.system.ExtLogging import ExtLogging from micropython import const import urequests Log = ExtLogging.Create("HttpProto") class HttpProtocol(MessagingProtocol): HTTP_MTU = const(1400) _Instance = None def __init__(self): super().__init__(None, self.HTTP_MTU) HttpProtocol._Instance = self return def Setup(self, recv_callback, msg_mappings): MessagingProtocol.Setup(self, recv_callback, msg_mappings) return def Send(self, msg_map, payload, size): route = msg_map[MessageExchange.MSG_MAP_ROUTING] decoded = payload.decode("utf-8") print(type(payload), type(decoded)) Log.info("POST to {}: {}".format(route, decoded)) headers = { 'Content-type': 'application/json',
def setUp(self): # Configure the URL fields. MessageSpecification.Config(self.UrlFields) # Create objects. filter_depth = len(self.TempSamples) / 2 dummy_temp_sensor = DummySensor.DummySensor(self.TempSamples) dummy_moist_sensor = DummySensor.DummySensor(self.MoistSamples) wlan_ap = WLAN() self.Time = SystemTime.InstanceGet() self.NetCon = NetCon(self.DIR, self.ApCfg, NetCon.MODE_STATION, wlan_ap) self.TempSensor = Sensor.Sensor(self.DIR, SensorReportTemp.NAME_TEMP, filter_depth, dummy_temp_sensor) self.MoistSensor = Sensor.Sensor(self.DIR, SensorReportMoist.NAME_MOIST, filter_depth, dummy_moist_sensor) self.MqttClient = MQTTClient(self.ID, self.BROKER, self.PORT) self.MsgEx = MessageExchange(self.DIR, self.MqttClient, self.ID, self.RETRIES) self.MsgEp = Endpoint() self.Scheduler = ServiceScheduler() # Set service dependencies. self.Time.SvcDependencies( {self.NetCon: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_RUN}) self.MsgEx.SvcDependencies({ self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN, self.NetCon: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_INIT }) self.TempSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) self.MoistSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) # Register all services to the scheduler. self.Scheduler.ServiceRegister(self.Time) self.Scheduler.ServiceRegister(self.NetCon) self.Scheduler.ServiceRegister(self.MsgEx) self.Scheduler.ServiceRegister(self.TempSensor) self.Scheduler.ServiceRegister(self.MoistSensor) # Create message specifications. self.TempMsgSpec = SensorReportTemp() self.MoistMsgSpec = SensorReportMoist() self.LogMsgSpec = LogMessage() # Create a Messaging Endpoint and MessageFormatAdapters. self.TempAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.TempMsgSpec) self.MoistAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.MoistMsgSpec) self.LogAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.LogMsgSpec) # Register message specs. self.MsgEx.RegisterMessageType(self.TempMsgSpec) self.MsgEx.RegisterMessageType(self.MoistMsgSpec) self.MsgEx.RegisterMessageType(self.LogMsgSpec) # Create observers for the sensor data. self.TempObserver = self.TempAdapt.CreateObserver( SensorReportTemp.DATA_KEY_SENSOR_REPORT_ARRAY, self.SamplesPerMessage) self.MoistObserver = self.MoistAdapt.CreateObserver( SensorReportMoist.DATA_KEY_SENSOR_REPORT_ARRAY, self.SamplesPerMessage) # Link the observers to the sensors. self.TempSensor.ObserverAttachNewSample(self.TempObserver) self.MoistSensor.ObserverAttachNewSample(self.MoistObserver) # Create a stream for the log messages. self.LogStream = self.LogAdapt.CreateStream( LogMessage.DATA_KEY_LOG_MSG, ExtLogging.WRITES_PER_LOG) # Configure the ExtLogging class. ExtLogging.ConfigGlobal(level=ExtLogging.INFO, stream=self.LogStream) # Configure the station settings to connect to a WLAN AP. self.NetCon.StationSettingsStore(self.ApCfg["ssid"], self.ApCfg["pwd"]) # Declare test variables. self.RecvMsgCount = 0 self.RecvTopic = None self.RecvMsg = None
def BeforeSleep(): ExtLogging.Stop() StructFile.ResetLogger()
from upyiot.middleware.NvQueue import NvQueue from upyiot.system.ExtLogging import ExtLogging from upyiot.comm.Messaging.MessageTemplate import MessageTemplate Log = ExtLogging.Create("MsgBuf") class MessageBuffer: MSG_STRUCT_TYPE = const(0) MSG_STRUCT_SUBTYPE = const(1) MSG_STRUCT_LEN = const(2) MSG_STRUCT_DATA = const(3) MsgDataLen = 0 MsgStructFmt = "" Directory = "" _UnPackBuffer = None Configured = False @staticmethod def Configure(directory): MessageBuffer.MsgDataLen = MessageTemplate.MsgSizeMax MessageBuffer.MsgStructFmt = "<iiI" + \ str(MessageBuffer.MsgDataLen) + "s" Log.debug("FMT: {}".format(MessageBuffer.MsgStructFmt)) MessageBuffer.Directory = directory + "/" Log.debug(directory) # MessageBuffer._UnPackBuffer = bytearray(msg_len_max + msg_len_max) MessageBuffer.Configured = True
def Setup(self): # Create driver instances. self.CapMoist = CapMoisture(Pins.CFG_HW_PIN_MOIST, Pins.CFG_HW_PIN_MOIST_EN) self.Mcp9700Temp = Mcp9700Temp(Pins.CFG_HW_PIN_TEMP, Pins.CFG_HW_PIN_TEMP_EN) self.Ldr = PhTLight(Pins.CFG_HW_PIN_LDR, Pins.CFG_HW_PIN_LDR_EN) # self.VBat = BatteryLevel(1, Pins.CFG_HW_PIN_VBAT_MEAS, Pins.CFG_HW_PIN_VBAT_MEAS_EN) self.RgbLed = RgbLed(Pins.CFG_HW_PIN_LED_RED, Pins.CFG_HW_PIN_LED_GREEN, Pins.CFG_HW_PIN_LED_BLUE) self.Button = UserButton(Pins.CFG_HW_PIN_BTN_0) # Create the WLAN station interface. wlan_ap = WLAN(network.STA_IF) self.Time = SystemTime.InstanceGet() self.NetCon.WlanInterface(wlan_ap, NetCon.MODE_STATION) self.TempSensor = Sensor.Sensor(self.DIR, SensorReportTemp.NAME_TEMP, self.FILTER_DEPTH, self.Mcp9700Temp, self.FILTER_DEPTH) self.MoistSensor = Sensor.Sensor(self.DIR, SensorReportMoist.NAME_MOIST, self.FILTER_DEPTH, self.CapMoist, self.FILTER_DEPTH) self.LightSensor = Sensor.Sensor(self.DIR, SensorReportLight.NAME_LIGHT, self.FILTER_DEPTH, self.PhTLight, self.FILTER_DEPTH) self.MqttClient = MQTTClient(self.ID, self.BROKER, self.PORT) self.MsgEx = MessageExchange(self.DIR, self.MqttClient, self.ID, self.RETRIES) self.Notifyer = Notifyer(self.RgbLed) self.MsgEp = Endpoint() self.Scheduler = ServiceScheduler(self.DEEPSLEEP_THRESHOLD_SEC) # Set service dependencies. self.Time.SvcDependencies( {self.NetCon: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_RUN}) self.MsgEx.SvcDependencies({ self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN, self.NetCon: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_INIT }) self.TempSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) self.MoistSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) self.LightSensor.SvcDependencies( {self.Time: Service.DEP_TYPE_RUN_ONCE_BEFORE_RUN}) self.Notifyer.SvcDependencies( {self.MoistSensor: Service.DEP_TYPE_RUN_ALWAYS_BEFORE_RUN}) # Register all services to the scheduler. self.Scheduler.ServiceRegister(self.Time) self.Scheduler.ServiceRegister(self.NetCon) self.Scheduler.ServiceRegister(self.MsgEx) self.Scheduler.ServiceRegister(self.TempSensor) self.Scheduler.ServiceRegister(self.MoistSensor) self.Scheduler.ServiceRegister(self.LightSensor) self.Scheduler.ServiceRegister(self.Notifyer) # Create message specifications. self.TempMsgSpec = SensorReportTemp() self.MoistMsgSpec = SensorReportMoist() self.LightMsgSpec = SensorReportLight() self.LogMsgSpec = LogMessage() # Create MessageFormatAdapters and couple them with their message specs. # self.TempAdapt = MessageFormatAdapter(self.MsgEp, # MessageFormatAdapter.SEND_ON_COMPLETE, # self.TempMsgSpec) self.MoistAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.MoistMsgSpec) self.LightAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.LightMsgSpec) self.LogAdapt = MessageFormatAdapter( self.MsgEp, MessageFormatAdapter.SEND_ON_COMPLETE, self.LogMsgSpec) # Register message specs for exchange. # self.MsgEx.RegisterMessageType(self.TempMsgSpec) self.MsgEx.RegisterMessageType(self.MoistMsgSpec) self.MsgEx.RegisterMessageType(self.LightMsgSpec) self.MsgEx.RegisterMessageType(self.LogMsgSpec) # Create observers for the sensor data. self.TempObserver = self.TempAdapt.CreateObserver( SensorReportTemp.DATA_KEY_SENSOR_REPORT_SAMPLES, self.SamplesPerMessage) self.MoistObserver = self.MoistAdapt.CreateObserver( SensorReportMoist.DATA_KEY_SENSOR_REPORT_SAMPLES, self.SamplesPerMessage) self.LightObserver = self.LightAdapt.CreateObserver( SensorReportLight.DATA_KEY_SENSOR_REPORT_SAMPLES, self.SamplesPerMessage) # Set the notification ranges and colors. moist_th_range = NotificationRange(self.MOIST_RANGE_MIN, self.MOIST_RANGE_MAX) moist_color_map = { RgbLed.RGB_COLOR_RED: NotificationRange(self.MOIST_RANGE_MAX, self.MOIST_RANGE_MIN), RgbLed.RGB_COLOR_BLUE: NotificationRange(self.MOIST_RANGE_MIN, self.MOIST_RANGE_MAX) } self.MoistNotif = Notification(moist_th_range, moist_color_map, self.MOIST_NOTIF_PRIO, self.MOIST_NOTIF_TIME) self.Notifyer.NotificationRegister(self.MoistNotif) # Link the observers to the sensors. self.TempSensor.ObserverAttachNewSample(self.TempObserver) self.MoistSensor.ObserverAttachNewSample(self.MoistObserver) self.MoistSensor.ObserverAttachNewSample(self.MoistNotif) self.LightSensor.ObserverAttachNewSample(self.LightObserver) # Create a stream for the log messages. self.LogStream = self.LogAdapt.CreateStream( LogMessage.DATA_KEY_LOG_MSG, ExtLogging.WRITES_PER_LOG) # Configure the ExtLogging class. ExtLogging.ConfigGlobal(level=ExtLogging.INFO, stream=self.LogStream) # Set intervals for all services. self.MsgEx.SvcIntervalSet(self.MsgExInterval) self.MoistSensor.SvcIntervalSet(self.EnvSensorReadInterval) self.TempSensor.SvcIntervalSet(self.EnvSensorReadInterval) self.LightSensor.SvcIntervalSet(self.EnvSensorReadInterval) self.Notifyer.SvcIntervalSet(self.NotificationInterval)
from micropython import const from upyiot.middleware.SubjectObserver.SubjectObserver import Observer from upyiot.system.ExtLogging import ExtLogging Log = ExtLogging.Create("MsgFmt") class MessagePartSource: def __init__(self, msg_formatter_obj, key, complete_count): self.MsgFormatter = msg_formatter_obj self.Key = key self.Count = 0 self.CompleteCount = complete_count def Put(self, data): if self.Count is 0: self.MsgFormatter.MessagePartAdd(self.Key, data) else: self.MsgFormatter.MessagePartAppend(self.Key, data) self._CountInc() def _CountInc(self): self.Count += 1 if self.Count is self.CompleteCount: self.Count = 0 self.MsgFormatter.MessagePartFinalize() class MessagePartSink: def __init__(self, msg_formatter_obj, key, complete_count): self.MsgFormatter = msg_formatter_obj
def tearDown(arg): try: ExtLogging.Clear() except: pass return
from upyiot.middleware.StructFile import StructFile from micropython import const from upyiot.system.ExtLogging import ExtLogging Log = ExtLogging.Create("NvQueue") class NvQueueIterator(object): def __init__(self, nvqueue_obj): print(nvqueue_obj) nvqueue_obj.Queue.IteratorConfig(nvqueue_obj.ReadOffset, nvqueue_obj.WriteOffset, nvqueue_obj.Count) self.Iterator = iter(nvqueue_obj.Queue) def __next__(self): return self.Iterator.__next__() class NvQueue: # Capacity, count, read offset, write offset. META_FMT = "<HHHH" META_STRUCT_CAP = const(0) META_STRUCT_CNT = const(1) META_STRUCT_R_OFF = const(2) META_STRUCT_W_OFF = const(3) def __init__(self, file, data_fmt, capacity): Log.info( "Creating NvQueue with path: {}, capacity: {}, format: {}".format(
def __init__( self, spi, pins, ttn_config, channel=0, # compatibility with Dragino LG02, set to None otherwise fport=1, lora_parameters=_default_parameters): self._spi = spi self._pins = pins self._parameters = lora_parameters self._lock = False self._log = ExtLogging.Create("SX127x") # setting pins if "dio_0" in self._pins: self._pin_rx_done = Pin(self._pins["dio_0"], Pin.IN) self._irq = Pin(self._pins["dio_0"], Pin.IN) if "ss" in self._pins: self._pin_ss = Pin(self._pins["ss"], Pin.OUT) if "led" in self._pins: self._led_status = Pin(self._pins["led"], Pin.OUT) # check hardware version init_try = True re_try = 0 while init_try and re_try < 5: version = self.read_register(REG_VERSION) re_try = re_try + 1 self._log.info("SX version: {}".format(version)) if version == 0x12: init_try = False else: utime.sleep_ms(1000) if version != 0x12: raise Exception('Invalid version.') # Set frequency registers self._rfm_msb = None self._rfm_mid = None self._rfm_lsb = None # init framecounter self.frame_counter = 0 self._fport = fport # Set datarate registers self._sf = None self._bw = None self._modemcfg = None # ttn configuration if "US" in ttn_config.country: from ttn.ttn_usa import TTN_FREQS self._frequencies = TTN_FREQS elif ttn_config.country == "AS": from ttn.ttn_as import TTN_FREQS self._frequencies = TTN_FREQS elif ttn_config.country == "AU": from ttn.ttn_au import TTN_FREQS self._frequencies = TTN_FREQS elif ttn_config.country == "EU": from ttn.ttn_eu import TTN_FREQS self._frequencies = TTN_FREQS else: raise TypeError("Country Code Incorrect/Unsupported") # Give the uLoRa object ttn configuration self._ttn_config = ttn_config # put in LoRa and sleep mode self.sleep() # set channel number self._channel = channel self._actual_channel = channel if self._channel is not None: self.set_frequency(self._channel) # set data rate and bandwidth self.set_bandwidth(self._parameters["signal_bandwidth"]) # set LNA boost self.write_register(REG_LNA, self.read_register(REG_LNA) | 0x03) # set auto AGC self.write_register(REG_MODEM_CONFIG, 0x04) self.implicit_header_mode(self._parameters['implicit_header']) self.set_tx_power(self._parameters['tx_power_level']) self.set_coding_rate(self._parameters['coding_rate']) self.set_sync_word(self._parameters['sync_word']) self.enable_CRC(self._parameters['enable_CRC']) #self.invert_IQ(self._parameters["invert_IQ"]) self.set_preamble_length(self._parameters['preamble_length']) self.set_spreading_factor(self._parameters['spreading_factor']) # set LowDataRateOptimize flag if symbol time > 16ms (default disable on reset) # self.write_register(REG_MODEM_CONFIG, self.read_register(REG_MODEM_CONFIG) & 0xF7) # default disable on reset #bw_parameter = self._parameters["signal_bandwidth"] #sf_parameter = self._parameters["spreading_factor"] #if 1000 / (bw_parameter / 2**sf_parameter) > 16: # self.write_register( # REG_MODEM_CONFIG, # self.read_register(REG_MODEM_CONFIG) | 0x08 # ) # set base addresses self.write_register(REG_FIFO_TX_BASE_ADDR, FifoTxBaseAddr) self.write_register(REG_FIFO_RX_BASE_ADDR, FifoRxBaseAddr) self.standby()
from upyiot.comm.Messaging.Protocol.MessagingProtocol import MessagingProtocol from upyiot.comm.Messaging.MessageExchange import MessageExchange from upyiot.comm.Network import LoRaWAN from upyiot.comm.Network.LoRaWAN.MHDR import MHDR from upyiot.middleware.StructFile import StructFile from upyiot.drivers.Modems.SX127x.LoRa import * from upyiot.drivers.Modems.SX127x.board_config import BOARD from upyiot.system.ExtLogging import ExtLogging from time import sleep from random import randrange import machine from micropython import const Log = ExtLogging.Create("LoraProto") ADDR_SIZE = const(4) EUI_SIZE = const(8) KEY_SIZE = const(16) TX_TIMEOUT_SEC = const(10) RX_TIMEOUT_SEC = const(30) TIMEOUT_POLL_SEC = const(1) class LoRaWANParams: SESSION_DATA_FMT = "<4s16s16s" # DevAddr, AppSKey, NwkSKey FCNT_DATA_FMT = "<I" def __init__(self, dir: str, dev_eui: str):
from upyiot.system.Service.Service import Service from upyiot.system.Service.Service import ServiceExceptionSuspend from upyiot.system.Service.Service import ServiceException from upyiot.middleware.StructFile.StructFile import StructFile from upyiot.system.ExtLogging import ExtLogging import utime from micropython import const Log = ExtLogging.Create("Scheduler") class SchedulerException(Exception): def __init__(self): return class SchedulerExceptionStopped(SchedulerException): def __init__(self): return class SchedulerExceptionDeepSleepFailed(SchedulerException): def __init__(self): return class SchedulerMemory: FILE_SCHEDULER_MEMORY = "/sched_mem" SVC_NAME_LEN = const(20)
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.")