Merge branch 'develop' into update_check

This commit is contained in:
Bastian Schroll 2020-04-28 15:46:24 +02:00 committed by GitHub
commit 9bd330f500
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 508 additions and 17 deletions

39
.github/workflows/build_docs.yml vendored Normal file
View file

@ -0,0 +1,39 @@
name: build_docs
on:
push:
branches:
- master
jobs:
build_docs:
name: Build documentation
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Build doxygen
uses: mattnotmitt/doxygen-action@v1
with:
working-directory: './'
doxyfile-path: 'docu/doxygen.ini'
- name: Build mkdocs
run: |
python -m pip install --upgrade pip
pip install mkdocs
python -m mkdocs build -f docu/mkdocs.yml
- name: Upload to docs-server
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SCP_HOST }}
port: ${{ secrets.SCP_PORT }}
username: ${{ secrets.SCP_USERNAME }}
password: ${{ secrets.SCP_PASSWORD }}
source: "docu/site/**"
target: ${{ secrets.SCP_TARGET_PATH }}
strip_components: 2

View file

@ -1,30 +1,34 @@
name: pytest
on: [push]
on: [push, pull_request]
jobs:
build:
strategy:
max-parallel: 3
matrix:
os: [ubuntu-latest]
python-version: [3.5, 3.6, 3.7]
python-version: [3.5, 3.6, 3.7, 3.8]
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v1
- name: Set up Python ${{matrix.python-version}} at ${{matrix.os}}
uses: actions/setup-python@v1
with:
python-version: ${{matrix.python-version}}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
mkdir log/
- name: Test with pytest
run: |
pytest -c 'test/pytest.ini'
- name: Save artifacts
uses: actions/upload-artifact@master
with:

View file

@ -42,7 +42,7 @@ class ZveiDecoder:
bwPacket = Packet()
bwPacket.set("mode", "zvei")
bwPacket.set("zvei", ZveiDecoder._solveDoubleTone(data[7:12]))
bwPacket.set("tone", ZveiDecoder._solveDoubleTone(data[7:12]))
return bwPacket

View file

@ -0,0 +1,76 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""!
____ ____ ______ __ __ __ _____
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
German BOS Information Script
by Bastian Schroll
@file: lienInInput.py
@date: 18.04.2020
@author: Philipp von Kirschbaum
@description: Input source for line-in with alsa
"""
import logging
from boswatch.utils import paths
from boswatch.processManager import ProcessManager
from boswatch.inputSource.inputBase import InputBase
logging.debug("- %s loaded", __name__)
class LineInInput(InputBase):
"""!Class for the line-in input source"""
def _runThread(self, dataQueue, lineInConfig, decoderConfig):
lineInProc = None
mmProc = None
try:
lineInProc = ProcessManager("arecord")
lineInProc.addArgument("-q ") # supress any other outputs
lineInProc.addArgument("-f S16_LE") # set output format (16bit)
lineInProc.addArgument("-r 22050") # set output sampling rate (22050Hz)
lineInProc.addArgument("-D plughw:" +
str(lineInConfig.get("card", default="1")) +
"," +
str(lineInConfig.get("device", default="0"))) # device id
lineInProc.setStderr(open(paths.LOG_PATH + "asla.log", "a"))
lineInProc.start()
mmProc = ProcessManager(str(lineInConfig.get("mmPath", default="multimon-ng")), textMode=True)
if decoderConfig.get("fms", default=0):
mmProc.addArgument("-a FMSFSK")
if decoderConfig.get("zvei", default=0):
mmProc.addArgument("-a ZVEI1")
if decoderConfig.get("poc512", default=0):
mmProc.addArgument("-a POCSAG512")
if decoderConfig.get("poc1200", default=0):
mmProc.addArgument("-a POCSAG1200")
if decoderConfig.get("poc2400", default=0):
mmProc.addArgument("-a POCSAG2400")
mmProc.addArgument("-f alpha")
mmProc.addArgument("-t raw -")
mmProc.setStdin(lineInProc.stdout)
mmProc.setStderr(open(paths.LOG_PATH + "multimon-ng.log", "a"))
mmProc.start()
logging.info("start decoding")
while self._isRunning:
if not lineInProc.isRunning:
logging.warning("asla was down - try to restart")
lineInProc.start()
elif not mmProc.isRunning:
logging.warning("multimon was down - try to restart")
mmProc.start()
elif lineInProc.isRunning and mmProc.isRunning:
line = mmProc.readline()
if line:
self.addToQueue(line)
except:
logging.exception("error in lineIn input routine")
finally:
mmProc.stop()
lineInProc.stop()

View file

@ -16,6 +16,11 @@
"""
# pylint: disable=wrong-import-position
# pylint: disable=wrong-import-order
import sys
major_version = sys.version_info.major
assert major_version >= 3, "please use python3 to run BosWatch 3"
from boswatch.utils import paths
if not paths.makeDirIfNotExist(paths.LOG_PATH):
@ -45,6 +50,7 @@ from boswatch.decoder.decoder import Decoder
from boswatch.utils import header
from boswatch.utils import misc
from boswatch.inputSource.sdrInput import SdrInput
from boswatch.inputSource.lineInInput import LineInInput
header.logoToLog()
header.infoToLog()
@ -83,6 +89,8 @@ try:
logging.debug("loading input source: %s", bwConfig.get("client", "inputSource"))
if bwConfig.get("client", "inputSource") == "sdr":
inputSource = SdrInput(inputQueue, bwConfig.get("inputSource", "sdr"), bwConfig.get("decoder"))
elif bwConfig.get("client", "inputSource") == "lineIn":
inputSource = LineInInput(inputQueue, bwConfig.get("inputSource", "lineIn"), bwConfig.get("decoder"))
else:
logging.fatal("Invalid input source: %s", bwConfig.get("client", "inputSource"))
exit(1)

