ATS-4: Amateur-Radio Contest Administration System
ATS-4 is an Automatic Acceptance & Tabulation System for Amateur-Radio Contests, based on QxSL. Feel free to visit ALLJA1 ATS-4.
Features
- provides a web interface for contest-log acceptance.
- verifies the uploaded logs according to the contest rules described in Ruby or LISP forms.
- supports many contests including UEC, ALLJA1, REAL-TIME, 1-Area 6m AM and TAMAGAWA.
Documents
Quick Start
Docker image is available. Paste the following command into the terminal and run it:
cat << EOS > docker-compose.yaml
version: '3'
services:
ATS4:
image: ghcr.io/nextzlog/ats4:master
ports:
- 9000:9000
volumes:
- ./ats/data:/ats/data
- ./ats/logs:/ats/logs
- ./ats.conf:/ats/conf/ats.conf
- ./rules.rb:/ats/conf/rules.rb
command: /ats/bin/ats4
www:
image: nginx:latest
ports:
- 80:80
volumes:
- ./proxy.conf:/etc/nginx/conf.d/default.conf
EOS
echo -n 'enter mail hostname: '
read host
echo -n 'enter mail username: '
read user
echo -n 'enter mail password: '
read pass
cat << EOS > ats.conf
play.mailer.host=$host
play.mailer.port=465
play.mailer.ssl=true
play.mailer.user="$user"
play.mailer.password="$pass"
play.mailer.mock=false
ats4.rules=rules.rb
EOS
cat << EOS > rules.rb
require 'rules/sample/plain'
RULE
EOS
echo -n 'enter server domain: '
read name
cat << EOS > proxy.conf
server {
server_name $name;
location / {
proxy_pass http://ATS4:9000;
location /admin/ {
allow 127.0.0.1;
deny all;
}
location ~ /admin {
allow 127.0.0.1;
deny all;
}
}
}
EOS
docker compose up -dConfiguration
First, create docker-compose.yaml as follows:
version: '3'
services:
ATS4:
image: ghcr.io/nextzlog/ats4:master
ports:
- 9000:9000
volumes:
- ./ats/data:/ats/data
- ./ats/logs:/ats/logs
- ./ats.conf:/ats/conf/ats.conf
- ./rules.rb:/ats/conf/rules.rb
command: /ats/bin/ats4
www:
image: nginx:latest
ports:
- 80:80
volumes:
- ./proxy.conf:/etc/nginx/conf.d/default.confThen, follow the instructions below.
Proxy
Create proxy.conf as follows:
server {
server_name localhost;
location / {
proxy_pass http://ATS4:9000;
location /admin/ {
allow 127.0.0.1;
deny all;
}
location ~ /admin {
allow 127.0.0.1;
deny all;
}
}
}Make sure that unauthorized clients cannot access administration pages under /admin.
Expose port 80 of the container to the internet so that the administration page cannot be accessed.
Create the system configuration file ats.conf as follows:
# Typesafe Mailer Plugin
play.mailer.host=mail.allja1.org
play.mailer.port=465
play.mailer.ssl=true
play.mailer.user="***********"
play.mailer.password="*******"
# Never forget to disable mock mode before the contest:
play.mailer.mock=trueModify the settings properly.
Regulation
Add the path to the contest definition file to ats.conf like this:
# Contest
# ats4.rules=/rules/JA1ZLO/ja1.rb
# ats4.rules=/rules/JA1ZGP/uec.rb
ats4.rules=rules.rbIn addition, create rules.rb as follows:
require 'rules/sample/plain'
RULEOf course, you can also modify rules.rb to customize it for your contest.
See plain.rb for example.
Run
Finally, create a container as follows:
$ docker compose up -dAccess 80 port of the container.
Shutdown
To kill the container, enter the following command:
$ docker compose killDevelopment Mode
You can change Scala code and configuration without restarting by starting ATS-4 in development mode as follows:
$ sbt runThen, access localhost:9000/admin/shell to develop contest rules interactively.
You can test the scoring algorithm by attaching QSO data to the web form.
Stream API
ATS-4 provides the streaming API for the REAL-TIME CONTEST.
Registration
Contest participants will register their account information with ATS-4 in advance.
ATS-4 returns a security key (UUID) by sending a GET request to http://localhost:8873?id=<UUID>.
Clients may retrieve the key by listening on the 8873 port and access /agent/<UUID>.
Upstream
When the contest starts, the client always connects to the server via WebSocket. Each time a participant contacts another participant on air, the client sends the difference in the QSO records to the server. Messages from the clients to the server must follow the format below.
| position | field |
|---|---|
| 1st byte | number of QSOs deleted |
| sequence | header of the QSO data |
| sequence | QSO entities to delete |
| sequence | QSO entities to append |
The second and subsequent bytes of the messages are formatted as a single electronic log file. The format must be officially supported by the QXSL library.
Downstream
The server receives the QSO records, scores it, wait a few seconds, and then notifies all clients of the score update. JSON messages from the server to the clients are formatted as follows:
{
"14MHz": [
{"call": "JA1ZLO", "score": 200, "total": 2200},
{"call": "JA1YWX", "score": 100, "total": 2100}
]
}Demonstration
A simple WebSocket client for ATS-4 may be written as follows:
Streaming Demo

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
