mirror of
https://github.com/BOSWatch/BW3-Core.git
synced 2025-12-06 07:12:04 +01:00
Merge branch 'develop' into process_manager
This commit is contained in:
commit
fc6e0111af
2
boswatch/router/__init__.py
Normal file
2
boswatch/router/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
38
boswatch/router/route.py
Normal file
38
boswatch/router/route.py
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""!
|
||||||
|
____ ____ ______ __ __ __ _____
|
||||||
|
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
|
||||||
|
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
|
||||||
|
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
|
||||||
|
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
|
||||||
|
German BOS Information Script
|
||||||
|
by Bastian Schroll
|
||||||
|
|
||||||
|
@file: route.py
|
||||||
|
@date: 04.03.2019
|
||||||
|
@author: Bastian Schroll
|
||||||
|
@description: Class for a single BOSWatch packet router route point
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Route:
|
||||||
|
"""!Class for single routing points"""
|
||||||
|
def __init__(self, name, callback):
|
||||||
|
"""!Create a instance of an route point
|
||||||
|
|
||||||
|
@param name: name of the route point
|
||||||
|
@param callback: instance of the callback function
|
||||||
|
"""
|
||||||
|
self._name = name
|
||||||
|
self._callback = callback
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""!Property to get the route point name"""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def callback(self):
|
||||||
|
"""!Porperty to get the callback function instance"""
|
||||||
|
return self._callback
|
||||||
72
boswatch/router/router.py
Normal file
72
boswatch/router/router.py
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""!
|
||||||
|
____ ____ ______ __ __ __ _____
|
||||||
|
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
|
||||||
|
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
|
||||||
|
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
|
||||||
|
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
|
||||||
|
German BOS Information Script
|
||||||
|
by Bastian Schroll
|
||||||
|
|
||||||
|
@file: router.py
|
||||||
|
@date: 01.03.2019
|
||||||
|
@author: Bastian Schroll
|
||||||
|
@description: Class for the BOSWatch packet router
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
import copy
|
||||||
|
|
||||||
|
logging.debug("- %s loaded", __name__)
|
||||||
|
|
||||||
|
|
||||||
|
class Router:
|
||||||
|
"""!Class for the Router"""
|
||||||
|
def __init__(self, name):
|
||||||
|
"""!Create a new router
|
||||||
|
|
||||||
|
@param name: name of the router"""
|
||||||
|
self._name = name
|
||||||
|
self._routeList = []
|
||||||
|
logging.debug("[%s] new router", self._name)
|
||||||
|
|
||||||
|
def addRoute(self, route):
|
||||||
|
"""!Adds a route point to the router
|
||||||
|
|
||||||
|
@param route: instance of the Route class
|
||||||
|
"""
|
||||||
|
logging.debug("[%s] add route: %s", self._name, route.name)
|
||||||
|
self._routeList.append(route)
|
||||||
|
|
||||||
|
def runRouter(self, bwPacket):
|
||||||
|
"""!Run the router
|
||||||
|
|
||||||
|
@param bwPacket: instance of Packet class
|
||||||
|
@return a instance of Packet class
|
||||||
|
"""
|
||||||
|
logging.debug("[%s] started", self._name)
|
||||||
|
for routeObject in self._routeList:
|
||||||
|
logging.debug("[%s] -> run route: %s", self._name, routeObject)
|
||||||
|
bwPacket_tmp = routeObject.callback(copy.deepcopy(bwPacket)) # copy bwPacket to prevent edit the original
|
||||||
|
|
||||||
|
if bwPacket_tmp is None: # returning None doesnt change the bwPacket
|
||||||
|
continue
|
||||||
|
|
||||||
|
if bwPacket_tmp is False: # returning False stops the router immediately
|
||||||
|
logging.debug("[%s] stopped", self._name)
|
||||||
|
break
|
||||||
|
|
||||||
|
bwPacket = bwPacket_tmp
|
||||||
|
logging.debug("[%s] <- bwPacket returned: %s", self._name, bwPacket)
|
||||||
|
logging.debug("[%s] ended", self._name)
|
||||||
|
return bwPacket
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""!Property to get the name of the router"""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def routeList(self):
|
||||||
|
"""!Property to get a list of all route points of this router"""
|
||||||
|
return self._routeList
|
||||||
|
|
@ -9,81 +9,41 @@
|
||||||
German BOS Information Script
|
German BOS Information Script
|
||||||
by Bastian Schroll
|
by Bastian Schroll
|
||||||
|
|
||||||
@file: router.py
|
@file: routerManager.py
|
||||||
@date: 01.03.2019
|
@date: 04.03.2019
|
||||||
@author: Bastian Schroll
|
@author: Bastian Schroll
|
||||||
@description: Class for the BOSWatch packet router
|
@description: Class for the BOSWatch packet router manager class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# todo think about implement threading for routers and the plugin calls (THREAD SAFETY!!!)
|
# todo think about implement threading for routers and the plugin calls (THREAD SAFETY!!!)
|
||||||
import logging
|
import logging
|
||||||
import copy
|
|
||||||
import importlib
|
import importlib
|
||||||
from boswatch.configYaml import ConfigYAML
|
from boswatch.configYaml import ConfigYAML
|
||||||
|
from boswatch.router.router import Router
|
||||||
|
from boswatch.router.route import Route
|
||||||
|
|
||||||
logging.debug("- %s loaded", __name__)
|
logging.debug("- %s loaded", __name__)
|
||||||
|
|
||||||
|
|
||||||
class _Route:
|
|
||||||
def __init__(self, name, callback):
|
|
||||||
self._name = name
|
|
||||||
self._callback = callback
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def callback(self):
|
|
||||||
return self._callback
|
|
||||||
|
|
||||||
|
|
||||||
class _Router:
|
|
||||||
def __init__(self, name):
|
|
||||||
self._name = name
|
|
||||||
self._routeList = []
|
|
||||||
logging.debug("[%s] new router", self._name)
|
|
||||||
|
|
||||||
def addRoute(self, route):
|
|
||||||
logging.debug("[%s] add route: %s", self._name, route.name)
|
|
||||||
self._routeList.append(route)
|
|
||||||
|
|
||||||
def runRouter(self, bwPacket):
|
|
||||||
logging.debug("[%s] started", self._name)
|
|
||||||
for routeObject in self._routeList:
|
|
||||||
logging.debug("[%s] -> run route: %s", self._name, routeObject)
|
|
||||||
bwPacket_tmp = routeObject.callback(copy.deepcopy(bwPacket)) # copy bwPacket to prevent edit the original
|
|
||||||
|
|
||||||
if bwPacket_tmp is None: # returning None doesnt change the bwPacket
|
|
||||||
continue
|
|
||||||
|
|
||||||
if bwPacket_tmp is False: # returning False stops the router immediately
|
|
||||||
logging.debug("[%s] stopped", self._name)
|
|
||||||
break
|
|
||||||
|
|
||||||
bwPacket = bwPacket_tmp
|
|
||||||
logging.debug("[%s] <- bwPacket returned: %s", self._name, bwPacket)
|
|
||||||
logging.debug("[%s] ended", self._name)
|
|
||||||
return bwPacket
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def routeList(self):
|
|
||||||
return self._routeList
|
|
||||||
|
|
||||||
|
|
||||||
class RouterManager:
|
class RouterManager:
|
||||||
|
"""!Class to manage all routers"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
"""!Create new router"""
|
||||||
self._routerDict = {}
|
self._routerDict = {}
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
"""!Destroy the internal routerDict
|
||||||
|
All routers and route point instances will be destroyed too
|
||||||
|
Also destroys all instances from modules or plugins"""
|
||||||
# destroy all routers (also destroys all instances of modules/plugins)
|
# destroy all routers (also destroys all instances of modules/plugins)
|
||||||
del self._routerDict
|
del self._routerDict
|
||||||
|
|
||||||
# if there is an error, router list would be empty (see tmp variable)
|
# if there is an error, router list would be empty (see tmp variable)
|
||||||
def buildRouter(self, config):
|
def buildRouter(self, config):
|
||||||
|
"""!Initialize Routers from given config file
|
||||||
|
|
||||||
|
@param config: instance of ConfigYaml class
|
||||||
|
@return True or False"""
|
||||||
self._routerDict = {} # all routers and instances of modules/plugins would be destroyed
|
self._routerDict = {} # all routers and instances of modules/plugins would be destroyed
|
||||||
routerDict_tmp = {}
|
routerDict_tmp = {}
|
||||||
logging.debug("build routers")
|
logging.debug("build routers")
|
||||||
|
|
@ -97,7 +57,7 @@ class RouterManager:
|
||||||
if router.get("name") in self._routerDict:
|
if router.get("name") in self._routerDict:
|
||||||
logging.error("duplicated router name: %s", router.get("name"))
|
logging.error("duplicated router name: %s", router.get("name"))
|
||||||
return False
|
return False
|
||||||
routerDict_tmp[router.get("name")] = _Router(router.get("name"))
|
routerDict_tmp[router.get("name")] = Router(router.get("name"))
|
||||||
|
|
||||||
for router in config.get("router"):
|
for router in config.get("router"):
|
||||||
routerName = router.get("name")
|
routerName = router.get("name")
|
||||||
|
|
@ -115,15 +75,15 @@ class RouterManager:
|
||||||
if routeType == "plugin":
|
if routeType == "plugin":
|
||||||
importedFile = importlib.import_module(routeType + "." + routeName)
|
importedFile = importlib.import_module(routeType + "." + routeName)
|
||||||
loadedClass = importedFile.BoswatchPlugin(routeConfig)
|
loadedClass = importedFile.BoswatchPlugin(routeConfig)
|
||||||
routerDict_tmp[routerName].addRoute(_Route(routeName, loadedClass._run))
|
routerDict_tmp[routerName].addRoute(Route(routeName, loadedClass._run))
|
||||||
|
|
||||||
elif routeType == "module":
|
elif routeType == "module":
|
||||||
importedFile = importlib.import_module(routeType + "." + routeName)
|
importedFile = importlib.import_module(routeType + "." + routeName)
|
||||||
loadedClass = importedFile.BoswatchModule(routeConfig)
|
loadedClass = importedFile.BoswatchModule(routeConfig)
|
||||||
routerDict_tmp[routerName].addRoute(_Route(routeName, loadedClass._run))
|
routerDict_tmp[routerName].addRoute(Route(routeName, loadedClass._run))
|
||||||
|
|
||||||
elif routeType == "router":
|
elif routeType == "router":
|
||||||
routerDict_tmp[routerName].addRoute(_Route(routeName, routerDict_tmp[routeName].runRouter))
|
routerDict_tmp[routerName].addRoute(Route(routeName, routerDict_tmp[routeName].runRouter))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.error("unknown type '%s' in %s", routeType, route)
|
logging.error("unknown type '%s' in %s", routeType, route)
|
||||||
|
|
@ -139,6 +99,10 @@ class RouterManager:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def runRouter(self, routerRunList, bwPacket):
|
def runRouter(self, routerRunList, bwPacket):
|
||||||
|
"""!Run given Routers
|
||||||
|
|
||||||
|
@param routerRunList: string or list of router names in string form
|
||||||
|
@param bwPacket: instance of Packet class"""
|
||||||
if type(routerRunList) is str: # convert single string name to list
|
if type(routerRunList) is str: # convert single string name to list
|
||||||
routerRunList = [routerRunList]
|
routerRunList = [routerRunList]
|
||||||
|
|
||||||
|
|
@ -147,6 +111,7 @@ class RouterManager:
|
||||||
self._routerDict[routerName].runRouter(bwPacket)
|
self._routerDict[routerName].runRouter(bwPacket)
|
||||||
|
|
||||||
def _showRouterRoute(self):
|
def _showRouterRoute(self):
|
||||||
|
"""!Show the routes of all routers"""
|
||||||
for name, routerObject in self._routerDict.items():
|
for name, routerObject in self._routerDict.items():
|
||||||
logging.debug("Route for %s", name)
|
logging.debug("Route for %s", name)
|
||||||
counter = 0
|
counter = 0
|
||||||
12
bw_client.py
12
bw_client.py
|
|
@ -97,13 +97,17 @@ try:
|
||||||
bwClient = TCPClient()
|
bwClient = TCPClient()
|
||||||
if bwClient.connect(ip, port):
|
if bwClient.connect(ip, port):
|
||||||
|
|
||||||
|
testFile = open(paths.TEST_PATH + "testdata.list", "r")
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
|
|
||||||
for i in range(0, 5): # todo implement real data receive
|
for testData in testFile:
|
||||||
time.sleep(1)
|
|
||||||
print("Alarm Nr #" + str(i))
|
|
||||||
|
|
||||||
bwPacket = Decoder.decode("ZVEI1: 12345")
|
if (len(testData.rstrip(' \t\n\r')) == 0) or ("#" in testData[0]):
|
||||||
|
continue
|
||||||
|
|
||||||
|
logging.debug("Test: %s", testData)
|
||||||
|
bwPacket = Decoder.decode(testData)
|
||||||
|
|
||||||
if bwPacket:
|
if bwPacket:
|
||||||
bwPacket.printInfo()
|
bwPacket.printInfo()
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ from boswatch.network.server import TCPServer
|
||||||
from boswatch.packet import Packet
|
from boswatch.packet import Packet
|
||||||
from boswatch.utils import header
|
from boswatch.utils import header
|
||||||
from boswatch.network.broadcast import BroadcastServer
|
from boswatch.network.broadcast import BroadcastServer
|
||||||
from boswatch.router import RouterManager
|
from boswatch.router.routerManager import RouterManager
|
||||||
|
|
||||||
|
|
||||||
header.logoToLog()
|
header.logoToLog()
|
||||||
|
|
@ -82,6 +82,7 @@ try:
|
||||||
while 1:
|
while 1:
|
||||||
if incomingQueue.empty(): # pause only when no data
|
if incomingQueue.empty(): # pause only when no data
|
||||||
time.sleep(0.1) # reduce cpu load (wait 100ms)
|
time.sleep(0.1) # reduce cpu load (wait 100ms)
|
||||||
|
# in worst case a packet have to wait 100ms until it will be processed
|
||||||
|
|
||||||
else:
|
else:
|
||||||
data = incomingQueue.get()
|
data = incomingQueue.get()
|
||||||
|
|
|
||||||
136
test/testdata.list
Normal file
136
test/testdata.list
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
# Testdata for the BOSWatch Test Mode function
|
||||||
|
# Data in Multimon-NG Raw Format
|
||||||
|
# Data is alternately passed to the decoder to simulate an used Radio-Frequency
|
||||||
|
|
||||||
|
#
|
||||||
|
# POCSAG
|
||||||
|
# ------
|
||||||
|
#
|
||||||
|
# The following settings in config.ini are expected for POCSAG
|
||||||
|
#
|
||||||
|
# [BOSWatch]
|
||||||
|
# useDescription = 1
|
||||||
|
# doubleFilter_ignore_entries = 10
|
||||||
|
# doubleFilter_check_msg = 1
|
||||||
|
#
|
||||||
|
# [POC]
|
||||||
|
# deny_ric = 7777777
|
||||||
|
# filter_range_start = 0000005
|
||||||
|
# filter_range_end = 8999999
|
||||||
|
# idDescribed = 1
|
||||||
|
#
|
||||||
|
|
||||||
|
# bitrate
|
||||||
|
POCSAG512: Address: 1000512 Function: 1 Alpha: BOSWatch-Test ÖÄÜß: okay
|
||||||
|
POCSAG1200: Address: 1001200 Function: 1 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG2400: Address: 1002400 Function: 1 Alpha: BOSWatch-Test: okay
|
||||||
|
|
||||||
|
# function-code
|
||||||
|
POCSAG512: Address: 1000000 Function: 0 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 1000001 Function: 1 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 1000002 Function: 2 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 1000003 Function: 3 Alpha: BOSWatch-Test: okay
|
||||||
|
|
||||||
|
# german special sign
|
||||||
|
POCSAG512: Address: 1200001 Function: 1 Alpha: BOSWatch-Test ÖÄÜß: okay
|
||||||
|
POCSAG512: Address: 1200001 Function: 1 Alpha: BOSWatch-Test öäü: okay
|
||||||
|
|
||||||
|
# with csv
|
||||||
|
POCSAG512: Address: 1234567 Function: 1 Alpha: BOSWatch-Test: with csv
|
||||||
|
|
||||||
|
# without csv
|
||||||
|
POCSAG1200: Address: 2345678 Function: 2 Alpha: BOSWatch-Test: without csv
|
||||||
|
POCSAG2400: Address: 3456789 Function: 3 Alpha: BOSWatch-Test: without csv
|
||||||
|
|
||||||
|
# OHNE TEXT????
|
||||||
|
POCSAG1200: Address: 1100000 Function: 0
|
||||||
|
POCSAG1200: Address: 1100000 Function: 1
|
||||||
|
POCSAG1200: Address: 1100000 Function: 2
|
||||||
|
POCSAG1200: Address: 1100000 Function: 3
|
||||||
|
|
||||||
|
# duplicate with same and other msg
|
||||||
|
POCSAG1200: Address: 2000001 Function: 2 Alpha: BOSWatch-Test: second is a duplicate
|
||||||
|
POCSAG1200: Address: 2000001 Function: 2 Alpha: BOSWatch-Test: second is a duplicate
|
||||||
|
POCSAG1200: Address: 2000001 Function: 2 Alpha: BOSWatch-Testing: okay
|
||||||
|
|
||||||
|
# duplicate in different order
|
||||||
|
POCSAG1200: Address: 2100000 Function: 2
|
||||||
|
POCSAG1200: Address: 2100001 Function: 2
|
||||||
|
POCSAG1200: Address: 2100002 Function: 2
|
||||||
|
POCSAG1200: Address: 2100000 Function: 2
|
||||||
|
POCSAG1200: Address: 2100001 Function: 2
|
||||||
|
POCSAG1200: Address: 2100002 Function: 2
|
||||||
|
POCSAG1200: Address: 2100000 Function: 2 Alpha: BOSWatch-Test: second is a duplicate
|
||||||
|
POCSAG1200: Address: 2100001 Function: 2 Alpha: BOSWatch-Test: second is a duplicate
|
||||||
|
POCSAG1200: Address: 2100002 Function: 2 Alpha: BOSWatch-Test: second is a duplicate
|
||||||
|
POCSAG1200: Address: 2100000 Function: 2 Alpha: BOSWatch-Test: second is a duplicate
|
||||||
|
POCSAG1200: Address: 2100001 Function: 2 Alpha: BOSWatch-Test: second is a duplicate
|
||||||
|
POCSAG1200: Address: 2100002 Function: 2 Alpha: BOSWatch-Test: second is a duplicate
|
||||||
|
|
||||||
|
# invalid
|
||||||
|
POCSAG512: Address: 3 Function: 0 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 33 Function: 0 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 333 Function: 0 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 3333 Function: 0 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 33333 Function: 0 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 333333 Function: 0 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 3333333 Function: 0 Alpha: BOSWatch-Test: okay
|
||||||
|
POCSAG512: Address: 333333F Function: 0 Alpha: BOSWatch-Test: invalid
|
||||||
|
POCSAG512: Address: 333333F Function: 1 Alpha: BOSWatch-Test: invalid
|
||||||
|
POCSAG512: Address: 3333333 Function: 4 Alpha: BOSWatch-Test: invalid
|
||||||
|
|
||||||
|
# denied
|
||||||
|
POCSAG1200: Address: 7777777 Function: 1 Alpha: BOSWatch-Test: denied
|
||||||
|
|
||||||
|
# out of filter Range
|
||||||
|
POCSAG1200: Address: 0000004 Function: 1 Alpha: BOSWatch-Test: out of filter start
|
||||||
|
POCSAG1200: Address: 9000000 Function: 1 Alpha: BOSWatch-Test: out of filter end
|
||||||
|
|
||||||
|
#Probealram
|
||||||
|
POCSAG1200: Address: 0871004 Function: 1 Alpha: Dies ist ein Probealarm!
|
||||||
|
## Multicast Alarm
|
||||||
|
POCSAG1200: Address: 0871002 Function: 0 Alpha: <EOT><FF>
|
||||||
|
POCSAG1200: Address: 0860001 Function: 0
|
||||||
|
POCSAG1200: Address: 0860002 Function: 0
|
||||||
|
POCSAG1200: Address: 0860003 Function: 0
|
||||||
|
POCSAG1200: Address: 0860004 Function: 0
|
||||||
|
POCSAG1200: Address: 0860005 Function: 0
|
||||||
|
POCSAG1200: Address: 0860006 Function: 0
|
||||||
|
POCSAG1200: Address: 0860007 Function: 0
|
||||||
|
POCSAG1200: Address: 0860008 Function: 0
|
||||||
|
POCSAG1200: Address: 0860009 Function: 0
|
||||||
|
POCSAG1200: Address: 0860010 Function: 0
|
||||||
|
POCSAG1200: Address: 0871003 Function: 0 Alpha: B2 Feuer Gebäude Pers in Gefahr. bla bla bla<NUL>
|
||||||
|
|
||||||
|
# regEx-Filter?
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# FMS
|
||||||
|
# ---
|
||||||
|
#
|
||||||
|
FMS: 43f314170000 (9=Rotkreuz 3=Bayern 1 Ort 0x25=037FZG 7141Status 3=Einsatz Ab 0=FZG->LST 2=I (ohneNA,ohneSIGNAL)) CRC correct
|
||||||
|
FMS: 43f314170000 (9=Rotkreuz 3=Bayern 1 Ort 0x25=037FZG 7141Status 3=Einsatz Ab 1=LST->FZG 2=I (ohneNA,ohneSIGNAL)) CRC correct
|
||||||
|
FMS: 43f314170000 (9=Rotkreuz 3=Bayern 1 Ort 0x25=037FZG 7141Status 3=Einsatz Ab 0=FZG->LST 2=II (ohneNA,mit SIGNAL)) CRC correct
|
||||||
|
FMS: 43f314170000 (9=Rotkreuz 3=Bayern 1 Ort 0x25=037FZG 7141Status 3=Einsatz Ab 1=LST->FZG 2=III(mit NA,ohneSIGNAL)) CRC correct
|
||||||
|
FMS: 43f314170000 (9=Rotkreuz 3=Bayern 1 Ort 0x25=037FZG 7141Status 3=Einsatz Ab 0=FZG->LST 2=IV (mit NA,mit SIGNAL)) CRC correct
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# ZVEI
|
||||||
|
# ----
|
||||||
|
#
|
||||||
|
|
||||||
|
#with csv description
|
||||||
|
ZVEI1: 12345
|
||||||
|
#without csv description
|
||||||
|
ZVEI1: 56789
|
||||||
|
#duplicate
|
||||||
|
ZVEI1: 56789
|
||||||
|
#with repeat Tone
|
||||||
|
ZVEI1: 1F2E3
|
||||||
|
#in case of invalid id
|
||||||
|
ZVEI1: 135
|
||||||
|
#in case of a double-tone for siren n-'D's are sended
|
||||||
|
# ZVEI1: DDD
|
||||||
|
# ZVEI1: DDDDD
|
||||||
Loading…
Reference in a new issue