View file

@ -16,6 +16,11 @@
"""
# pylint: disable=wrong-import-position
# pylint: disable=wrong-import-order
import sys
major_version = sys.version_info.major
assert major_version >= 3, "please use python3 to run BosWatch 3"
from boswatch.utils import paths
if not paths.makeDirIfNotExist(paths.LOG_PATH):

View file

@ -9,7 +9,7 @@
client:
name: BW3 Client # name of the BW3 Client instance
inputSource: sdr # atm only 'sdr' is possible
inputSource: sdr # name of the input source('sdr' or 'lineIn')
useBroadcast: no # use broadcast to find server automatically
reconnectDelay: 3 # time in seconds to delay reconnect try
sendTries: 3 # how often should tried to send a packet
@ -28,6 +28,10 @@ inputSource:
gain: 100
rtlPath: /usr/bin/rtl_fm
mmPath: /opt/multimon/multimon-ng
lineIn:
card: 1
device: 0
mmPath: /opt/multimon/multimon-ng
decoder:
fms: yes

View file

@ -11,7 +11,7 @@ zwingend in die Konfiguration eingetragen werden.
|Feld|Beschreibung|Default|
|----|------------|-------|
|name|Name zur Identifizierung der Client Instanz||
|inputSource|Art der zu nutzenden Input Quelle (aktuell nur `sdr`)|sdr|
|inputSource|Art der zu nutzenden Input Quelle (`sdr` oder `lineIn`)||
|useBroadcast|Verbindungsdaten per [Broadcast](information/broadcast.md) beziehen|no|
|reconnectDelay|Verzögerung für erneuten Verbindungsversuch zum Server|3|
|sendTries|Anzahl der Sendeversuche eines Pakets|3|
@ -36,7 +36,7 @@ server:
---
### `inputSource:`
Aktuell gibt es nur `sdr:` als Input Quelle
Es gibt die Auswahl zwischen `sdr` oder `lineIn` als Input Quelle
#### `sdr:`
|Feld|Beschreibung|Default|
@ -62,6 +62,54 @@ inputSource:
mmPath: /opt/multimon/multimon-ng
```
#### `lineIn:`
|Feld|Beschreibung|Default|
|----|------------|-------|
|device|die device Id der Soundkarte|1|
|mmPath|Pfad zur multimon-ng Binary|multimon-ng|
**Device herausfinden**
Durch eingabe des Befehls `aplay -l` werden alle Soundkarten ausgegeben. Das schaut ungefähr so aus:
```console
**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
Subdevices: 7/7
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
card 0: ALSA [bcm2835 ALSA], device 1: bcm2835 IEC958/HDMI [bcm2835 IEC958/HDMI]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: ALSA [bcm2835 ALSA], device 2: bcm2835 IEC958/HDMI1 [bcm2835 IEC958/HDMI1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: Device [C-Media USB Audio Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
```
Wir betrachten das letzte Gerät: `card 1: Device [C-Media USB Audio Device], device 0: USB Audio [USB Audio]`
In dem Fall ist das letzte Gerät - `card 1` - unsere USB-Audio Schnittstelle die wir verwenden wollen.
In der Konfiguration wird das Feld `card` nun auf den Wert 1 gesetzt.
Nach dem Typ der Soundkarte steht das device, in diesem Fall `device 0`.
In der Konfiguration wird das Feld `device` nun auf den Wert 0 gesetzt.
**Beispiel:**
```yaml
inputSource:
...
lineIn:
card: 1
device: 0
mmPath: /opt/multimon/multimon-ng
```
---
### `decoder:`
|Feld|Beschreibung|Default|

View file

@ -34,7 +34,7 @@ Informationen zum Aufbau eines [BOSWatch Pakets](../develop/packet.md)
- type: module
res: descriptor
config:
- scanField: zvei
- scanField: tone
descrField: description
wildcard: "{DESCR}"
descriptions:

View file

@ -43,7 +43,7 @@ Vereinfacht kann man sagen, dass einzelnen Router ODER-verknüpft und die jeweil
config:
- name: "Zvei filter"
checks:
- field: zvei
- field: tone
regex: "65[0-9]{3}" # all zvei with starting 65
- name: "FMS Stat 3"
checks:

View file

@ -3,7 +3,7 @@
## Beschreibung
Mit diesem Plugin ist es moeglich, Telegram-Nachrichten für POCSAG-Alarmierungen zu senden.
Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket definiert sind. (beispielsweise durch das [Geocoding](../modul/geocoding.md) Modul)
Außerdem werden Locations versendet, wenn die Felder `lat` und `lon` im Paket definiert sind. (beispielsweise durch das [Geocoding](../modul/geocoding.md) Modul)
## Unterstütze Alarmtypen
- Pocsag
@ -26,9 +26,9 @@ Außerdem werden Locations versenden, wenn die Felder `lat` und `lon` im Paket d
res: telegram
config:
message: "{RIC}({SRIC})\n{MSG}"
botToken: "{{ Telegram Bot Token }}"
chatIds:
- "{{ Telegram Chat Id }}"
botToken: "BOT_TOKEN"
chatIds:
- "CHAT_ID"
```
---

226
install.sh Normal file
View file

@ -0,0 +1,226 @@
#!/bin/bash
# -*- coding: utf-8 -*-
"""
____ ____ ______ __ __ __ _____
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
/ __ / / / /\__ \| | /| / / __ / __/ ___/ __ \ /_ <
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
German BOS Information Script
by Bastian Schroll
@file: install.sh
@date: 14.04.2020
@author: Bastian Schroll, Smeti
@description: Installation File for BOSWatch3
"""
"""
Die Installation von BOSWatch3 wird mittels diesem bash-Skript weitestgehend automatisiert durchgeführt.
Zunächst wird das aktuelle Installationsskript heruntergeladen:
wget https://github.com/BOSWatch/BW3-Core/raw/master/install.sh
Im Anschluss wird das Skript mit dem Kommando
sudo bash install.sh
ausgeführt.
Standardmäßig wird das Programm nach /opt/boswatch3 installiert. Folgende Parameter stehen zur Installation zur Verfügung:
Parameter zulässige Werte Funktion
-r / --reboot - Reboot nach Installation (Ohne Angabe: Kein Reboot)
-b / --branch dev Installiert einen anderen Branch (dev nicht empfohlen!)
-p / --path /your/path Installiert in ein anderes Verzeichnis (nicht empfohlen!)
master ist der stabile, zur allgemeinen Nutzung vorgesehene Branch
develop ist der aktuelle Entwicklungs-Branch (Nur für Entwickler empfohlen)
"""
function exitcodefunction {
errorcode=$1
action=$2
module=$3
if [ $errorcode -ne "0" ]; then
echo "Action: $action on $module failed." >> $boswatchpath/install/setup_log.txt
echo "Exitcode: $errorcode" >> $boswatchpath/install/setup_log.txt
echo ""
echo "Action: $action on $module failed."
echo "Exitcode: $errorcode"
echo ""
echo " -> If you want to open an issue at https://github.com/BOSWatch/BW3-Core/issues"
echo " please post the logfile, located at $boswatchpath/install/setup_log.txt"
exit 1
else
echo "Action: $action on $module ok." >> $boswatchpath/install/setup_log.txt
fi
}
tput clear
tput civis
echo " ____ ____ ______ __ __ __ _____ "
echo " / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ / "
echo " / __ / / / /\__ \| | /| / / __ / __/ ___/ __ \ /_ < "
echo " / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ / "
echo "/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/ "
echo " German BOS Information Script "
echo " by Bastian Schroll "
echo ""
# Make sure only root can run our script
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root!" 1>&2
exit 1
fi
echo "This may take several minutes... Don't panic!"
echo ""
echo "Caution, script does not install a webserver with PHP and MySQL"
echo "So you have to make up manually if you want to use MySQL support"
boswatchpath=/opt/boswatch3
reboot=false
for (( i=1; i<=$#; i=$i+2 )); do
t=$((i + 1))
eval arg=\$$i
eval arg2=\$$t
case $arg in
-r|--reboot) reboot=true ;;
-b|--branch)
case $arg2 in
dev|develop) echo " !!! WARNING: you are using the DEV BRANCH !!! "; branch=dev ;;
*) branch=master ;;
esac ;;
-p|--path) echo " !!! WARNING: you'll install BOSWATCH to alternative path !!! "; boswatchpath=$arg2 ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
mkdir -p $boswatchpath
mkdir -p $boswatchpath/install
echo ""
tput cup 13 15
echo "[ 1/9] [#--------]"
tput cup 15 5
echo "-> make an apt-get update................"
apt-get update -y > $boswatchpath/install/setup_log.txt 2>&1
tput cup 13 15
echo "[ 2/9] [##-------]"
tput cup 15 5
echo "-> download GIT and other stuff.........."
apt-get -y install git cmake build-essential libusb-1.0 qt4-qmake qt4-default libpulse-dev libx11-dev sox >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? download stuff
tput cup 13 15
echo "[ 3/9] [###------]"
tput cup 15 5
echo "-> download Python, Yaml and other stuff.."
sudo apt-get -y install python3 python3-yaml >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? download python
tput cup 13 15
echo "[ 4/9] [####-----]"
tput cup 15 5
echo "-> download rtl_fm........................."
cd $boswatchpath/install
git clone --branch v0.5.4 https://github.com/osmocom/rtl-sdr.git rtl-sdr >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? git-clone rtl-sdr
cd $boswatchpath/install/rtl-sdr/
tput cup 13 15
echo "[ 5/9] [#####----]"
tput cup 15 5
echo "-> compile rtl_fm......................"
mkdir -p build && cd build
cmake ../ -DINSTALL_UDEV_RULES=ON >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? cmake rtl-sdr
make >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? make rtl-sdr
make install >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? make-install rtl-sdr
ldconfig >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? ldconfig rtl-sdr
tput cup 13 15
echo "[ 6/9] [######---]"
tput cup 15 5
echo "-> download multimon-ng................"
cd $boswatchpath/install
git clone --branch 1.1.8 https://github.com/EliasOenal/multimon-ng.git multimonNG >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? git-clone multimonNG
cd $boswatchpath/install/multimonNG/
tput cup 13 15
echo "[ 7/9] [#######--]"
tput cup 15 5
echo "-> compile multimon-ng................."
mkdir -p build
cd build
qmake ../multimon-ng.pro >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? qmake multimonNG
make >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? make multimonNG
make install >> $boswatchpath/install/setup_log.txt 2>&1
exitcodefunction $? qmakeinstall multimonNG
tput cup 13 15
echo "[ 8/9] [########-]"
tput cup 15 5
echo "-> download BOSWatch3.................."
cd $boswatchpath/
case $branch in
"dev") git clone -b develop https://github.com/BOSWatch/BW3-Core >> $boswatchpath/install/setup_log.txt 2>&1 && \
exitcodefunction $? git-clone BW3-Core-develop ;;
*) git clone -b master https://github.com/BOSWatch/BW3-Core >> $boswatchpath/install/setup_log.txt 2>&1 && \
exitcodefunction $? git-clone BW3-Core ;;
esac
tput cup 13 15
echo "[9/9] [#########]"
tput cup 15 5
echo "-> configure..........................."
cd $boswatchpath/
chmod +x *
echo $'# BOSWatch3 - blacklist the DVB drivers to avoid conflicts with the SDR driver\n blacklist dvb_usb_rtl28xxu \n blacklist rtl2830\n blacklist dvb_usb_v2\n blacklist dvb_core' >> /etc/modprobe.d/boswatch_blacklist_sdr.conf
tput cup 17 1
tput rev # Schrift zur besseren lesbarkeit Revers
echo "BOSWatch is now installed in $boswatchpath/ Installation ready!"
tput sgr0 # Schrift wieder Normal
tput cup 19 3
echo "Watch out: to run BOSWatch3 you have to modify the server.yaml and client.yaml!"
echo "Do the following step to do so:"
echo "sudo nano $boswatchpath/config/client.yaml eg. server.yaml"
echo "and modify the config as you need. This step is optional if you are upgrading an old version of BOSWatch3."
echo "You can read the instructions on https://docs.boswatch.de/"
tput setaf 1 # Rote Schrift
echo "Please REBOOT bevor the first start"
tput setaf 9 # Schrift zurücksetzen
echo "start Boswatch3 with"
echo "sudo python3 bw_client.py -c client.yaml and sudo python3 bw_server.py -c server.yaml"
tput cnorm
# cleanup
mkdir $boswatchpath/log/install -p
mv $boswatchpath/install/setup_log.txt $boswatchpath/log/install/
rm $boswatchpath/install/ -R
mv $boswatchpath/BW3-Core/* $boswatchpath/
rm $boswatchpath/BW3-Core -R
if [ $reboot = "true" ]; then
/sbin/reboot
fi

View file

@ -42,10 +42,10 @@ class BoswatchModule(ModuleBase):
@param bwPacket: A BOSWatch packet instance"""
for descriptor in self.config:
if not bwPacket.get(descriptor.get("scanField")):
break # scanField is not available in this packet
bwPacket.set(descriptor.get("descrField"), bwPacket.get(descriptor.get("scanField")))
for description in descriptor.get("descriptions"):
if not bwPacket.get(descriptor.get("scanField")):
break # scanField is not available in this packet
bwPacket.set(descriptor.get("descrField"), description.get("for"))
if str(description.get("for")) == bwPacket.get(descriptor.get("scanField")):
logging.debug("Description '%s' added in packet field '%s'",
description.get("add"), descriptor.get("descrField"))

