templates | ||
.gitignore | ||
decoder.py | ||
password.txt.example | ||
read.py | ||
README.md | ||
webserver.py |
About
Receive monitoring data from a squeow AM transmitter.
read.py will (using decoder.py) connect to a serial port, print values to stdout, and send values to a webserver
webserver.py is such a webserver. It provides an authenticated API for receiving values (most likely by read.py) and an unauthenticated API to get values.
Howto
Dependencies
apt install python3-fastapi python3-serial python3-requests
Run
./read.py -v --baudrate 115200 --wait --device /dev/pts/17 --http-endpoint http://127.0.0.1:8000 --http-auth-file password.txt
uvicorn webserver:app
Serial protocol
Goals
receive-only
if you only want to receive data, you shouldn't need to ask for data. This makes it possible to connect a serial port to multiple receivers!
machine and human-readable
this software will parse messages, but even if you don't have it around, you should be able to read messages
just opening minicom
.
High level description
Messages are started by the 0x01 ascii character (SOH start of heading) and ended by 0x0A ("\n", NL, new line). A messages needs to be entirely ascii.
There are two types of messages:
- log messages
- dump messages
Dump messages
Example: DMP freq=1234567 temp1=78 temp2=50 alm_temp=0 ros=4095 alm_ros=1
DMP is just a prefix to indicate the kind of message. Follows a space-separated sequence of key-values. A
value is any string (including numbers, but no spaces). Please only use lowercase letters, numbers, and
underscore ([a-z0-9_]
).
Values can only be integral positive numbers. Booleans don't have any specific form of support.
It is allowed to send dump messages which only inform the receiver about a part of the state, and not all of it. It's the receiver's responsibility to keep track of the whole state, and updating it whenever a new dump message arrives.
Log messages
Examples :
LOG I starting
LOG E overcurrent protection
LOG
is just a prefix.
Then a space
Then a single capital letter indicating the severity of the message.
Then a space.
Whatever follows is the actual message
This makes it possible for debug messages to be sent.
Monitoring
None of the software provided will include monitoring functionalities. However, it will be easy to integrate with an existing monitoring service:
Nagios
This check will verify whether the alarm for temp1 is off
/usr/lib/nagios/plugins/check_http --regex '^0$' -I 127.0.0.1 -p 8000 --url=/variables/alm_temp1
If you want to check whether the squeow microcontroller is still alive, this will check that the last message was received from the microcontroller less than 100s ago.
/usr/lib/nagios/plugins/check_http --regex '^squeow_time_since_last_seen [0-9][0-9]?$' -I 127.0.0.1 -p 8000 --url=/metrics
Prometheus
a /metrics
endpoint is exposed with the common metric=value
format, which is easily to integrate into your
prometheus instance.
Adding something like this at the end of the scrape_configs
section of your prometheus.yml
could be
enough:
- job_name: 'squeow'
# Override the global default and scrape targets from this job every 5 seconds.
scrape_interval: 5s
scrape_timeout: 5s
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:8000']
Development
Simulate a serial port
you might want to avoid developing with the squeow microcontroller actually connected to your computer, and just simulate it.
if you want to do so, run:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
Now, read the output; the first two lines would be sth like
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/2
2013/11/01 13:47:27 socat[2506] N PTY is /dev/pts/3
This means that your read.py
must use --device /dev/pts/2
.
To simulate the reception of a message from the microcontroller, do this
echo -e '\x01DMP freq=1234567 temp1=78 temp2=50 alm_temp=0 ros=4095 alm_ros=1' > /dev/pts/3