Make Your Own Sensor Driver
Using the Data Logger Application provided by Observator you can easily integrate your own sensor (driver). Please study the manual on how to use the OMC-048 Data Logger Application before you start integrating your own sensor driver.
Creating a .py driver file
Create a new .py file and place this in the scriptmodules folder of your OMC-048 data logger. In this example we create the file ‘simple_driver.py’ but you are free to choose any name you like, as long as there are no duplicate names.
Now paste the following code in your driver file:
1from sensor_drv import SensorDrv
2
3class simple_driver(SensorDrv):
4
5 def __init__(self, serial, conf):
6 SensorDrv.__init__(self)
7
8 async def read_values(self):
9 self.data = [0]
10 return True
11
12 async def detect_parameters(self, tag_number = ''):
13 self.parameters = [('parameter', '', 'TAG{}'.format(tag_number))]
14 return True
15
16 async def flush(self):
17 pass
Important
The class name (line 3) must be identical to the .py file name!
Add your own driver code
In this example we are simulating a sensor which transmits data over RS422 on serial port 1 on 1 Hz interval.
serial port 1
9600 baud, 8N1
The string transmitted by the sensor is:
Temp=20.34,Hum=56.4,Status=OK\r\n
In our example we want to capture three fields of data: Temperature
, Humidity
and Status
We start by adding the parameters to the driver: name, unit and unique tag. We must also provide 3 value’s to ‘self.data’ in the ‘read_values’ function, corresponding to the given parameters. For now we just enter the decimal values 1, 2 and 3.
1from sensor_drv import SensorDrv
2
3class simple_driver(SensorDrv):
4
5 def __init__(self, serial, conf):
6 SensorDrv.__init__(self)
7
8 async def read_values(self):
9 self.data = [1,2,3]
10 return True
11
12 async def detect_parameters(self, tag_number = ''):
13 self.parameters = [ ('Temperature', '', 'TMP{}'.format(tag_number)),
14 ('Humidity', '', 'HUM{}'.format(tag_number)),
15 ('Status', '', 'STS{}'.format(tag_number)) ]
16 return True
17
18 async def flush(self):
19 pass
Test your driver
The base for our sensor driver is now provided, we can already test it by adding our sensor driver to the config.txt The entire config is displayed below, note the ‘simple_driver’ for our example.
# ----System---- #
Omc048:
system_id: PROTO_1
application: PROTO_1
file_log_level: info
repl_log_level: info
utc_time_offset_hours: +0
utc_time_offset_minutes: +0
sensor_data_print: True
usb_mode: debug
self_test: False
simple_driver:
- id: simple_1
sample_interval: "* * * * *"
port: serial1
mode: RS422
baudrate: 9600
# ----Data-log-settings---- #
Data_file:
- id: data
create_interval: "0 0,5,10,15,20,25,30,35,40,45,50,55 * * *"
Using the REPL to start our application shows our driver is working:
2022-06-10 10:00:02 [APPLICATION] INFO config.txt detected
2022-06-10 10:00:02 [APPHELPER] INFO DEBUG mode is active
2022-06-10 10:00:02 [APPLICATION] INFO UTC time device offset: 0(hrs):0(min)
2022-06-10 10:00:02 [DRIVER_MANAGER] INFO Acquiring parameters simple_driver sensor: simple_1
2022-06-10 10:00:02 [DRIVER_MANAGER] INFO simple_driver sensor detected: simple_1
2022-06-10 10:00:02 [LOGGER_MANAGER] INFO Log parameters appended: simple_1
2022-06-10 10:00:02 [APPLICATION] INFO Application started: PROTO_1
2022-06-10 10:00:02 [APPLICATION] INFO File Syslog level: info
2022-06-10 10:00:02 [APPLICATION] INFO Repl Syslog level: info
2022-06-10 10:00:02 [DATALOG045] INFO Started logging in 'data/OMC-045_PROTO_1_048000201_220610_100002.txt'
2022-06-10 10:00:02 [SCHEDULER] INFO Enabled sleeping in between tasks
2022-06-10 10:00:03 [DRIVER_MANAGER] INFO Sensor [simple_1] power on
2022-06-10 10:00:03 [DRIVER_MANAGER] INFO Sensor [simple_1] data successfully obtained
2022-06-10 10:00:03 [DRIVER_MANAGER] INFO Sensor [simple_1] power off
Sensor data: ('Temperature', '', 'TMP_simple_1') 1
Sensor data: ('Humidity', '', 'HUM_simple_1') 2
Sensor data: ('Status', '', 'STS_simple_1') 3
2022-06-10 10:00:03 [SCHEDULER] INFO Sleep for 0.749 seconds
2022-06-10 10:00:04 [DRIVER_MANAGER] INFO Sensor [simple_1] power on
2022-06-10 10:00:04 [DRIVER_MANAGER] INFO Sensor [simple_1] data successfully obtained
2022-06-10 10:00:04 [DRIVER_MANAGER] INFO Sensor [simple_1] power off
Sensor data: ('Temperature', '', 'TMP_simple_1') 1
Sensor data: ('Humidity', '', 'HUM_simple_1') 2
Sensor data: ('Status', '', 'STS_simple_1') 3
Note
The base of our sensor is operational now, from this point we can start adding the actual sensor driver by reading the data string over the given serial port.
Simulating the data
We now need to simulate the data, this can be done using a generic serial talker or use another OMC-048 using the script below:
import omc048, obs
print("simple_driver sensor simulator")
s2 = omc048.serial(2)
s2.init(9600, s2.RS422, txbuf=1024)
sensor_data = "Temp=20.34,Hum=56.4,Status=OK\r\n"
while True:
s2.write(sensor_data)
print(sensor_data)
obs.delay(1000)
Connect the simulated sensor output to the OMC-048 data logger and edit the simple_driver file to the example below:
1from sensor_drv import SensorDrv
2from read_line import Read_line
3
4 class simple_driver(SensorDrv):
5
6 def __init__(self, serial, conf):
7 SensorDrv.__init__(self)
8 self.__serial_data = Read_line(serial)
9
10 async def read_values(self):
11 while True:
12 received = await self.__serial_data.update()
13 if received:
14 print('received data:', received)
15 data = received[0].decode()
16 data_replace = data.replace('\r\n','')
17 data_replace = data_replace.replace('=',',')
18 data_split = data_replace.split(',')
19 print('split data:', data_split)
20 break
21 self.data = [data_split[1],data_split[3],data_split[5]]
22 return True
23
24 async def detect_parameters(self, tag_number = ''):
25 self.parameters = [ ('Temperature', '', 'TMP{}'.format(tag_number)),
26 ('Humidity', '', 'HUM{}'.format(tag_number)),
27 ('Status', '', 'STS{}'.format(tag_number)) ]
28 return True
29
30 async def flush(self):
31 pass
Note
We have used the read_line module to collect the data. Prints were added on the original input data as wel as the split data to show the results
Running the application presents us the following:
received data: [b'Temp=20.34,Hum=56.4,Status=OK\r\n']
split data: ['Temp', '20.34', 'Hum', '56.4', 'Status', 'OK']
2022-06-10 10:52:14 [DRIVER_MANAGER] INFO Sensor [simple_1] data successfully obtained
Sensor data: ('Temperature', '', 'TMP_simple_1') 20.34
Sensor data: ('Humidity', '', 'HUM_simple_1') 56.4
Sensor data: ('Status', '', 'STS_simple_1') OK
This concludes our simple driver example. Your own sensor driver now workes as any other! The data is automatically added to the logs!
Important
The ‘detect_parameters’ is executed on startup and should actually check for a present sensor, this prevents the sensor from being scheduled if not attatched.
The ‘read_values’ is executed every given cron interval and should only return ‘True’ in case the sensor reading was succesfully obtained and ‘self.data’ filled with data.
You can add sensor specific settings to the config.txt file by using the config module!
There are many sensor drivers you can use as an example, you can find them in the ‘script/modules’ folder
Tip
Can’t get it figured out? Feel free to contact us!