Websocket server implementing a clock handling alarms and timezones
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Yann Weber 0a91cd8a80 README.md update 3 lat temu
pyws_clock Updated documentation 3 lat temu
.gitignore Initial commit 3 lat temu
README.md README.md update 3 lat temu
config.ini.inc Initial commit 3 lat temu
logrotate_pyws_clock.inc Initial commit 3 lat temu
nginx_server.conf Initial commit 3 lat temu
pyws_clock.service.inc Initial commit 3 lat temu
requirements.txt Initial commit 3 lat temu
run_server.sh Initial commit 3 lat temu

README.md

pyws_clock

Websocket clock server, handling timezones, alarms and sessions.

TODO

Add some test using unittest.

Replace dateutil by pytz in order to implement a command listing available timezones.

Send an array of alarms instead of 1 message per ringing alarm.

Replace dirty & quick session implementation with something like werkzeug sessions.

Dependencies

  • Python >= 3.9
  • python3-dateutil 2.8.1
  • python3-websockets 8.1

Debian-based dependencies installation

apt install python3-dateutil python3-websockets

Installing dependencies using pip

pip3 install -r requirements.txt

Running the server

python3 -m pyws_clock

Get some help using python3 -m pyws_clock --help

Deployment

Systemd service will run the server using the run_server.sh script. This script runs python3 -m pyws_clock -C config.ini allowing to configure the daemon with a config.ini file.

Create a configuration file

cp config.ini.inc config.ini; edit config.ini

Create a systemd service

cp pyws_clock.service.inc pyws_clock.service
edit pyws_clock.service
cp pyws_clock.service /etc/systemd/system/
systemctl enable pyws_clock.service
systemctl start pyws_clock.service
systemctl status pyws_clock.service

Testing the websocket server

Run this command and send a dummy session id by pressing enter. python3 -m websockets ws://127.0.0.1:8901

Example deployment on Debian 11

adduser --system pyws_clock
cp -R pyws_clock /home/pyws_clock/
cd /home/pyws_clock/pyws_clock/

cp config.ini.inc config.ini
echo "session_directory=/var/run/pyws_clock/sessions/
logfile=/var/log/pyws_clock/pyws_clock.log" >> config.ini

cp pyws_clock.service.inc pyws_clock.service
echo -e "User=pyws_clock
Group=nogroup
WorkingDirectory=/home/pyws_clock/pyws_clock/
ExecStart=/home/pyws_clock/pyws_clock/run_server.sh" >> pyws_clock.service
mv pyws_clock.service /etc/systemd/system/

# log dir & rotation config
mkdir /var/log/pyws_clock/
chown pyws_clock: /var/log/pyws_clock
cp logrotate_pyws_clock.inc /etc/logrotate.d/pyws_clock
systemctl restart logrotate

# session directory creation
mkdir -p /var/run/pyws_clock/sessions/
chown -R pyws_clock: /var/run/pyws_clock

# Enabling & starting the systemd service
systemctl enable pyws_clock.service
systemctl start pyws_clock.service
systemctl status pyws_clock.service

Nginx configuration

A sample configuration is available in nginx_server.conf.

Websocket server protocol description

The server replies on any URL.

Before entering the main loop, the listening server waits for 1st message containing a session ID. If an empty/dummy/invalid/unknown session ID is sent by the client, the server replies with a new, valid, session ID and enter the main loop. If a valid session ID is sent, the server reply the same session ID and enter the main loop, formated using SESSION:<SESSION_ID>.

Main loop

The server send the current time (ISO 8601 format) every second.

Command results

The client can interact with the server sending one of the command listed using python3 -m pyws_clock -L.

When a client send a command, the next message from the server will be a command result. Results are string formatted using <STATUS>:<DETAILS>. Status can be one of 'ERR' or 'OK', details are optionnale for OK statuses.

Alarms rings

When an alarm is ringing, after sending time, the server send messages formatted using ALRM:<NAME> where NAMEis the name of the ringing alarm. If multiple alarms are ringing, multiple ALRM: messages are sent every second.

Timezone informations

Before the first time is sent and every time the timezone changes (inclucing summer/winter transitions), the clock. Timezones messages are formatted using TZN:<TZNAME>

Messages types summary

  • Session ID
    • SESSION:<SESSION_ID>
  • Clock tick
    • ISO8601_Datetime
  • Timezone name
    • TZN:<TZNAME>
  • Alarm rings
    • ALRM:<JSON_ARRAY>
  • Command results
    • OK:<DETAILS>
    • ERR:<REASON>