View file

@ -0,0 +1,72 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""!
____ ____ ______ __ __ __ _____
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
German BOS Information Script
by Bastian Schroll
@file: test_descriptor.py
@date: 14.04.2020
@author: Bastian Schroll
@description: Unittests for BOSWatch. File have to run as "pytest" unittest
"""
# problem of the pytest fixtures
# pylint: disable=redefined-outer-name
import logging
import pytest
from boswatch.utils import paths
from boswatch.configYaml import ConfigYAML
from boswatch.packet import Packet
from module.descriptor import BoswatchModule as Descriptor
def setup_method(method):
logging.debug("[TEST] %s.%s", method.__module__, method.__name__)
@pytest.fixture
def makeDescriptor():
"""!Build a descriptor object with loaded configuration"""
config = ConfigYAML()
assert config.loadConfigFile(paths.TEST_PATH + "test_config.yaml") is True
descriptor = Descriptor(config.get("descriptor_test"))
return descriptor
@pytest.fixture
def makePacket():
"""!Build a BW Packet object"""
packet = Packet()
return packet
def test_descriptorFoundFirst(makeDescriptor, makePacket):
"""!Run descriptor on the first entry in list"""
makePacket.set("tone", "12345")
makePacket = makeDescriptor.doWork(makePacket)
assert makePacket.get("description") == "Test 12345"
def test_descriptorFoundSecond(makeDescriptor, makePacket):
"""!Run descriptor on the second entry in list"""
makePacket.set("tone", "23456")
makePacket = makeDescriptor.doWork(makePacket)
assert makePacket.get("description") == "Test 23456"
def test_descriptorNotFound(makeDescriptor, makePacket):
"""!Run descriptor no matching data found"""
makePacket.set("tone", "99999")
makePacket = makeDescriptor.doWork(makePacket)
assert makePacket.get("description") == "99999"
def test_descriptorScanFieldNotAvailable(makeDescriptor, makePacket):
"""!Run descriptor on a non existent scanField"""
makePacket = makeDescriptor.doWork(makePacket)
assert makePacket.get("description") is None

View file

@ -8,7 +8,7 @@
# by Bastian Schroll
[pytest]
addopts = -v --pep8 --flakes --cov=boswatch/ --cov-report=term-missing --log-level=CRITICAL
addopts = -v --pep8 --flakes --cov=boswatch/ --cov=module/ --cov plugin/ --cov-report=term-missing --log-level=CRITICAL
# classic or progress
console_output_style = progress

View file

@ -30,3 +30,12 @@ list1:
- two
- three
- string1
descriptor_test:
- scanField: tone
descrField: description
descriptions:
- for: 12345
add: Test 12345
- for: 23456
add: Test 23456