mirror of
https://github.com/Schrolli91/BOSWatch.git
synced 2026-02-24 16:15:11 +01:00
Compare commits
473 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ebbaba6f1 | ||
|
|
52151c76b7 | ||
|
|
dff0c3b206 | ||
|
|
e2e7f01692 | ||
|
|
4f5b4854c7 | ||
|
|
b3d3e1cc82 | ||
|
|
e7a62ba1a3 | ||
|
|
68cb7c6b17 | ||
|
|
7fe98e2516 | ||
|
|
9101ce33e1 | ||
|
|
27ca5125aa | ||
|
|
b8c9edefe5 | ||
|
|
d833bc5389 | ||
|
|
b14fc23c8c | ||
|
|
fa039c0f03 | ||
|
|
8ee395ce26 | ||
|
|
7e4ba5188f | ||
|
|
4958ae4c1d | ||
|
|
0f95820bff | ||
|
|
3fd9e92bcd | ||
|
|
e582c4a030 | ||
|
|
9e659ebd11 | ||
|
|
d75800e8d3 | ||
|
|
28e9a91173 | ||
|
|
f2d1bec3b4 | ||
|
|
ac767ce020 | ||
|
|
a1bda7ebf6 | ||
|
|
fdd1260a52 | ||
|
|
a4ed7089b8 | ||
|
|
cdf37c417e | ||
|
|
1548e2fdfc | ||
|
|
f18e47334e | ||
|
|
9fb4e5fbe9 | ||
|
|
dac24eda19 | ||
|
|
abecd52377 | ||
|
|
784a38b3b3 | ||
|
|
52039a056e | ||
|
|
5bbb1b0106 | ||
|
|
6797ee52bf | ||
|
|
13692eb261 | ||
|
|
b46dc26a50 | ||
|
|
743f3d079c | ||
|
|
8ea90d5e53 | ||
|
|
b2d49244f8 | ||
|
|
a53d5609cc | ||
|
|
858ee854f2 | ||
|
|
82d282a87c | ||
|
|
75799dda80 | ||
|
|
c2b3c70a9c | ||
|
|
5136c6fb31 | ||
|
|
ab96a4db38 | ||
|
|
18358abec2 | ||
|
|
8eb2901bcb | ||
|
|
2a3243477c | ||
|
|
fd2392437f | ||
|
|
cf70393b2f | ||
|
|
572c40d1a4 | ||
|
|
6580d385f8 | ||
|
|
b4bb32a41b | ||
|
|
d9176db476 | ||
|
|
0bfd6d558c | ||
|
|
04af8f0359 | ||
|
|
44efa8a3b4 | ||
|
|
e14fbb1b2b | ||
|
|
9b5aa11462 | ||
|
|
1bb71d1375 | ||
|
|
c8f6ed52c0 | ||
|
|
c564993ce2 | ||
|
|
502f4036fb | ||
|
|
6912c59785 | ||
|
|
23e7406f48 | ||
|
|
a8eb55981d | ||
|
|
641bf4b81f | ||
|
|
cac07ed9ab | ||
|
|
344c0d8535 | ||
|
|
d4e87ed71c | ||
|
|
21013a05f6 | ||
|
|
587ddad079 | ||
|
|
6f8354d6cd | ||
|
|
3027178750 | ||
|
|
e20f49b7b2 | ||
|
|
4b87e21a6f | ||
|
|
cdd0d95e4d | ||
|
|
bf9ae8d5b3 | ||
|
|
d1b1c1c320 | ||
|
|
6054a38ff5 | ||
|
|
b9c6744667 | ||
|
|
09a497ef03 | ||
|
|
d4b397073e | ||
|
|
f0b9efb1b3 | ||
|
|
158e0d73fa | ||
|
|
6222463a96 | ||
|
|
e7bd6ae2c5 | ||
|
|
bd3e15ba57 | ||
|
|
f6523929b2 | ||
|
|
c113093ee3 | ||
|
|
3c92d4285f | ||
|
|
ad405829ea | ||
|
|
a7c657e447 | ||
|
|
7d67bd87ac | ||
|
|
219eb34322 | ||
|
|
c77391db88 | ||
|
|
4321234499 | ||
|
|
3fc0e6d27a | ||
|
|
ddbddbbcdd | ||
|
|
a5b4a4a889 | ||
|
|
0dfe1ee89c | ||
|
|
0181075d3e | ||
|
|
35b0c4d92e | ||
|
|
d432a423fb | ||
|
|
6ded657899 | ||
|
|
fd1c93326b | ||
|
|
c00022d834 | ||
|
|
3761eb8e28 | ||
|
|
d30bb515cd | ||
|
|
dc00fbc7a0 | ||
|
|
c631692bac | ||
|
|
c3589a9337 | ||
|
|
3d76997639 | ||
|
|
6b638c55b2 | ||
|
|
9f251bd544 | ||
|
|
656fe482c2 | ||
|
|
4b8f64795b | ||
|
|
ca26f1dc9a | ||
|
|
13073ec75a | ||
|
|
057945be47 | ||
|
|
18bde9d505 | ||
|
|
a994381de1 | ||
|
|
7904fc3275 | ||
|
|
85fcba43a5 | ||
|
|
9a8a00ef83 | ||
|
|
58c3a9134b | ||
|
|
edb2329ab7 | ||
|
|
1a75c1befb | ||
|
|
5120bd5751 | ||
|
|
116a06eb20 | ||
|
|
fa5acd4d79 | ||
|
|
2da87a46dd | ||
|
|
9e0e448520 | ||
|
|
9d708a0fcc | ||
|
|
82448a737a | ||
|
|
51709d0a61 | ||
|
|
016bd906c3 | ||
|
|
860f3d5e7d | ||
|
|
7a8afb1c51 | ||
|
|
dd82fe80ab | ||
|
|
c60c51e565 | ||
|
|
d45214627a | ||
|
|
0c19b5ece5 | ||
|
|
216ee05f18 | ||
|
|
9d8c9c986c | ||
|
|
6130efa762 | ||
|
|
dab072d03c | ||
|
|
7decb88d8b | ||
|
|
ad0673b357 | ||
|
|
33b633c475 | ||
|
|
52fe249ab6 | ||
|
|
5663bea32f | ||
|
|
22e13d76bf | ||
|
|
ae11c53fe6 | ||
|
|
483c4f167e | ||
|
|
fb188bc5ee | ||
|
|
42f841ba15 | ||
|
|
8599093a6c | ||
|
|
e2ed799b87 | ||
|
|
bd5f7f4707 | ||
|
|
190e7f36fe | ||
|
|
f4c35391b4 | ||
|
|
861253375f | ||
|
|
af887c2b23 | ||
|
|
9c0ed135bb | ||
|
|
b1170668b2 | ||
|
|
07a69d5e26 | ||
|
|
b3e63afc9c | ||
|
|
ea68fabc12 | ||
|
|
65dd9b495d | ||
|
|
d47635f6ea | ||
|
|
9a3d4ec12b | ||
|
|
d7b43ca808 | ||
|
|
f86aeb914b | ||
|
|
a360b1cd8a | ||
|
|
6332bd39a1 | ||
|
|
5fc8f92f42 | ||
|
|
94321415f5 | ||
|
|
04f98f21c4 | ||
|
|
1eae3098e0 | ||
|
|
2b89d49e7d | ||
|
|
11e948e4e9 | ||
|
|
3300e88f5c | ||
|
|
a1a96e7d7d | ||
|
|
5692cebdcb | ||
|
|
53efd1467a | ||
|
|
5681d33832 | ||
|
|
7605a14229 | ||
|
|
6fa93f2f99 | ||
|
|
f35ca75688 | ||
|
|
97e00d239c | ||
|
|
6bbffb111d | ||
|
|
0c6c682bb9 | ||
|
|
69452e9036 | ||
|
|
740f10dfae | ||
|
|
28d45966b2 | ||
|
|
5e978fbb2a | ||
|
|
203bbedaa9 | ||
|
|
de7947bec7 | ||
|
|
642b7e069e | ||
|
|
9ad1ed74ef | ||
|
|
a333b22a06 | ||
|
|
c26deb995e | ||
|
|
c00146ccd0 | ||
|
|
a4b19b66b9 | ||
|
|
2761ace2b0 | ||
|
|
4f8c15d7d0 | ||
|
|
942a738704 | ||
|
|
01eb1b870a | ||
|
|
9b33f78087 | ||
|
|
da4904e696 | ||
|
|
af9e01398c | ||
|
|
bf31a04e07 | ||
|
|
04ef809e51 | ||
|
|
56f62c33e1 | ||
|
|
110d3bf66f | ||
|
|
dbaedf83b5 | ||
|
|
9ad6da6af2 | ||
|
|
cf7e8ead5a | ||
|
|
95262e0c7c | ||
|
|
e5db9fed09 | ||
|
|
ce144c82e1 | ||
|
|
8c1351ccbd | ||
|
|
86c0467ee2 | ||
|
|
58ad0e5308 | ||
|
|
bbeda7f843 | ||
|
|
5e267c8c13 | ||
|
|
fadb1de813 | ||
|
|
6ce67f24dd | ||
|
|
aa20cd0cfb | ||
|
|
3ed90b4a97 | ||
|
|
9257cb2cfe | ||
|
|
0468db2647 | ||
|
|
14df7d7fa4 | ||
|
|
fcae71a7d1 | ||
|
|
5209ac0804 | ||
|
|
7566ff014c | ||
|
|
cf1b5b3fc4 | ||
|
|
f92ce0d5f8 | ||
|
|
098fcc2c46 | ||
|
|
173e552018 | ||
|
|
7fe28aa765 | ||
|
|
64a5fe5868 | ||
|
|
7c6611a072 | ||
|
|
52e724be5d | ||
|
|
16f576064e | ||
|
|
20becf5337 | ||
|
|
c212eac45b | ||
|
|
46f7719c89 | ||
|
|
b565a31637 | ||
|
|
25365b0ba0 | ||
|
|
5cabb9ab4d | ||
|
|
ba1c35b44d | ||
|
|
48e518deac | ||
|
|
cc81c30848 | ||
|
|
decd4461d7 | ||
|
|
a9ac73a634 | ||
|
|
9a63c25640 | ||
|
|
b96e099cea | ||
|
|
9fd07658f6 | ||
|
|
4f0caae300 | ||
|
|
fe96367769 | ||
|
|
76253ac900 | ||
|
|
4811477656 | ||
|
|
02d7ba2055 | ||
|
|
2b90ebef8a | ||
|
|
335a051cb0 | ||
|
|
4646012723 | ||
|
|
0539e33207 | ||
|
|
1771c2ec6f | ||
|
|
84932346b5 | ||
|
|
568ead750e | ||
|
|
e9b7cf17ba | ||
|
|
493624ea22 | ||
|
|
eb10fdce43 | ||
|
|
dbebc75d82 | ||
|
|
59b78a4f64 | ||
|
|
9c0c5e9358 | ||
|
|
3b2275094d | ||
|
|
3265c51316 | ||
|
|
9d06e38de9 | ||
|
|
fb82b1868d | ||
|
|
50a2c70408 | ||
|
|
c144205eb0 | ||
|
|
44821bbfcd | ||
|
|
66d2b4a79a | ||
|
|
fea211f32a | ||
|
|
2836f2857e | ||
|
|
c15de920ac | ||
|
|
5ec51d56cf | ||
|
|
9cad78f71c | ||
|
|
9e0e43ee13 | ||
|
|
c49c76dd6b | ||
|
|
2626a0418f | ||
|
|
7abc398a94 | ||
|
|
ec96317226 | ||
|
|
886dcf63d0 | ||
|
|
5f65e86922 | ||
|
|
b7141d986b | ||
|
|
b5d860f5cb | ||
|
|
8961148ecf | ||
|
|
307731dabe | ||
|
|
bcdac6e2e6 | ||
|
|
18425e2be2 | ||
|
|
3782974094 | ||
|
|
33706e5f2d | ||
|
|
cc66f4547a | ||
|
|
594ddb4452 | ||
|
|
578750a810 | ||
|
|
7fa4a97ba4 | ||
|
|
fca69b974e | ||
|
|
5b9c8d75d9 | ||
|
|
03cd002cfe | ||
|
|
de6073e8f6 | ||
|
|
cea266709c | ||
|
|
a74ef0fe45 | ||
|
|
0f13853cc8 | ||
|
|
cb0fd53713 | ||
|
|
cfcc12b445 | ||
|
|
e86059a2f3 | ||
|
|
e503130a03 | ||
|
|
3fed1ac12a | ||
|
|
fa90ba10cc | ||
|
|
63f2e58310 | ||
|
|
3220088e6c | ||
|
|
9aaa8aa267 | ||
|
|
9c446b0660 | ||
|
|
f701b6a010 | ||
|
|
b52d972c20 | ||
|
|
9aa163d5a8 | ||
|
|
6bcba28979 | ||
|
|
166dd3e3f8 | ||
|
|
eacb72adea | ||
|
|
d248a7d45d | ||
|
|
625d6b643e | ||
|
|
b6077d522d | ||
|
|
acbef6591c | ||
|
|
c54bd55888 | ||
|
|
fed717a22d | ||
|
|
9d552e5d24 | ||
|
|
c060da0a80 | ||
|
|
47bdff4b28 | ||
|
|
d4946bf714 | ||
|
|
b2df53430d | ||
|
|
760f6c1aba | ||
|
|
0774a58193 | ||
|
|
3aa0b382e9 | ||
|
|
45f4887163 | ||
|
|
00e4e52352 | ||
|
|
8069ded206 | ||
|
|
d45ff3b197 | ||
|
|
f6e4c8d3a9 | ||
|
|
736d0f95ce | ||
|
|
bd733b61b4 | ||
|
|
06d36b3b48 | ||
|
|
d30eee5866 | ||
|
|
07f42e15d8 | ||
|
|
0fc12abf44 | ||
|
|
2d8d5e42d9 | ||
|
|
167c0b90f3 | ||
|
|
2f3817c64f | ||
|
|
ae03473f94 | ||
|
|
8beb46f55a | ||
|
|
0ed8df0202 | ||
|
|
6af6981b68 | ||
|
|
f73e6f215b | ||
|
|
4a89ed44db | ||
|
|
55f55295d0 | ||
|
|
7fd88a452b | ||
|
|
70d769862c | ||
|
|
f171bda835 | ||
|
|
46a53dd8dc | ||
|
|
81a146b78f | ||
|
|
9ffa872b74 | ||
|
|
fbc3e53a1d | ||
|
|
e770937c6d | ||
|
|
3532a64cf1 | ||
|
|
990ef0ff1c | ||
|
|
5503ac0be8 | ||
|
|
c52c76aa50 | ||
|
|
f31532d79a | ||
|
|
c698a9eb15 | ||
|
|
afa224a9aa | ||
|
|
e5391a2b75 | ||
|
|
8a0c05f626 | ||
|
|
731d2c2d13 | ||
|
|
84b944348e | ||
|
|
4f29129007 | ||
|
|
53aa810df8 | ||
|
|
ac5db0dc98 | ||
|
|
84d39d0686 | ||
|
|
dfad66783e | ||
|
|
35e3ba8069 | ||
|
|
4c60d501b5 | ||
|
|
61398d95cb | ||
|
|
c02cd74586 | ||
|
|
42e7de7d4c | ||
|
|
256d726bc6 | ||
|
|
311b183265 | ||
|
|
2ab78cd7b9 | ||
|
|
98de4c077d | ||
|
|
c9ffd6ae0d | ||
|
|
c3398ccd3f | ||
|
|
a4c9d8197f | ||
|
|
f6d62828b8 | ||
|
|
67a1028081 | ||
|
|
0ab896b17a | ||
|
|
3ce29711a1 | ||
|
|
3b9da8eb0e | ||
|
|
f2e7c00fee | ||
|
|
d7896459ca | ||
|
|
78092389e9 | ||
|
|
3e1db59d46 | ||
|
|
daddd02279 | ||
|
|
aeedcd4c8c | ||
|
|
4202061bb7 | ||
|
|
418411e09c | ||
|
|
4e23d9856e | ||
|
|
bf9a604931 | ||
|
|
a4c218887b | ||
|
|
5ccd6d8cc0 | ||
|
|
58b3158e9a | ||
|
|
de451ffc6f | ||
|
|
80a9cdb6f4 | ||
|
|
4b296f1a39 | ||
|
|
d3cbbb60d8 | ||
|
|
fdd05c8643 | ||
|
|
d99574239b | ||
|
|
4e1cf00cb3 | ||
|
|
0694154d04 | ||
|
|
a2b7cb3b56 | ||
|
|
77f51e3509 | ||
|
|
5d98112480 | ||
|
|
5f4f6caa10 | ||
|
|
20746d66db | ||
|
|
fb4c922fef | ||
|
|
84b9d4ba61 | ||
|
|
2e03519333 | ||
|
|
142e2ba5b0 | ||
|
|
08c671cd09 | ||
|
|
642d95b11a | ||
|
|
1a9e2a34d1 | ||
|
|
1d62fe34f8 | ||
|
|
4aeb413f4f | ||
|
|
c77f2a9fdd | ||
|
|
38123fbf7c | ||
|
|
7d7c33e208 | ||
|
|
7abda0bc50 | ||
|
|
97f2956bc3 | ||
|
|
d6ce41f42b | ||
|
|
e3fcd9033d | ||
|
|
29ffd30391 | ||
|
|
8a8320f45f | ||
|
|
15aa38238f | ||
|
|
c6a0f8ecff | ||
|
|
d4c6a85b4f | ||
|
|
62fb787aef | ||
|
|
e2d20fed96 | ||
|
|
8244d7ac55 | ||
|
|
230187faef | ||
|
|
e0887fa0fb | ||
|
|
a29a4412bc | ||
|
|
88a4ae57ce | ||
|
|
98b50110a0 | ||
|
|
81e83e4c2e | ||
|
|
a1a48e4ec7 | ||
|
|
f946a9102b |
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: [Schrolli91] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -3,3 +3,11 @@
|
|||
*.log
|
||||
config.ini
|
||||
log/
|
||||
|
||||
\.project
|
||||
|
||||
\.pydevproject
|
||||
|
||||
\.settings/
|
||||
|
||||
\.idea/
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ sudo: required
|
|||
branches:
|
||||
only:
|
||||
- master
|
||||
- beta
|
||||
- develop
|
||||
|
||||
before_script:
|
||||
|
|
|
|||
135
CHANGELOG.md
Normal file
135
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
# Changelog
|
||||
|
||||
|
||||
### __[v2.5.2]__ - 08.01.2021
|
||||
##### Added
|
||||
- fhemCmd-Plugin: New plugin fhemCmd to execute commands in FHEM home automation. [#457](https://github.com/Schrolli91/BOSWatch/pull/457)
|
||||
- Add field "ricFuncChar" in data structure for POC messages as a combination of "ric" and "functionChar" for using in RegEx filter. [#459](https://github.com/Schrolli91/BOSWatch/pull/459)
|
||||
- MQTT Plugin: Send alarms to an MQTT broker [#498](https://github.com/Schrolli91/BOSWatch/pull/498)
|
||||
##### Changed
|
||||
- Divera Plugin: Add individual alarms for FMS, ZVEI and POC. [#451](https://github.com/Schrolli91/BOSWatch/pull/451)
|
||||
- install.sh: local git repo available at /opt/boswatch (or at your own path). Updates easier with `git pull` in /opt/boswatch. [#452](https://github.com/Schrolli91/BOSWatch/pull/452)
|
||||
- Telegram Plugin: Add support for simple HTML style message formatting. [#482](https://github.com/Schrolli91/BOSWatch/pull/482)
|
||||
##### Fixed
|
||||
- install.sh: old version of mysql-connector-python removed; add new via pip [#452](https://github.com/Schrolli91/BOSWatch/pull/452) [#445](https://github.com/Schrolli91/BOSWatch/issues/445)
|
||||
- GPIOcontrol plugin: Fixing indentation errors. [#465](https://github.com/Schrolli91/BOSWatch/pull/465)
|
||||
|
||||
|
||||
### __[v2.5.1]__ - 28.04.2020
|
||||
##### Added
|
||||
- Plugin requirements: Added requirements.txt for all plugins requiring extra python packages so the install will be easier [#446](https://github.com/Schrolli91/BOSWatch/pull/446)
|
||||
- DescriptionList POC: add new description parameter for Sub-RICs without a main RIC definition. parameter 'onlysubric'. [#449](https://github.com/Schrolli91/BOSWatch/pull/449)
|
||||
##### Fixed
|
||||
- MySQL plugin: Ensure character set (utf8mb4) and collation (utf8mb4_general_ci) are set correctly when connection to database is established. [#447](https://github.com/Schrolli91/BOSWatch/pull/447)
|
||||
- E-Mail plugin: Create MIME-compliant header that can contain any kind of string. [#448](https://github.com/Schrolli91/BOSWatch/pull/448)
|
||||
|
||||
|
||||
### __[v2.5]__ - 16.04.2020
|
||||
##### Added
|
||||
- Divera-Plugin: Plugin zum Ansteuern der Divera-Api. [#415](https://github.com/Schrolli91/BOSWatch/pull/415)
|
||||
- GPIO-Control: Plugin zum Ansteuern der GPIO Pins. [#438](https://github.com/Schrolli91/BOSWatch/pull/438)
|
||||
##### Changed
|
||||
- MySQL-Plugin: Index für die RIC Adresse hinzugefügt [#411](https://github.com/Schrolli91/BOSWatch/issues/411)
|
||||
- MySQL-Plugin: INSERT Befehl für MySQL 8.x angepasst, Spaltennamen escaped [#410](https://github.com/Schrolli91/BOSWatch/issues/410)
|
||||
- Pushover-Plugin: Konfigurationsmöglichkeit für den Sound [#418](https://github.com/Schrolli91/BOSWatch/issues/418)
|
||||
##### Fixed
|
||||
- Description-List: Buchstaben in FMS-Kennungen werden nun erkannt und zugelassen [#409](https://github.com/Schrolli91/BOSWatch/issues/409)
|
||||
- MySQL-Plugin: Volle UTF-8 Kompatibilität für Datenbankstruktur, Verbindung und Darstellung im WebUI [#398](https://github.com/Schrolli91/BOSWatch/issues/398)
|
||||
|
||||
|
||||
### __[v2.4.3]__ - 22.09.2019
|
||||
##### Added
|
||||
- Telegram-Plugin: In der generierten Übersichtkarte wird eine Anfahrtsroute integriert. Der Abfahrtsort ist konfiguierbar. [#382](https://github.com/Schrolli91/BOSWatch/pull/382)
|
||||
- Hue-Plugin: Geräte die mit einer Hue bridge verbunden sind können aus BOSWatch ein- und ausgeschaltet werden. [#394](https://github.com/Schrolli91/BOSWatch/issues/394)
|
||||
##### Changed
|
||||
- FFAgent Plugin: zusätzliches OrderedDict "alarmHeadersOrdered" implementiert um das HTTP Header Ordering sicherzustellen. Zusätzlich den HTTP Request mittels Session implementiert um das Header Ordering zu bewahren. Zusätzliches Debug Logging für die Header implementiert. [#356](https://github.com/Schrolli91/BOSWatch/issues/356)
|
||||
- POC-Decoder: Im POC-Text wird nach einem RegEx, welcher Koordinaten enthält, gesucht. Werden diese gefunden, so stehen zwei neu befüllte Data-Felder Lon bzw Lat zur Verfügung. [#405](https://github.com/Schrolli91/BOSWatch/pull/405)
|
||||
##### Fixed
|
||||
- Asynchrone Alarme: Bei asynchroner Verarbeitung von schnell aufeinander folgenden Alarmen, wurde der Inhalt der Objekte typ, freq und data bereits vor dem Abschluss der Verarbeitung eines Alarms wieder überschrieben. Ergebnis hiervon war die Vermischung von RICs und Texten unterschiedlicher Alarme. Lösung über copy.deepcopy() [#394](https://github.com/Schrolli91/BOSWatch/issues/394)
|
||||
- POC-Decoder: Bug wegen nicht zugeweisener Variable 'has_geo' [#410](https://github.com/Schrolli91/BOSWatch/issues/413) [HOTFIX]
|
||||
|
||||
|
||||
### __[v2.4.2]__ - 11.03.2019
|
||||
##### Added
|
||||
- Telegram-Plugin: In der generierten Übersichtkarte wird eine Anfahrtsroute integriert. Der Abfahrtsort ist konfiguierbar. [#382](https://github.com/Schrolli91/BOSWatch/pull/382)
|
||||
##### Changed
|
||||
- Telegram-Plugin: Aufrufe der Google API erfolgen per SSL und ohne zusätzliche Bibliotheken [#382](https://github.com/Schrolli91/BOSWatch/pull/382)
|
||||
|
||||
|
||||
### __[v2.4.1]__ - 23.10.2018
|
||||
##### Added
|
||||
- Pushover-Plugin: Priorität für einzelne RIC und ZVEI in config einstellbar [#378](https://github.com/Schrolli91/BOSWatch/pull/378)
|
||||
##### Changed
|
||||
- Kleinere Anpassungen im Telegram Plugin (Karten-Generierung) [#380](https://github.com/Schrolli91/BOSWatch/pull/380)
|
||||
##### Removed
|
||||
- Notify-my-Andoird Plugin und Logging-Handler wegen Einstellung des Service entfernt [#374](https://github.com/Schrolli91/BOSWatch/pull/374)
|
||||
|
||||
|
||||
### __[v2.4]__ - 17.08.2018
|
||||
##### Added
|
||||
- Config Eintrag um Port für MySQL Plugin festzulegen [#345](https://github.com/Schrolli91/BOSWatch/pull/345)
|
||||
- FMS und ZVEI Support für Pushover Plugin [#352](https://github.com/Schrolli91/BOSWatch/pull/352)
|
||||
- Benutzerdefinierte Nachrichten für Pushover Plugin in config [#352](https://github.com/Schrolli91/BOSWatch/pull/352)
|
||||
##### Changed
|
||||
- multicastAlarm Plugin - RICs die von multicastAlarm genutzt werden, müssen nicht mehr in der config bei allow_ric bzw. filter_range_start/filter_range_end berücksichtigt werden. [#357](https://github.com/Schrolli91/BOSWatch/pull/357)
|
||||
- FFAgent Plugin - Debug Logging für die alarmHeaders eingebaut zwecks Troubleshooting [#354](https://github.com/Schrolli91/BOSWatch/pull/354)
|
||||
- multicastAlarm Plugin - Buffer nach jedem Alarm löschen - erlaubt in kombination mit "doubleFilter_check_msg" die Verwendung in Netzen, die zwischen multicastAlarm RICs auch normale Alarme senden. [#370](https://github.com/Schrolli91/BOSWatch/pull/370)
|
||||
##### Fixed
|
||||
- Fehler beim Auslesen der netIdent_RIC im MySQL Plugin [#347](https://github.com/Schrolli91/BOSWatch/pull/347)
|
||||
- FFAgent Plugin - Typo bei alarmHeaders für Live Betrieb gefixt [#354](https://github.com/Schrolli91/BOSWatch/pull/354)
|
||||
|
||||
|
||||
### __[v2.3]__ - 22.12.2017
|
||||
##### Added
|
||||
- zuschaltbare POCSAG Multicast-Alarm Funktionalität [#307](https://github.com/Schrolli91/BOSWatch/pull/307)
|
||||
- Flag in Config um nur letzte Net Ident oder gesamte Historie zu speichern [#317](https://github.com/Schrolli91/BOSWatch/pull/317)
|
||||
##### Removed
|
||||
- Beta Branch aus Readme, Installer und Travis-CI entfernt [#324](https://github.com/Schrolli91/BOSWatch/pull/324)
|
||||
##### Fixed
|
||||
- Bug in httpRequest Plugin (data Field wurde überschrieben) [#337](https://github.com/Schrolli91/BOSWatch/pull/337)
|
||||
- Kommentar für FirEmergency Einstellung angepasst [#338](https://github.com/Schrolli91/BOSWatch/pull/338)
|
||||
|
||||
|
||||
### __[v2.2.2]__ - 21.10.2017
|
||||
##### Added
|
||||
- Installations Script für Services [#316](https://github.com/Schrolli91/BOSWatch/pull/316)
|
||||
##### Changed
|
||||
- Telegram Plugin importiert Google Maps Funktionen nur noch wenn API Key eingetragen ist [#315](https://github.com/Schrolli91/BOSWatch/pull/315)
|
||||
- Versions Nummer und Branch Name getrennt [3fed1ac](https://github.com/Schrolli91/BOSWatch/commit/3fed1ac12af8690213766e0e81d71c237530ed2c)
|
||||
##### Deprecated
|
||||
- Beta Branch wird mit nächstem Update entfernt [Forum](http://boswatch.de/index.php?thread/16-beta-branch-abschaffen/&postID=113#post113)
|
||||
##### Fixed
|
||||
- Schreibfehler der Pfadangabe im Installer [#317](https://github.com/Schrolli91/BOSWatch/pull/317)
|
||||
- Schreibfehler in Service Readme [#313](https://github.com/Schrolli91/BOSWatch/issues/313)
|
||||
- Einige Code-Style Verbesserungen [#310](https://github.com/Schrolli91/BOSWatch/pull/310)
|
||||
|
||||
|
||||
### __[v2.2.1]__ - 19.09.2017
|
||||
##### Added
|
||||
- Neues Service Script [#263](https://github.com/Schrolli91/BOSWatch/pull/263)
|
||||
- Eigene Message für jeden Typ im Telegram Plugin in der config definierbar [#267](https://github.com/Schrolli91/BOSWatch/pull/267)
|
||||
- httpRequest Plugin unterstützt nun mehrere URLs [254](https://github.com/Schrolli91/BOSWatch/pull/254)
|
||||
|
||||
##### Changed
|
||||
- Name der csv Dateien geändert um überschreiben bei Update zu vermeiden [#262](https://github.com/Schrolli91/BOSWatch/pull/262)
|
||||
- Description Liste kann nun zusätzlich Einträge für jede Subric enthalten (POCSAG) [#271](https://github.com/Schrolli91/BOSWatch/pull/271)
|
||||
- RegEX verbietet nun grundsätzlich alles - Es muss explizit zugelassen werden (wenn RegEX aktiv) [#284](https://github.com/Schrolli91/BOSWatch/pull/284)
|
||||
|
||||
##### Fixed
|
||||
- Bug im SMS77 Plugin behoben [#257](https://github.com/Schrolli91/BOSWatch/issues/257)
|
||||
- einige Code-Style Verbesserungen
|
||||
|
||||
|
||||
----------------------------
|
||||
|
||||
|
||||
Zum schreiben des Changelog's siehe:
|
||||
http://keepachangelog.com/de/1.0.0/
|
||||
|
||||
### __[v#.#]__ - unreleased
|
||||
##### Added
|
||||
##### Changed
|
||||
##### Deprecated
|
||||
##### Removed
|
||||
##### Fixed
|
||||
##### Security
|
||||
118
Konzept.md
118
Konzept.md
|
|
@ -1,118 +0,0 @@
|
|||
# BOSWatch 3.0
|
||||
============
|
||||
|
||||
|
||||
Verpacken der Funktionalitäten in Klassen um OOP-Grundsätze zu erreichen.
|
||||
|
||||
|
||||
|
||||
## Dekodierung und Auswertung trennen.
|
||||
|
||||
### Client:
|
||||
- reine Dekodierung mittels rtl-fm und multimon
|
||||
- Keine Filter usw. nur die Dekoder, Daten verpacken, verschicken
|
||||
- per TCP Socket an den Server
|
||||
|
||||
### Server:
|
||||
- Empfängt die TCP Socket Pakete der einzelnen Clients
|
||||
- Durch doubleFiltering fallen doppelt eingehende Alarme der Clienten sowieso raus
|
||||
- Danach Filterung usw. dann call an die plugins
|
||||
|
||||
|
||||
|
||||
## Konfiguration:
|
||||
- Alle Einstellungen in INI File
|
||||
- Einziges Argument beim Start des Clienten ist der Name der INI (-v -q -t sollen auch bleiben)
|
||||
- So werden mehrere Sticks auf einem Rechner einfach möglich ohne BOSWatch Ordner kopieren zu müssen
|
||||
|
||||
### Client:
|
||||
|
||||
```
|
||||
[Server]
|
||||
IP = 127.0.0.1
|
||||
PORT = 23
|
||||
|
||||
[Client]
|
||||
Name = BOSWatch Client 1
|
||||
LogDir = log/
|
||||
|
||||
[Stick]
|
||||
device = 0
|
||||
Frequency = 85...M
|
||||
PPMError = 0
|
||||
Squelch = 0
|
||||
gain = 100
|
||||
|
||||
[Decoder]
|
||||
FMS = 0
|
||||
ZVEI = 0
|
||||
POC512 = 0
|
||||
POC1200 = 1
|
||||
POC2400 = 0
|
||||
```
|
||||
|
||||
### Server:
|
||||
```
|
||||
[Server]
|
||||
PORT = 23
|
||||
|
||||
[Filter]
|
||||
...
|
||||
|
||||
[Plugins]
|
||||
MySQL = 1
|
||||
template = 0
|
||||
...
|
||||
```
|
||||
|
||||
### Plugin:
|
||||
- Konfigurations Datei für Plugin mit in den Plugin Ordner
|
||||
- Plugin läd bei Bedarf seine Config selbst, die geht BOSWatch ja nichts an
|
||||
- Aktuell wird eine ewig lange Config geladen, obwohl 90% der Plugins nicht genutzt werden
|
||||
|
||||
|
||||
|
||||
## Filterung
|
||||
Ein Vernünftiges Filterkonzept sollte aufgestellt werden, welches bei POC, FMS und ZVEI gleichermaßen funktioniert
|
||||
und daher nicht 3 mal implementiert erden muss.
|
||||
|
||||
|
||||
|
||||
## Versions Überprüfung
|
||||
|
||||
über die LIB sched.py - https://docs.python.org/3/library/sched.html - können Zeitgesteuerte Events gestartet werden.
|
||||
Dies kann zur Überprüfung einer neuen Software version verwendet werden.
|
||||
information des Nutzers muss noch überlegt werden - evtl als "Alarm" absetzen über normalen Plugin weg.
|
||||
|
||||
|
||||
|
||||
## Code Dokumentation
|
||||
Dokumentiert werden sollten alle Funktion und Klassen in Doxygen gerechter Notation.
|
||||
Genaue Erklärung und Bennenung der Tags in der Doxygen Hilfe
|
||||
```
|
||||
class Hello:
|
||||
## @brief Short description.
|
||||
# Longer description.
|
||||
#
|
||||
# @param self
|
||||
# @param name Another Parameter
|
||||
# @return value Returns a Value
|
||||
|
||||
def __init__(self, name):
|
||||
## @brief Constructor
|
||||
# Longer description optinal.
|
||||
#
|
||||
# @param self
|
||||
# @param name Another Parameter
|
||||
dosomething(12)
|
||||
|
||||
def dosomething(self, x):
|
||||
## @brief Do something
|
||||
# Longer description for do something.
|
||||
#
|
||||
# @param self
|
||||
# @param x Another Parameter
|
||||
# @return value Returns a 0
|
||||
dosomethingelse
|
||||
return 0
|
||||
```
|
||||
109
README.md
109
README.md
|
|
@ -1,32 +1,43 @@
|
|||
|Branch|Code Qualität|CI-Build|
|
||||
|---|---|---|
|
||||
|master|[](https://www.codacy.com/app/Schrolli91/BOSWatch/dashboard?bid=3763821)|[](https://travis-ci.org/Schrolli91/BOSWatch)|
|
||||
|beta|[](https://www.codacy.com/app/Schrolli91/BOSWatch/dashboard?bid=4213030)|[](https://travis-ci.org/Schrolli91/BOSWatch)|
|
||||
|develop|[](https://www.codacy.com/app/Schrolli91/BOSWatch/dashboard?bid=3763820)|[](https://travis-ci.org/Schrolli91/BOSWatch)|
|
||||
|
||||
|
||||
**Unterstützung gesucht**
|
||||
|
||||
Zur Weiterentwicklung des Programms benötigen wir Deine Mithilfe - bitte melde dich per Issue, wenn du Anwender in einem verschlüsselten POCSAG-Netz und im (legalen) Besitz des dazugehörigen Schlüssels bist.
|
||||
In der Zukunft wollen wir die Möglichkeit schaffen, codierte Nachrichten zu entschlüsseln (und nur dann, wenn der Schlüssel bekannt ist!), dafür brauchen wir Dich als Tester!
|
||||
|
||||
**Readme ist veraltet** - bitte im [Wiki](https://github.com/Schrolli91/BOSWatch/wiki) nachschauen!
|
||||
|
||||

|
||||
|
||||
:satellite: Python Script to receive and decode German BOS Information with rtl_fm and multimon-NG :satellite:
|
||||
|
||||
#### WICHTIG
|
||||
**Es wird darauf hingewiesen, dass für die Teilnahme am BOS-Funk nur nach den Technischen Richtlinien der BOS zugelassene Funkanlagen verwendet werden dürfen.**
|
||||
**Der BOS-Funk ist ein nichtöffentlicher mobiler Landfunk. Privatpersonen gehören nicht zum Kreis der berechtigten Funkteilnehmer.** _(Quelle: TR-BOS)_
|
||||
|
||||
#### Notice:
|
||||
The intercept of the German BOS radio is **strictly prohibited** and will be prosecuted. the use is **only authorized** personnel permitted.
|
||||
The software was developed using the Multimon-NG code, a function in the real operation can not be guaranteed.
|
||||
|
||||
|
||||
### Fast support on https://bwcc.boswatch.de (Mattermost)
|
||||
### BW3 in first testing phase - see: https://github.com/BOSWatch/BW3-Core
|
||||
|
||||
|Branch|Code Qualität|CI-Build|
|
||||
|---|---|---|
|
||||
|master|[](https://www.codacy.com/app/Schrolli91/BOSWatch/dashboard?bid=3763821)|[](https://travis-ci.org/Schrolli91/BOSWatch)|
|
||||
|develop|[](https://www.codacy.com/app/Schrolli91/BOSWatch/dashboard?bid=3763820)|[](https://travis-ci.org/Schrolli91/BOSWatch)|
|
||||
|
||||
|
||||
**Unterstützung gesucht**
|
||||
|
||||
Zur Weiterentwicklung des Programms benötigen wir Deine Mithilfe - bitte melde dich per Issue, wenn du Anwender in einem verschlüsselten POCSAG-Netz und im **legalen** Besitz des dazugehörigen Schlüssels bist.
|
||||
In der Zukunft wollen wir die Möglichkeit schaffen, codierte Nachrichten zu entschlüsseln (und nur dann, wenn der Schlüssel bekannt ist!), dafür brauchen wir Dich als Tester!
|
||||
|
||||
**Readme ist veraltet** - bitte im [Wiki](https://github.com/Schrolli91/BOSWatch/wiki) nachschauen!
|
||||
|
||||
|
||||
|
||||
**Please** only use Code from **master**-Branch - thats **the only stable!**
|
||||
|
||||
beta-branch is for beta-test of new features
|
||||
|
||||
unless you are developer you can use the develop-Branch - may be unstable!
|
||||
|
||||
### Features
|
||||
##### Implemented features:
|
||||
**list is not complete!**
|
||||
- FMS, ZVEI and POCSAG512/1200/2400 decoding and displaying
|
||||
- Plugin support for easy functional extension
|
||||
- Filtering double alarms with adjustable time and check width
|
||||
|
|
@ -40,31 +51,14 @@ unless you are developer you can use the develop-Branch - may be unstable!
|
|||
- Ready for use BOSWatch as daemon
|
||||
- possibility to start plugins asynchron
|
||||
- NMA Error Handler
|
||||
|
||||
##### Features for the future:
|
||||
- more plugins
|
||||
- other Ideas per Issues please
|
||||
- multicastAlarm for transmission optimized networks
|
||||
|
||||
|
||||
###Plugins
|
||||
### Plugins
|
||||
If you want to code your own Plugin, see `plugins/README.md`.
|
||||
|
||||
##### Implemented plugins:
|
||||
|
||||
|Plugin|Function|FMS|ZVEI|POC|
|
||||
|-----|---------|:-:|:--:|:-:|
|
||||
|MySQL|insert data into MySQL database|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
||||
|httpRequest|send a request with parameter to an URL|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
||||
|eMail|send Mails with own text|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
||||
|BosMon|send data to BosMon server|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
||||
|firEmergency|send data to firEmergency server|:x:|:white_check_mark:|:white_check_mark:|
|
||||
|jsonSocket|send data as jsonString to a socket server|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
||||
|NMA|send data to Notify my Android|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
||||
|
||||
- for more Information to the plugins see `config.ini`
|
||||
|
||||
##### Plugins for the Future:
|
||||
- Ideas per Issues please
|
||||
please look at the wiki page
|
||||
|
||||
|
||||
### Configuration
|
||||
|
|
@ -81,7 +75,7 @@ For the other functions see "Usage" below.
|
|||
For the RegEX filter functions see Section `[Filters]`
|
||||
http://www.regexr.com/ - RegEX test tool an documentation
|
||||
|
||||
No filter for a combination typ/plugin = all data will pass
|
||||
If RegEX is enabled - only allowed data will pass !
|
||||
|
||||
Syntax: `INDIVIDUAL_NAME = TYP;DATAFIELD;PLUGIN;FREQUENZ;REGEX` (separator `;`)
|
||||
- `TYP` = the data typ (FMS|ZVEI|POC)
|
||||
|
|
@ -105,52 +99,15 @@ Take a look into the parser.php for the parsing functions~~
|
|||
|
||||
|
||||
### Usage
|
||||
`sudo python boswatch.py -f 85.235M -a FMS ZVEI`
|
||||
Starts boswatch at frequency 85.235 MHz with the demodulation functions FMS and ZVEI.
|
||||
Parameter -f/--freq and -a/--demod are required!
|
||||
|
||||
Help to all usable parameters with `sudo python boswatch.py -h`
|
||||
|
||||
```
|
||||
usage: boswatch.py [-h] -f FREQ [-d DEVICE] [-e ERROR] -a
|
||||
{FMS,ZVEI,POC512,POC1200,POC2400}
|
||||
[{FMS,ZVEI,POC512,POC1200,POC2400} ...] [-s SQUELCH] [-v]
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-f FREQ, --freq FREQ Frequency you want to listen
|
||||
-d DEVICE, --device DEVICE Device you want to use (Check with rtl_test)
|
||||
-e ERROR, --error ERROR Frequency-Error of your device in PPM
|
||||
-a {FMS,ZVEI,POC512,POC1200,POC2400} [{FMS,ZVEI,POC512,POC1200,POC2400} ...],
|
||||
--demod {FMS,ZVEI,POC512,POC1200,POC2400} [{FMS,ZVEI,POC512,POC1200,POC2400} ...]
|
||||
Demodulation functions
|
||||
-s SQUELCH, --squelch SQUELCH level of squelch
|
||||
-u, --usevarlog Use '/var/log/boswatch' for logfiles instead of subdir 'log' in BOSWatch directory
|
||||
-v, --verbose Shows more information
|
||||
-q, --quiet Shows no information. Only logfiles
|
||||
```
|
||||
|
||||
please look at the wiki page
|
||||
|
||||
### Installation
|
||||
Please follow the instructions written down in the wiki:
|
||||
|
||||
https://github.com/Schrolli91/BOSWatch/wiki
|
||||
|
||||
You just need to download a single file since the installer manages the whole process except the installation of a webserver and a database.
|
||||
please look at the wiki page
|
||||
|
||||
If you want to use BOSWatch as a daemon, you have to set your
|
||||
configuration in `service/boswatch.sh` and copy it to `/etc/init.d`.
|
||||
Then you can start BOSWatch with `sudo /etc/init.d/boswatch.sh start`.
|
||||
For configuration-details see `service/README.md`.
|
||||
|
||||
### Requirements
|
||||
- RTL_SDR (rtl_fm)
|
||||
- Multimon-NG
|
||||
- Python Support
|
||||
- MySQL Connector for Python (for MySQL-plugin)
|
||||
|
||||
Thanks to smith_fms and McBo from Funkmeldesystem.de - Forum for Inspiration and Groundwork!
|
||||
|
||||
|
||||
### Code your own Plugin
|
||||
See `plugins/README.md`
|
||||
##### Big thanks
|
||||
to smith_fms and McBo from Funkmeldesystem.de - Forum for Inspiration and Groundwork!
|
||||
|
|
|
|||
43
boswatch.py
43
boswatch.py
|
|
@ -18,11 +18,12 @@ GitHUB: https://github.com/Schrolli91/BOSWatch
|
|||
import logging
|
||||
import logging.handlers
|
||||
|
||||
import argparse # for parse the args
|
||||
import ConfigParser # for parse the config file
|
||||
import os # for log mkdir
|
||||
import time # for time.sleep()
|
||||
import subprocess # for starting rtl_fm and multimon-ng
|
||||
import argparse # for parse the args
|
||||
import ConfigParser # for parse the config file
|
||||
import os # for log mkdir
|
||||
import sys # for py version
|
||||
import time # for time.sleep()
|
||||
import subprocess # for starting rtl_fm and multimon-ng
|
||||
|
||||
from includes import globalVars # Global variables
|
||||
from includes import MyTimedRotatingFileHandler # extension of TimedRotatingFileHandler
|
||||
|
|
@ -162,7 +163,9 @@ try:
|
|||
#
|
||||
try:
|
||||
logging.debug("SW Version: %s",globalVars.versionNr)
|
||||
logging.debug("Branch: %s",globalVars.branch)
|
||||
logging.debug("Build Date: %s",globalVars.buildDate)
|
||||
logging.debug("Python Vers: %s",sys.version)
|
||||
logging.debug("BOSWatch given arguments")
|
||||
if args.test:
|
||||
logging.debug(" - Test-Mode!")
|
||||
|
|
@ -178,7 +181,7 @@ try:
|
|||
demodulation += "-a FMSFSK "
|
||||
logging.debug(" - Demod: FMS")
|
||||
if "ZVEI" in args.demod:
|
||||
demodulation += "-a ZVEI2 "
|
||||
demodulation += "-a ZVEI1 "
|
||||
logging.debug(" - Demod: ZVEI")
|
||||
if "POC512" in args.demod:
|
||||
demodulation += "-a POCSAG512 "
|
||||
|
|
@ -217,9 +220,14 @@ try:
|
|||
# if given loglevel is debug:
|
||||
if globalVars.config.getint("BOSWatch","loglevel") == 10:
|
||||
configHandler.checkConfig("BOSWatch")
|
||||
configHandler.checkConfig("multicastAlarm")
|
||||
configHandler.checkConfig("Filters")
|
||||
configHandler.checkConfig("FMS")
|
||||
configHandler.checkConfig("ZVEI")
|
||||
configHandler.checkConfig("POC")
|
||||
configHandler.checkConfig("Plugins")
|
||||
configHandler.checkConfig("Filters")
|
||||
#NMAHandler is outputed below
|
||||
except:
|
||||
# we couldn't work without config -> exit
|
||||
logging.critical("cannot read config file")
|
||||
|
|
@ -241,29 +249,6 @@ try:
|
|||
logging.debug("cannot set loglevel of fileHandler", exc_info=True)
|
||||
|
||||
|
||||
#
|
||||
# Add NMA logging handler
|
||||
#
|
||||
try:
|
||||
if configHandler.checkConfig("NMAHandler"):
|
||||
# is NMAHandler enabled?
|
||||
if globalVars.config.getboolean("NMAHandler", "enableHandler") == True:
|
||||
# we only could do something, if an APIKey is given:
|
||||
if len(globalVars.config.get("NMAHandler","APIKey")) > 0:
|
||||
logging.debug("add NMA logging handler")
|
||||
from includes import NMAHandler
|
||||
if globalVars.config.get("NMAHandler","appName") == "":
|
||||
nmaHandler = NMAHandler.NMAHandler(globalVars.config.get("NMAHandler","APIKey"))
|
||||
else:
|
||||
nmaHandler = NMAHandler.NMAHandler(globalVars.config.get("NMAHandler","APIKey"), globalVars.config.get("NMAHandler","appName"))
|
||||
nmaHandler.setLevel(globalVars.config.getint("NMAHandler","loglevel"))
|
||||
myLogger.addHandler(nmaHandler)
|
||||
except:
|
||||
# It's an error, but we could work without that stuff...
|
||||
logging.error("cannot add NMA logging handler")
|
||||
logging.debug("cannot add NMA logging handler", exc_info=True)
|
||||
|
||||
|
||||
# initialization was fine, continue with main program...
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -114,6 +114,26 @@ ricd = Unwetter
|
|||
# Usually sent periodically, separated by comma
|
||||
netIdent_ric = 0174760, 1398098
|
||||
|
||||
|
||||
[multicastAlarm]
|
||||
# Configure multicastAlarm if your POCSAG network uses an optimized transmission scheme for alarms with more than one RIC (often found in Swissphone networks).
|
||||
# In this optimized transmission scheme, a POCSAG telegram with each RIC that needs to be alarmed will be send in a sequence. These telegrams are send without a text message. This sequence is directly followed by a telegram with a specific RIC and the text message that belongs to the sequnece send right before.
|
||||
# A POCSAG pager (DME) can be configured to start an acoustic alarm if a specific RIC without text has been received. If afterwards the specific RIC with the text message will be received, the pager will show the message in it's display.
|
||||
# multicastAlarm enables BOSwatch to process the all received RICs joined with the text message.
|
||||
#
|
||||
# enable multicastAlarm (0 - off | 1 - on)
|
||||
multicastAlarm = 0
|
||||
|
||||
# time limit for alarms that do not belong to the multicastAlarm sequence in seconds
|
||||
multicastAlarm_ignore_time = 15
|
||||
|
||||
# multicastAlarm delimiter RIC (usually used as a starting point for a alarm sequence) (can be empty)
|
||||
multicastAlarm_delimiter_ric =
|
||||
|
||||
# multicastAlarm RIC that is used to send the text message
|
||||
multicastAlarm_ric =
|
||||
|
||||
|
||||
[Filters]
|
||||
# RegEX Filter Configuration
|
||||
# http://www.regexr.com/ - RegEX Test Tool an Documentation
|
||||
|
|
@ -154,8 +174,10 @@ template = 0
|
|||
|
||||
[MySQL]
|
||||
# MySQL configuration
|
||||
#default port: 3306
|
||||
dbserver = localhost
|
||||
dbuser = root
|
||||
dbport = 3306
|
||||
dbuser = boswatch
|
||||
dbpassword = root
|
||||
database = boswatch
|
||||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,26 @@ ricd = Unwetter
|
|||
# Usually sent periodically, separated by comma
|
||||
netIdent_ric = 0174760, 1398098
|
||||
|
||||
|
||||
[multicastAlarm]
|
||||
# Configure multicastAlarm if your POCSAG network uses an optimized transmission scheme for alarms with more than one RIC (often found in Swissphone networks).
|
||||
# In this optimized transmission scheme, a POCSAG telegram with each RIC that needs to be alarmed will be send in a sequence. These telegrams are send without a text message. This sequence is directly followed by a telegram with a specific RIC and the text message that belongs to the sequnece send right before.
|
||||
# A POCSAG pager (DME) can be configured to start an acoustic alarm if a specific RIC without text has been received. If afterwards the specific RIC with the text message will be received, the pager will show the message in it's display.
|
||||
# multicastAlarm enables BOSwatch to process the all received RICs joined with the text message.
|
||||
#
|
||||
# enable multicastAlarm (0 - off | 1 - on)
|
||||
multicastAlarm = 0
|
||||
|
||||
# time limit for alarms that do not belong to the multicastAlarm sequence in seconds
|
||||
multicastAlarm_ignore_time = 15
|
||||
|
||||
# multicastAlarm delimiter RIC (usually used as a starting point for a alarm sequence) (can be empty)
|
||||
multicastAlarm_delimiter_ric =
|
||||
|
||||
# multicastAlarm RIC that is used to send the text message
|
||||
multicastAlarm_ric =
|
||||
|
||||
|
||||
[Filters]
|
||||
# RegEX Filter Configuration
|
||||
# http://www.regexr.com/ - RegEX Test Tool an Documentation
|
||||
|
|
@ -154,7 +174,9 @@ template = 0
|
|||
|
||||
[MySQL]
|
||||
# MySQL configuration
|
||||
#default port: 3306
|
||||
dbserver = localhost
|
||||
dbport = 3306
|
||||
dbuser = boswatch
|
||||
dbpassword = root
|
||||
database = boswatch
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ POCSAG512: Address: 1000003 Function: 3 Alpha: BOSWatch-Test: okay
|
|||
POCSAG512: Address: 1200001 Function: 1 Alpha: BOSWatch-Test ÖÄÜß: okay
|
||||
POCSAG512: Address: 1200001 Function: 1 Alpha: BOSWatch-Test öäü: okay
|
||||
|
||||
# witch csv
|
||||
# with csv
|
||||
POCSAG512: Address: 1234567 Function: 1 Alpha: BOSWatch-Test: with csv
|
||||
|
||||
# without csv
|
||||
|
|
@ -86,6 +86,22 @@ POCSAG1200: Address: 7777777 Function: 1 Alpha: BOSWatch-Test: denied
|
|||
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?
|
||||
|
||||
|
||||
|
|
@ -106,15 +122,15 @@ FMS: 43f314170000 (9=Rotkreuz 3=Bayern 1 Ort 0x25=037FZG 7141Stat
|
|||
#
|
||||
|
||||
#with csv description
|
||||
ZVEI2: 12345
|
||||
ZVEI1: 12345
|
||||
#without csv description
|
||||
ZVEI2: 56789
|
||||
ZVEI1: 56789
|
||||
#duplicate
|
||||
ZVEI2: 56789
|
||||
ZVEI1: 56789
|
||||
#with repeat Tone
|
||||
ZVEI2: 1F2F3
|
||||
ZVEI1: 1F2F3
|
||||
#in case of invalid id
|
||||
ZVEI2: 135
|
||||
ZVEI1: 135
|
||||
#in case of a double-tone for siren n-'D's are sended
|
||||
ZVEI2: DDD
|
||||
ZVEI2: DDDDD
|
||||
ZVEI1: DDD
|
||||
ZVEI1: DDDDD
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
Can't render this file because it has a wrong number of fields in line 2.
|
10
csv/poc.csv
10
csv/poc.csv
|
|
@ -1,10 +0,0 @@
|
|||
ric,description
|
||||
#
|
||||
# BOSWatch CSV file for describing POCSAG-Addresses
|
||||
#
|
||||
# For each RIC-Address you could set a description-text
|
||||
# Use the structure: ric,"Description-Text"
|
||||
#
|
||||
# !!! DO NOT delete the first line !!!
|
||||
#
|
||||
1234567,"POCSAG testdata äöüß"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
22
csv/poc.template.csv
Normal file
22
csv/poc.template.csv
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
ric,description
|
||||
#
|
||||
# BOSWatch CSV file for describing POCSAG-Addresses
|
||||
#
|
||||
# For each RIC-Address you could set a description-text
|
||||
# Use the structure: ric,"Description-Text"
|
||||
#
|
||||
# main RIC with subric:
|
||||
# You can even define specific subrics, therefore you
|
||||
# 1. need to specify a main RIC: 1234567, "Unit One"
|
||||
# 2. specify a certain subric: 1234567B, "Subunit Bravo"
|
||||
# The result for 1234567B will be "Unit One Subunit Bravo"
|
||||
# - Be sure having defined the main RIC (step one)! -
|
||||
#
|
||||
# Only subric:
|
||||
# Specify only the subric: 123457B, "Subunit Bravo"
|
||||
# The result for 1234567B will be "Subunit Bravo"
|
||||
# - main RIC is not required -
|
||||
#
|
||||
# !!! DO NOT delete the first line !!!
|
||||
#
|
||||
1234567,"POCSAG testdata äöüß"
|
||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
Can't render this file because it has a wrong number of fields in line 2.
|
|
|
@ -36,7 +36,7 @@ CREATE TABLE `login` (
|
|||
|
||||
LOCK TABLES `login` WRITE;
|
||||
/*!40000 ALTER TABLE `login` DISABLE KEYS */;
|
||||
INSERT INTO `login` VALUES ,(1,'Test','098f6bcd4621d373cade4e832627b4f6');
|
||||
INSERT INTO `login` VALUES (1,'admin',md5('admin'));
|
||||
/*!40000 ALTER TABLE `login` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
$dbhost = "localhost";
|
||||
$dbuser = "USERNAME";
|
||||
$dbpassword = "PASSWORD";
|
||||
$dbuser = "boswatch";
|
||||
$dbpassword = "boswatch";
|
||||
$database = "boswatch";
|
||||
|
||||
$tableFMS = "bos_fms";
|
||||
|
|
|
|||
57
exampleAddOns/alarmMonitorWeb/do_eintragen.php
Normal file
57
exampleAddOns/alarmMonitorWeb/do_eintragen.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
<?php
|
||||
session_start();
|
||||
?>
|
||||
|
||||
<?php
|
||||
if(($_SESSION["username"])!="admin")
|
||||
{
|
||||
echo "Sie sind nicht berechtigt fuer diesen Bereich";
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
@require_once("config.php");
|
||||
$verbindung = mysqli_connect($dbhost, $dbuser , $dbpassword, $database)
|
||||
or die("Verbindung zur Datenbank konnte nicht hergestellt werden");
|
||||
|
||||
$username = $_POST["username"];
|
||||
$passwort = $_POST["passwort"];
|
||||
$passwort2 = $_POST["passwort2"];
|
||||
|
||||
if($passwort != $passwort2 OR $username == "" OR $passwort == "")
|
||||
{
|
||||
echo "Eingabefehler. Bitte alle Felder korekt ausfüllen. <a href=\"eintragen.html\">Zurück</a>";
|
||||
exit;
|
||||
}
|
||||
$passwort = md5($passwort);
|
||||
|
||||
$result = mysqli_query($verbindung, "SELECT id FROM login WHERE username LIKE '$username'");
|
||||
$menge = mysqli_num_rows($result);
|
||||
|
||||
if($menge == 0)
|
||||
{
|
||||
$eintrag = "INSERT INTO login (username, passwort) VALUES ('$username', '$passwort')";
|
||||
$eintragen = mysqli_query($verbindung, $eintrag);
|
||||
|
||||
if($eintragen == true)
|
||||
{
|
||||
echo "Benutzername <b>$username</b> wurde erstellt. <a href=\"index.php\">Login</a>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Fehler beim Speichern des Benutzernames. <a href=\"eintragen.html\">Zurück</a>";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
echo "Benutzername schon vorhanden. <a href=\"eintragen.html\">Zurück</a>";
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
Escape Velocity by HTML5 UP
|
||||
html5up.net | @n33co
|
||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||
-->
|
||||
|
||||
<?php
|
||||
session_start();
|
||||
?>
|
||||
|
||||
<?php
|
||||
if(!isset($_SESSION["username"]))
|
||||
{
|
||||
echo "Bitte erst <a href=\"login.html\">einloggen</a>";
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
require_once ("config.php");
|
||||
require_once ("tpl/parser.php");
|
||||
|
||||
require_once ("tpl/mysql.class.php");
|
||||
$db = new Database($dbhost, $dbuser, $dbpassword, $database, 1); //Show Error = 1!
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>BOSwatch</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="description" content="" />
|
||||
<meta name="keywords" content="" />
|
||||
<!--[if lte IE 8]><script src="css/ie/html5shiv.js"></script><![endif]-->
|
||||
<script src="js/jquery.min.js"></script>
|
||||
<script src="js/jquery.dropotron.min.js"></script>
|
||||
<script src="js/skel.min.js"></script>
|
||||
<script src="js/skel-layers.min.js"></script>
|
||||
<script src="js/init.js"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="css/skel.css" />
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
<link rel="stylesheet" href="css/style-desktop.css" />
|
||||
</noscript>
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="css/ie/v8.css" /><![endif]-->
|
||||
</head>
|
||||
<body class="no-sidebar">
|
||||
|
||||
<!-- Header -->
|
||||
<div id="header-wrapper" class="wrapper">
|
||||
<div id="header">
|
||||
|
||||
|
||||
|
||||
<!-- Nav -->
|
||||
<nav id="nav">
|
||||
<ul>
|
||||
<li><a href="show_pocsag.php">POCSAG</a></li>
|
||||
<li><a href="show_fms.php">FMS</a></li>
|
||||
<li><a href="show_zvei.php">ZVEI</a></li>
|
||||
<li><a href="prefs.php">Einstellungen</a></li>
|
||||
<li><a href="eintragen.html">Nutzer anlegen</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Highlights -->
|
||||
<div class="wrapper style1">
|
||||
<div class="title">Usermanagment</div>
|
||||
<div class="container">
|
||||
|
||||
<div style="width: 400px;margin-left:auto;margin-right:auto;text-align:center;">
|
||||
|
||||
<form action="eintragen.php" method="post">
|
||||
Username:<br>
|
||||
<input type="text" size="12"
|
||||
name="username"><br>
|
||||
|
||||
Passwort:<br>
|
||||
<input type="password" size="24" maxlength="50"
|
||||
name="passwort"><br>
|
||||
|
||||
Passwort wiederholen:<br>
|
||||
<input type="password" size="24" maxlength="50"
|
||||
name="passwort2"><br>
|
||||
|
||||
<input type="submit" value="Abschicken">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="copyright">
|
||||
<ul>
|
||||
<li style="color:grey;">© BOSWatch</li><li style="color:grey;">Design: <a href="http://html5up.net">HTML5 UP</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,58 +1,111 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
Escape Velocity by HTML5 UP
|
||||
html5up.net | @n33co
|
||||
Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
|
||||
-->
|
||||
|
||||
<?php
|
||||
session_start();
|
||||
?>
|
||||
|
||||
<?php
|
||||
if(($_SESSION["username"])!="Kevin")
|
||||
if(!isset($_SESSION["username"]))
|
||||
{
|
||||
echo "Sie sind nicht berechtigt fuer diesen Bereich";
|
||||
echo "Bitte erst <a href='login.html'>einloggen</a>";
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
require_once ("config.php");
|
||||
require_once ("tpl/parser.php");
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
$verbindung = mysql_connect("localhost", "root" , "kevin21")
|
||||
or die("Verbindung zur Datenbank konnte nicht hergestellt werden");
|
||||
|
||||
mysql_select_db("login") or die ("Datenbank konnte nicht ausgewählt werden");
|
||||
|
||||
$username = $_POST["username"];
|
||||
$passwort = $_POST["passwort"];
|
||||
$passwort2 = $_POST["passwort2"];
|
||||
|
||||
if($passwort != $passwort2 OR $username == "" OR $passwort == "")
|
||||
{
|
||||
echo "Eingabefehler. Bitte alle Felder korekt ausfüllen. <a href=\"eintragen.html\">Zurück</a>";
|
||||
exit;
|
||||
}
|
||||
$passwort = md5($passwort);
|
||||
|
||||
$result = mysql_query("SELECT id FROM login WHERE username LIKE '$username'");
|
||||
$menge = mysql_num_rows($result);
|
||||
|
||||
if($menge == 0)
|
||||
{
|
||||
$eintrag = "INSERT INTO login (username, passwort) VALUES ('$username', '$passwort')";
|
||||
$eintragen = mysql_query($eintrag);
|
||||
|
||||
if($eintragen == true)
|
||||
{
|
||||
echo "Benutzername <b>$username</b> wurde erstellt. <a href=\"login.html\">Login</a>";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Fehler beim Speichern des Benutzernames. <a href=\"eintragen.html\">Zurück</a>";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
echo "Benutzername schon vorhanden. <a href=\"eintragen.html\">Zurück</a>";
|
||||
}
|
||||
require_once ("tpl/mysql.class.php");
|
||||
$db = new Database($dbhost, $dbuser, $dbpassword, $database, 1); //Show Error = 1!
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>BOSwatch</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="description" content="" />
|
||||
<meta name="keywords" content="" />
|
||||
<!--[if lte IE 8]><script src="css/ie/html5shiv.js"></script><![endif]-->
|
||||
<script src="js/jquery.min.js"></script>
|
||||
<script src="js/jquery.dropotron.min.js"></script>
|
||||
<script src="js/skel.min.js"></script>
|
||||
<script src="js/skel-layers.min.js"></script>
|
||||
<script src="js/init.js"></script>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="css/skel.css" />
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
<link rel="stylesheet" href="css/style-desktop.css" />
|
||||
</noscript>
|
||||
<!--[if lte IE 8]><link rel="stylesheet" href="css/ie/v8.css" /><![endif]-->
|
||||
</head>
|
||||
<body class="no-sidebar">
|
||||
|
||||
<!-- Header -->
|
||||
<div id="header-wrapper" class="wrapper">
|
||||
<div id="header">
|
||||
|
||||
|
||||
|
||||
<!-- Nav -->
|
||||
<nav id="nav">
|
||||
<ul>
|
||||
<li><a href="show_pocsag.php">POCSAG</a></li>
|
||||
<li><a href="show_fms.php">FMS</a></li>
|
||||
<li><a href="show_zvei.php">ZVEI</a></li>
|
||||
<li><a href="prefs.php">Einstellungen</a></li>
|
||||
<li><a href="eintragen.php">Nutzer anlegen</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Highlights -->
|
||||
<div class="wrapper style1">
|
||||
<div class="title">Usermanagment</div>
|
||||
<div class="container">
|
||||
|
||||
<div style="width: 400px;margin-left:auto;margin-right:auto;text-align:center;">
|
||||
|
||||
<form action="do_eintragen.php" method="post">
|
||||
Username:<br>
|
||||
<input type="text" size="12"
|
||||
name="username"><br>
|
||||
|
||||
Passwort:<br>
|
||||
<input type="password" size="24" maxlength="50"
|
||||
name="passwort"><br>
|
||||
|
||||
Passwort wiederholen:<br>
|
||||
<input type="password" size="24" maxlength="50"
|
||||
name="passwort2"><br>
|
||||
|
||||
<input type="submit" value="Abschicken">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="copyright">
|
||||
<ul>
|
||||
<li style="color:grey;">© BOSWatch</li><li style="color:grey;">Design: <a href="http://html5up.net">HTML5 UP</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ $db = new Database($dbhost, $dbuser, $dbpassword, $database, 1); //Show Error =
|
|||
|
||||
<!-- Logo -->
|
||||
<div id="logo">
|
||||
<h1><a href="index.html">Willkommen bei BOSWatch</a></h1>
|
||||
<h1><a href="index.php">Willkommen bei BOSWatch</a></h1>
|
||||
</div>
|
||||
|
||||
<!-- Nav -->
|
||||
|
|
@ -75,6 +75,14 @@ Dein Passwort:<br>
|
|||
<input type="password" size="24" maxlength="50"
|
||||
name="password"><br>
|
||||
|
||||
Startanzeige:<br>
|
||||
<select name="view">
|
||||
<option value="pocsag">POCSAG</option>
|
||||
<option value="fms">FMS</option>
|
||||
<option value="zvei">ZVEI</option>
|
||||
</select><br>
|
||||
|
||||
|
||||
<input type="submit" value="Login">
|
||||
</form>
|
||||
|
||||
|
|
@ -100,4 +108,4 @@ name="password"><br>
|
|||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -4,25 +4,44 @@ session_start();
|
|||
|
||||
<?php
|
||||
require_once ("config.php");
|
||||
$verbindung = mysql_connect($dbhost, $dbuser , $dbpassword)
|
||||
$verbindung = mysqli_connect($dbhost, $dbuser , $dbpassword)
|
||||
or die("Verbindung zur Datenbank konnte nicht hergestellt werden");
|
||||
mysql_select_db($tableLOG) or die ("Datenbank konnte nicht ausgewählt werden");
|
||||
mysqli_select_db($verbindung, $database) or die ("Datenbank konnte nicht ausgewählt werden");
|
||||
|
||||
if (!isset($_POST["username"]) XOR !isset($_POST["password"]))
|
||||
{
|
||||
echo "Fehlende Eingaben - <a href='index.php'>Login</a>";
|
||||
exit;
|
||||
}
|
||||
|
||||
$username = $_POST["username"];
|
||||
$passwort = md5($_POST["password"]);
|
||||
|
||||
$abfrage = "SELECT username, passwort FROM" $tableLOG "WHERE username LIKE '$username' LIMIT 1";
|
||||
$ergebnis = mysql_query($abfrage);
|
||||
$row = mysql_fetch_object($ergebnis);
|
||||
|
||||
$abfrage = "SELECT username, passwort FROM ".$tableLOG." WHERE username LIKE '$username' LIMIT 1";
|
||||
$ergebnis = mysqli_query($verbindung, $abfrage);
|
||||
$row = mysqli_fetch_object($ergebnis);
|
||||
|
||||
if($row->passwort == $passwort)
|
||||
{
|
||||
$_SESSION["username"] = $username;
|
||||
header("Location: /show_pocsag.php");
|
||||
switch ($_POST["view"]) {
|
||||
case 'pocsag':
|
||||
header("Location: show_pocsag.php");
|
||||
break;
|
||||
case 'zvei':
|
||||
header("Location: show_zvei.php");
|
||||
break;
|
||||
case 'fms':
|
||||
header("Location: show_fms.php");
|
||||
break;
|
||||
default:
|
||||
header("Location: show_pocsag.php");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Benutzername und/oder Passwort waren falsch. <a href=\"login.html\">Login</a>";
|
||||
echo "Benutzername und/oder Passwort waren falsch. <a href=\"index.php\">Login</a>";
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
|||
6
exampleAddOns/alarmMonitorWeb/logout.php
Normal file
6
exampleAddOns/alarmMonitorWeb/logout.php
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
session_unset();
|
||||
header("Location: index.php");
|
||||
|
||||
?>
|
||||
|
|
@ -11,7 +11,7 @@ session_start();
|
|||
?>
|
||||
|
||||
<?php
|
||||
if(($_SESSION["username"])!="Test")
|
||||
if(($_SESSION["username"])!="admin")
|
||||
{
|
||||
echo "Sie sind nicht berechtigt fuer diesen Bereich";
|
||||
exit;
|
||||
|
|
@ -27,7 +27,7 @@ include("tpl/a_header.php");
|
|||
<div class="wrapper style3">
|
||||
<div class="title">Einstellungen</div>
|
||||
<div id="highlights" class="container" style="">
|
||||
|
||||
<!--
|
||||
<tr>
|
||||
<td>Filter Range Start:</td><td>
|
||||
<input type="text" size="24" maxlength="50" value="
|
||||
|
|
@ -43,7 +43,7 @@ $ini_array = parse_ini_file("config.ini");
|
|||
echo($ini_array['filter_range_end']);
|
||||
?>
|
||||
"></td>
|
||||
</tr>
|
||||
</tr>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -60,4 +60,4 @@ echo($ini_array['filter_range_end']);
|
|||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@
|
|||
<li><a href="show_fms.php">FMS</a></li>
|
||||
<li><a href="show_zvei.php">ZVEI</a></li>
|
||||
<li><a href="prefs.php">Einstellungen</a></li>
|
||||
<li><a href="eintragen.html">Nutzer anlegen</a></li>
|
||||
<li><a href="eintragen.php">Nutzer anlegen</a></li>
|
||||
<li><a href="logout.php">Ausloggen</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ Simple Database Class (C) by Bastian Schroll
|
|||
function __construct($host, $user, $password, $database, $show_error = 1)
|
||||
{
|
||||
$this->show_error = $show_error;
|
||||
@$this->conn = mysql_connect($host, $user, $password);
|
||||
@$this->conn = mysqli_connect($host, $user, $password);
|
||||
if ($this->conn == false)
|
||||
{
|
||||
$this->error("Keine Verbindung zum Datenbank Server!", mysql_error());
|
||||
$this->error("Keine Verbindung zum Datenbank Server!", mysqli_error($this->conn));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!@mysql_select_db($database, $this->conn))
|
||||
if (!@mysqli_select_db($this->conn, $database))
|
||||
{
|
||||
$this->error("Datenbank nicht gefunden!", mysql_error());
|
||||
$this->error("Datenbank nicht gefunden!", mysqli_error($this->conn));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -48,10 +48,10 @@ Simple Database Class (C) by Bastian Schroll
|
|||
*/
|
||||
function query($query)
|
||||
{
|
||||
$this->result = @mysql_query($query, $this->conn);
|
||||
$this->result = @mysqli_query($this->conn, $query);
|
||||
if ($this->result == false)
|
||||
{
|
||||
$this->error("Fehlerhafte Datenbank Anfrage!", mysql_error());
|
||||
$this->error("Fehlerhafte Datenbank Anfrage!", mysqli_error($this->conn));
|
||||
return false;
|
||||
}
|
||||
return $this->result;
|
||||
|
|
@ -69,10 +69,10 @@ Simple Database Class (C) by Bastian Schroll
|
|||
{
|
||||
if ($result != null)
|
||||
{
|
||||
return @mysql_fetch_assoc($result);
|
||||
return @mysqli_fetch_assoc($result);
|
||||
} else
|
||||
{
|
||||
return @mysql_fetch_assoc($this->result);
|
||||
return @mysqli_fetch_assoc($this->result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
</tr>
|
||||
<?php
|
||||
|
||||
$db->query("SELECT id, time, ric, funktion, text, description FROM ".$tablePOC." ORDER BY id DESC LIMIT 100");
|
||||
$db->query("SELECT id, time, ric, function, msg, description FROM ".$tablePOC." ORDER BY id DESC LIMIT 100");
|
||||
$Rows = array();
|
||||
while ($daten = $db->fetchAssoc())
|
||||
{
|
||||
|
|
@ -29,11 +29,11 @@
|
|||
// echo "<td>". $poc['id'] . "</td>";
|
||||
//
|
||||
echo "<td>". $poc['description'] . "</td>";
|
||||
echo "<td>". $poc['text'] . "</td>";
|
||||
echo "<td>". $poc['msg'] . "</td>";
|
||||
echo "<td>". $time . "</td>";
|
||||
echo "<td>". $poc['ric'] . "</td>";
|
||||
echo "<td>". $poc['funktion'] . "</td>";
|
||||
echo "<td>". $poc['function'] . "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -23,35 +23,39 @@ Simple Database Class (C) by Bastian Schroll
|
|||
function __construct($host, $user, $password, $database, $show_error = 1)
|
||||
{
|
||||
$this->show_error = $show_error;
|
||||
@$this->conn = mysql_connect($host, $user, $password);
|
||||
@$this->conn = mysqli_connect($host, $user, $password);
|
||||
if ($this->conn == false)
|
||||
{
|
||||
$this->error("Keine Verbindung zum Datenbank Server!", mysql_error());
|
||||
$this->error("Keine Verbindung zum Datenbank Server!", mysqli_error($this->conn));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!@mysql_select_db($database, $this->conn))
|
||||
if (!@mysqli_select_db($this->conn, $database))
|
||||
{
|
||||
$this->error("Datenbank nicht gefunden!", mysql_error());
|
||||
$this->error("Datenbank nicht gefunden!", mysqli_error($this->conn));
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set character set for database connection to utf8mb4 */
|
||||
mysqli_query($this->conn, "SET NAMES 'utf8mb4'");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Database::query()
|
||||
*
|
||||
* F<EFBFBD>hrt einen MySQL Query aus
|
||||
* Fuehrt einen MySQL Query aus
|
||||
*
|
||||
* @param mixed $query Auszuf<EFBFBD>hrender Query
|
||||
* @param mixed $query Auszufuehrender Query
|
||||
* @return Result-Handler/FALSE
|
||||
*/
|
||||
function query($query)
|
||||
{
|
||||
$this->result = @mysql_query($query, $this->conn);
|
||||
$this->result = @mysqli_query($this->conn, $query);
|
||||
if ($this->result == false)
|
||||
{
|
||||
$this->error("Fehlerhafte Datenbank Anfrage!", mysql_error());
|
||||
$this->error("Fehlerhafte Datenbank Anfrage!", mysqli_error($this->conn));
|
||||
return false;
|
||||
}
|
||||
return $this->result;
|
||||
|
|
@ -60,51 +64,51 @@ Simple Database Class (C) by Bastian Schroll
|
|||
/**
|
||||
* Database::fetchAssoc()
|
||||
*
|
||||
* Liefert alle gefundnen Datens<EFBFBD>tze als Assoc
|
||||
* Liefert alle gefundnen Datensaetze als Assoc
|
||||
*
|
||||
* @param mixed $result Externer Result-Handler
|
||||
* @return gefundene Datens<EFBFBD>tze als Assoc
|
||||
* @return gefundene Datensaetze als Assoc
|
||||
*/
|
||||
function fetchAssoc($result = null)
|
||||
{
|
||||
if ($result != null)
|
||||
{
|
||||
return @mysql_fetch_assoc($result);
|
||||
return @mysqli_fetch_assoc($result);
|
||||
} else
|
||||
{
|
||||
return @mysql_fetch_assoc($this->result);
|
||||
return @mysqli_fetch_assoc($this->result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Database::count()
|
||||
*
|
||||
* Z<EFBFBD>hlt alle gefundenen Datens<EFBFBD>tze
|
||||
* Zaehlt alle gefundenen Datensaetze
|
||||
*
|
||||
* @param mixed $result Externer Result-Handler
|
||||
* @return Anzahl gefundener Datens<EFBFBD>tze
|
||||
* @return Anzahl gefundener Datensaetze
|
||||
*/
|
||||
function count($result = null)
|
||||
{
|
||||
if ($result != null)
|
||||
{
|
||||
return @mysql_num_rows($result);
|
||||
return @mysqli_num_rows($result);
|
||||
} else
|
||||
{
|
||||
return @mysql_num_rows($this->result);
|
||||
return @mysqli_num_rows($this->result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Database::closeConnection()
|
||||
*
|
||||
* Schlie<EFBFBD>t die bestehende MySQL Verbindung
|
||||
* Schliesst die bestehende MySQL Verbindung
|
||||
*
|
||||
* @return TRUE/FALSE
|
||||
*/
|
||||
function closeConnection()
|
||||
{
|
||||
if (!@mysql_close($this->conn))
|
||||
if (!@mysqli_close($this->conn))
|
||||
{
|
||||
$this->error("Verbindung zur Datenbank konnte nicht getrennt werden!", mysql_error());
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
"""
|
||||
Logging Handler for NotifyMyAndroid
|
||||
|
||||
@author: Jens Herrmann
|
||||
"""
|
||||
|
||||
import logging
|
||||
from includes.pynma import pynma
|
||||
|
||||
class NMAHandler(logging.Handler): # Inherit from logging.Handler
|
||||
"""
|
||||
Handler instances dispatch logging events to NotifyMyAndroid.
|
||||
"""
|
||||
|
||||
def __init__(self, APIKey, application="BOSWatch", event="Logging-Handler"):
|
||||
"""
|
||||
Initializes the handler with NMA-specific parameters.
|
||||
|
||||
@param APIKey: might be a string containing 1 key or an array of keys
|
||||
@param application: application name [256]
|
||||
@param event: event name [1000]
|
||||
"""
|
||||
# run the regular Handler __init__
|
||||
logging.Handler.__init__(self)
|
||||
# Our custom argument
|
||||
self.APIKey = APIKey
|
||||
self.application = application
|
||||
self.event = event
|
||||
self.nma = pynma.PyNMA(self.APIKey)
|
||||
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Send logging record via NMA
|
||||
"""
|
||||
# record.message is the log message
|
||||
message = record.message
|
||||
|
||||
# if exist, add details as NMA event:
|
||||
# record.module is the module- or filename
|
||||
if (len(record.module) > 0):
|
||||
event = "Module: " + record.module
|
||||
# record.functionName is the name of the function
|
||||
# will be "<module>" if the message is not in a function
|
||||
if len(record.funcName) > 0:
|
||||
if not record.funcName == "<module>":
|
||||
event += " - " + record.funcName + "()"
|
||||
else:
|
||||
# we have to set an event-text, use self.event now
|
||||
event = self.event
|
||||
|
||||
# record.levelno is the log level
|
||||
# loglevel: 10 = debug => priority: -2
|
||||
# loglevel: 20 = info => priority: -1
|
||||
# loglevel: 30 = warning => priority: 0
|
||||
# loglevel: 40 = error => priority: 1
|
||||
# loglevel: 50 = critical => priority: 2
|
||||
if record.levelno >= 50:
|
||||
priority = 2
|
||||
elif record.levelno >= 40:
|
||||
priority = 1
|
||||
elif record.levelno >= 30:
|
||||
priority = 0
|
||||
elif record.levelno >= 20:
|
||||
priority = -1
|
||||
else:
|
||||
priority = -2
|
||||
|
||||
# pynma.push(self, application="", event="", description="", url="", contenttype=None, priority=0, batch_mode=False, html=False)
|
||||
self.nma.push(application=self.application, event=event, description=message, priority=priority)
|
||||
|
|
@ -14,6 +14,7 @@ import logging # Global logger
|
|||
import time # timestamp
|
||||
|
||||
from includes import globalVars # Global variables
|
||||
from copy import deepcopy # copy objects to avoid issues if the objects will be changed by the plugin's during runtime and during asynch/threaded processing
|
||||
|
||||
##
|
||||
#
|
||||
|
|
@ -40,7 +41,7 @@ def processAlarmHandler(typ, freq, data):
|
|||
logging.debug("starting processAlarm async")
|
||||
try:
|
||||
from threading import Thread
|
||||
Thread(target=processAlarm, args=(typ, freq, data)).start()
|
||||
Thread(target=processAlarm, args=(typ, freq, deepcopy(data))).start()
|
||||
except:
|
||||
logging.error("Error in starting alarm processing async")
|
||||
logging.debug("Error in starting alarm processing async", exc_info=True)
|
||||
|
|
@ -80,7 +81,7 @@ def processAlarm(typ, freq, data):
|
|||
if regexFilter.checkFilters(typ, data, pluginName, freq):
|
||||
logging.debug("call Plugin: %s", pluginName)
|
||||
try:
|
||||
plugin.run(typ, freq, data)
|
||||
plugin.run(typ, freq, deepcopy(data))
|
||||
logging.debug("return from: %s", pluginName)
|
||||
except:
|
||||
# call next plugin, if one has thrown an exception
|
||||
|
|
@ -88,7 +89,7 @@ def processAlarm(typ, freq, data):
|
|||
else: # RegEX filter off - call plugin directly
|
||||
logging.debug("call Plugin: %s", pluginName)
|
||||
try:
|
||||
plugin.run(typ, freq, data)
|
||||
plugin.run(typ, freq, deepcopy(data))
|
||||
logging.debug("return from: %s", pluginName)
|
||||
except:
|
||||
# call next plugin, if one has thrown an exception
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ def decode(freq, decoded):
|
|||
|
||||
# ZVEI Decoder Section
|
||||
# check ZVEI: -> validate -> check double alarm -> log
|
||||
elif "ZVEI2:" in decoded:
|
||||
elif "ZVEI1:" in decoded:
|
||||
logging.debug("received ZVEI")
|
||||
from includes.decoders import zvei
|
||||
zvei.decode(freq, decoded)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ def isAllowed(poc_id):
|
|||
"""
|
||||
|
||||
allowed = 0
|
||||
has_geo = False
|
||||
|
||||
# 1.) If allowed RICs is set, only they will path,
|
||||
# If RIC is the right one return True, else False
|
||||
|
|
@ -62,11 +63,23 @@ def isAllowed(poc_id):
|
|||
return True
|
||||
else:
|
||||
allowed = 0
|
||||
# 5.) Implementation for multicastAlarm
|
||||
if globalVars.config.get("multicastAlarm", "multicastAlarm_delimiter_ric"):
|
||||
if poc_id in globalVars.config.get("multicastAlarm", "multicastAlarm_delimiter_ric"):
|
||||
logging.info("RIC %s as multicastAlarm delimiter", poc_id)
|
||||
return True
|
||||
else:
|
||||
allowed = 0
|
||||
if globalVars.config.get("multicastAlarm", "multicastAlarm_ric"):
|
||||
if poc_id in globalVars.config.get("multicastAlarm", "multicastAlarm_ric"):
|
||||
logging.info("RIC %s as multicastAlarm message", poc_id)
|
||||
return True
|
||||
else:
|
||||
allowed = 0
|
||||
|
||||
if allowed == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
##
|
||||
#
|
||||
# POCSAG decoder function
|
||||
|
|
@ -86,6 +99,8 @@ def decode(freq, decoded):
|
|||
@return: nothing
|
||||
@exception: Exception if POCSAG decode failed
|
||||
"""
|
||||
has_geo = False
|
||||
|
||||
try:
|
||||
bitrate = 0
|
||||
|
||||
|
|
@ -111,29 +126,72 @@ def decode(freq, decoded):
|
|||
logging.debug("POCSAG Bitrate: %s", bitrate)
|
||||
|
||||
if "Alpha:" in decoded: #check if there is a text message
|
||||
poc_text = decoded.split('Alpha: ')[1].strip().replace('<NUL><NUL>','').replace('<NUL>','').replace('<NUL','').replace('< NUL>','').replace('<EOT>','').strip()
|
||||
poc_text = decoded.split('Alpha: ')[1].strip().replace('<NUL><NUL>','').replace('<NUL>','').replace('<NUL','').replace('< NUL>','').replace('<EOT>','').strip()
|
||||
if globalVars.config.getint("POC","geo_enable"):
|
||||
try:
|
||||
logging.debug("Using %s to find geo-tag in %s", globalVars.config.get("POC","geo_format"),poc_text)
|
||||
m = re.search(globalVars.config.get("POC","geo_format"),poc_text)
|
||||
if m:
|
||||
logging.debug("Found geo-tag in message, parsing...")
|
||||
has_geo = True
|
||||
geo_order = globalVars.config.get("POC","geo_order").split(',')
|
||||
if geo_order[0].lower == "lon":
|
||||
lat = m.group(1) + "." + m.group(2)
|
||||
lon = m.group(3) + "." + m.group(4)
|
||||
else:
|
||||
lon = m.group(1) + "." + m.group(2)
|
||||
lat = m.group(3) + "." + m.group(4)
|
||||
logging.debug("Finished parsing geo; lon: %s, lat: %s", lon, lat)
|
||||
else:
|
||||
logging.debug("No geo-tag found")
|
||||
has_geo = False
|
||||
except:
|
||||
has_geo = False
|
||||
logging.error("Exception parsing geo-information",exc_info=true)
|
||||
else:
|
||||
has_geo = False
|
||||
else:
|
||||
poc_text = ""
|
||||
|
||||
if re.search("[0-9]{7}", poc_id) and re.search("[1-4]{1}", poc_sub): #if POC is valid
|
||||
if isAllowed(poc_id):
|
||||
|
||||
# check for double alarm
|
||||
if doubleFilter.checkID("POC", poc_id+poc_sub, poc_text):
|
||||
logging.info("POCSAG%s: %s %s %s ", bitrate, poc_id, poc_sub, poc_text)
|
||||
data = {"ric":poc_id, "function":poc_sub, "msg":poc_text, "bitrate":bitrate, "description":poc_id}
|
||||
data = {"ric":poc_id, "function":poc_sub, "msg":poc_text, "bitrate":bitrate, "description":poc_id, "has_geo":has_geo}
|
||||
if has_geo == True:
|
||||
data["lon"] = lon
|
||||
data["lat"] = lat
|
||||
# Add function as character a-d to dataset
|
||||
data["functionChar"] = data["function"].replace("1", "a").replace("2", "b").replace("3", "c").replace("4", "d")
|
||||
data["ricFuncChar"] = data["ric"] + data["functionChar"]
|
||||
|
||||
logging.info("POCSAG%s: %s %s %s ", data["bitrate"], data["ric"], data["function"], data["msg"])
|
||||
|
||||
# If enabled, look up description
|
||||
if globalVars.config.getint("POC", "idDescribed"):
|
||||
from includes import descriptionList
|
||||
data["description"] = descriptionList.getDescription("POC", poc_id)
|
||||
# processing the alarm
|
||||
try:
|
||||
from includes import alarmHandler
|
||||
alarmHandler.processAlarmHandler("POC", freq, data)
|
||||
except:
|
||||
logging.error("processing alarm failed")
|
||||
logging.debug("processing alarm failed", exc_info=True)
|
||||
data["description"] = descriptionList.getDescription("POC", data["ric"]+data["functionChar"])
|
||||
|
||||
# multicastAlarm processing if enabled and a message without text or delimiter RIC or netIdent_ric received
|
||||
if globalVars.config.getint("multicastAlarm", "multicastAlarm") and data["ric"] != globalVars.config.get("POC", "netIdent_ric") and (data["msg"] == "" or data["ric"] in globalVars.config.get("multicastAlarm", "multicastAlarm_delimiter_ric")):
|
||||
logging.debug(" - multicastAlarm without msg")
|
||||
from includes import multicastAlarm
|
||||
multicastAlarm.newEntrymultiList(data)
|
||||
|
||||
# multicastAlarm processing if enabled and alarm message has been received
|
||||
elif globalVars.config.getint("multicastAlarm", "multicastAlarm") and data["msg"] != "" and data["ric"] in globalVars.config.get("multicastAlarm", "multicastAlarm_ric"):
|
||||
logging.debug(" - multicastAlarm with message")
|
||||
from includes import multicastAlarm
|
||||
multicastAlarm.multicastAlarmExec(freq, data)
|
||||
|
||||
else:
|
||||
# processing the alarm
|
||||
try:
|
||||
from includes import alarmHandler
|
||||
alarmHandler.processAlarmHandler("POC", freq, data)
|
||||
except:
|
||||
logging.error("processing alarm failed")
|
||||
logging.debug("processing alarm failed", exc_info=True)
|
||||
# in every time save old data for double alarm
|
||||
doubleFilter.newEntry(poc_id+poc_sub, poc_text)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -17,24 +17,24 @@ from includes import doubleFilter # double alarm filter
|
|||
|
||||
##
|
||||
#
|
||||
# Local function to remove the 'F'
|
||||
# Local function to remove the 'E'
|
||||
#
|
||||
def removeF(zvei):
|
||||
def removeE(zvei):
|
||||
"""
|
||||
Resolve the F from the repeat Tone
|
||||
Resolve the E from the repeat Tone
|
||||
|
||||
@type zvei: string
|
||||
@param zvei: ZVEI Information
|
||||
|
||||
@return: ZVEI without F
|
||||
@return: ZVEI without E
|
||||
@exception: none
|
||||
"""
|
||||
if "F" in zvei:
|
||||
if "E" in zvei:
|
||||
zvei_old = zvei
|
||||
for i in range(1, len(zvei_old)):
|
||||
if zvei[i] == "F":
|
||||
zvei = zvei.replace("F",zvei[i-1],1)
|
||||
logging.debug("resolve F: %s -> %s", zvei_old, zvei)
|
||||
if zvei[i] == "E":
|
||||
zvei = zvei.replace("E",zvei[i-1],1)
|
||||
logging.debug("remove E: %s -> %s", zvei_old, zvei)
|
||||
return zvei
|
||||
|
||||
##
|
||||
|
|
@ -58,7 +58,7 @@ def decode(freq, decoded):
|
|||
"""
|
||||
try:
|
||||
zvei_id = decoded[7:12] # ZVEI Code
|
||||
zvei_id = removeF(zvei_id) # resolve F
|
||||
zvei_id = removeE(zvei_id) # remove E (repeated tone)
|
||||
if re.search("[0-9]{5}", zvei_id): # if ZVEI is valid
|
||||
# check for double alarm
|
||||
if doubleFilter.checkID("ZVEI", zvei_id):
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ Function to expand the dataset with a description.
|
|||
|
||||
import logging # Global logger
|
||||
import csv # for loading the description files
|
||||
import re # for matching IDs with a regular expression
|
||||
|
||||
from includes import globalVars # Global variables
|
||||
from includes.helper import stringConverter
|
||||
|
|
@ -41,10 +42,10 @@ def loadCSV(typ, idField):
|
|||
reader = csv.DictReader(csvfile)
|
||||
for row in reader:
|
||||
logging.debug(row)
|
||||
# only import rows with an integer as id
|
||||
if row[idField].isdigit() == True:
|
||||
# only import rows with an integer as id, allow subrics though
|
||||
if re.match("^[0-9A-F]+$", row[idField], re.IGNORECASE):
|
||||
try:
|
||||
resultList[row[idField]] = stringConverter.convertToUTF8(row['description'])
|
||||
resultList[row[idField].lower()] = stringConverter.convertToUTF8(row['description'])
|
||||
except:
|
||||
# skip entry in case of an exception
|
||||
pass
|
||||
|
|
@ -101,18 +102,19 @@ def getDescription(typ, data):
|
|||
|
||||
@return: description as string
|
||||
"""
|
||||
resultStr = data;
|
||||
resultStr = data
|
||||
logging.debug("look up description lists")
|
||||
try:
|
||||
if typ == "FMS":
|
||||
global fmsDescribtionList
|
||||
resultStr = fmsDescribtionList[data]
|
||||
elif typ == "ZVEI":
|
||||
global zveiDescribtionList
|
||||
resultStr = zveiDescribtionList[data]
|
||||
elif typ == "POC":
|
||||
global ricDescribtionList
|
||||
resultStr = ricDescribtionList[data]
|
||||
if globalVars.config.getint("POC", "onlysubric"):
|
||||
resultStr = ricDescribtionList[data] # only SubRIC
|
||||
else:
|
||||
resultStr = ricDescribtionList[data[:-1]] # MainRIC
|
||||
resultStr += " " + ricDescribtionList[data] # SubRIC
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,10 @@ def checkID(typ, data, msg=""):
|
|||
@return: True if check was OK
|
||||
@return: False if double was found
|
||||
"""
|
||||
global doubleList
|
||||
timestamp = int(time.time()) # Get Timestamp
|
||||
|
||||
logging.debug("checkID: %s (%s)", data, msg)
|
||||
for i in range(len(doubleList)):
|
||||
(xID, xTimestamp, xMsg) = doubleList[i]
|
||||
for (xID, xTimestamp, xMsg) in doubleList:
|
||||
# given ID found?
|
||||
# return False if the first entry in double_ignore_time is found, we will not check for younger ones...
|
||||
if data == xID and timestamp < xTimestamp + globalVars.config.getint("BOSWatch", "doubleFilter_ignore_time"):
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ Global variables
|
|||
"""
|
||||
|
||||
# version info
|
||||
versionNr = "2.2-beta"
|
||||
buildDate = "2016/02/23"
|
||||
versionNr = "2.5.2"
|
||||
branch = "master"
|
||||
buildDate = "08.01.2021"
|
||||
|
||||
# Global variables
|
||||
config = 0
|
||||
|
|
|
|||
|
|
@ -159,7 +159,6 @@ def convertToUTF8(inputString = ""):
|
|||
raise
|
||||
|
||||
# End of exception UnicodeDecodeError: check given string is already UTF-8
|
||||
pass
|
||||
|
||||
except:
|
||||
logging.warning("error checking given string")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from includes import globalVars
|
|||
from includes.helper import timeHandler
|
||||
|
||||
|
||||
def replaceWildcards(text, data, lineBrakeAllowed=False):
|
||||
def replaceWildcards(text, data):
|
||||
"""
|
||||
Replace all official Wildcards with the Information from the data[] var
|
||||
|
||||
|
|
@ -25,8 +25,6 @@ def replaceWildcards(text, data, lineBrakeAllowed=False):
|
|||
@param text: Input text with wildcards
|
||||
@type data: map
|
||||
@param data: map of data (structure see readme.md in plugin folder)
|
||||
@type lineBrakeAllowed: Boolean
|
||||
@param lineBrakeAllowed: switch to allow lineBreak (%BR%) as wildcard
|
||||
|
||||
@return: text with replaced wildcards
|
||||
@exception: Exception if Error at replace
|
||||
|
|
@ -36,8 +34,7 @@ def replaceWildcards(text, data, lineBrakeAllowed=False):
|
|||
text = text.replace("%TIME%", timeHandler.getTime(data["timestamp"])).replace("%DATE%", timeHandler.getDate(data["timestamp"]))
|
||||
|
||||
# replace some special chars
|
||||
if lineBrakeAllowed == True:
|
||||
text = text.replace("%BR%", "\r\n")
|
||||
text = text.replace("%BR%", "\r\n")
|
||||
text = text.replace("%LPAR%", "(")
|
||||
text = text.replace("%RPAR%", ")")
|
||||
|
||||
|
|
|
|||
65
includes/multicastAlarm.py
Normal file
65
includes/multicastAlarm.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
multicastAlarm is the function to enable BOSwatch to work in networks that optimise the transmission of POCSAG telegrams
|
||||
|
||||
@author: Fabian Kessler
|
||||
|
||||
@requires: Configuration has to be set in the config.ini
|
||||
"""
|
||||
|
||||
import logging # Global logger
|
||||
import time # timestamp for multicastAlarm
|
||||
|
||||
from includes import globalVars # Global variables
|
||||
|
||||
#
|
||||
# ListStructure [0..n] = (Data, TimeStamp)
|
||||
#
|
||||
multiList = []
|
||||
|
||||
def newEntrymultiList(data):
|
||||
"""
|
||||
add entry to multi alarm list and remove old entries
|
||||
|
||||
@return: nothing
|
||||
"""
|
||||
global multiList
|
||||
timestamp = int(time.time())
|
||||
# multicastAlarm processing if enabled and delimiter RIC has been received
|
||||
if data['ric'] == globalVars.config.get("multicastAlarm", "multicastAlarm_delimiter_ric"):
|
||||
del multiList[:]
|
||||
logging.debug("delimiter RIC received - buffer cleared")
|
||||
else:
|
||||
multiList.append([data, timestamp])
|
||||
logging.debug("Added %s to multiList", data['ric'])
|
||||
# check for old entries in multiList
|
||||
for (xData, xTimestamp) in multiList[:]:
|
||||
if xTimestamp < timestamp-globalVars.config.getint("multicastAlarm", "multicastAlarm_ignore_time"):
|
||||
multiList.remove([xData, xTimestamp])
|
||||
logging.debug("RIC %s removed - %s sec. older than current timestamp", xData['ric'], xTimestamp-timestamp)
|
||||
|
||||
|
||||
def multicastAlarmExec(freq, data):
|
||||
"""
|
||||
call alarmHandler for every entry in multiList
|
||||
|
||||
@return: nothing
|
||||
"""
|
||||
logging.debug("data before update from multiList: %s", data)
|
||||
for (xData, _) in multiList:
|
||||
#update data with values multiList
|
||||
data['ric'] = xData['ric']
|
||||
data['function'] = xData['function']
|
||||
data['functionChar'] = xData['functionChar']
|
||||
data['description'] = xData['description']
|
||||
logging.debug("data after update from multiList: %s", data)
|
||||
try:
|
||||
from includes import alarmHandler
|
||||
alarmHandler.processAlarmHandler("POC", freq, data)
|
||||
except:
|
||||
logging.error("processing alarm failed")
|
||||
logging.debug("processing alarm failed", exc_info=True)
|
||||
del multiList[:]
|
||||
logging.debug("multicastAlarm finished - buffer cleared")
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
Pynma
|
||||
======
|
||||
|
||||
Pynma is a simple python module for the [NotifyMyAndroid][nma] [API][NMA API].
|
||||
|
||||
[nma]: http://nma.usk.bz/
|
||||
[NMA API]: http://nma.usk.bz/api.php
|
||||
|
||||
Credits to: Damien Degois (github.com/babs)
|
||||
Refactoring: Adriano Maia (adriano@usk.bz)
|
||||
|
||||
[NotifyMyAndroid][nma]
|
||||
---------------
|
||||
NotifyMyAndroid is a Prowl-like application for the Android. Notifications can be sent from your application Android device using push. NMA has an extensive API, which allows your scripts to integrate beautifully. (source: http://nma.usk.bz/)
|
||||
|
||||
### How it works:
|
||||
First, import the module:
|
||||
|
||||
import pynma
|
||||
|
||||
#### Keys management
|
||||
|
||||
Create a PyNMA simple instance:
|
||||
|
||||
p = pynma.PyNMA( "apikey(s)", "developerkey")
|
||||
|
||||
A developerkey is optional. If you'd like to add just one API key, set it as string, if you want more, just provide a list of API key strings.
|
||||
|
||||
p = pynma.PyNMA(['apikey1','apikey2']) # multiple API keys
|
||||
p = pynma.PyNMA("apikey1","providerkey") # 1 API key with a providerkey
|
||||
|
||||
For more flexible usage, you can add and remove keys:
|
||||
|
||||
p.addkey("apikey1")
|
||||
p.addkey(["apikey2","apikey3"])
|
||||
|
||||
Or set or change the providerkey
|
||||
|
||||
p.developerkey("developerkey")
|
||||
|
||||
#### Notification or Push or Add
|
||||
|
||||
p.push(application, event, description, (opt) url, (opt) priority, (opt) batch mode)
|
||||
|
||||
##### Application
|
||||
|
||||
Application is your message generating application name (limited to 256)
|
||||
|
||||
ex: my music player
|
||||
|
||||
##### Event
|
||||
|
||||
Event is the event name (limited to 1000)
|
||||
|
||||
ex: switched to next track
|
||||
|
||||
##### Description
|
||||
|
||||
The description is the payload of your message (limited to 10000 (10k))
|
||||
ex:
|
||||
|
||||
Playing next song, Blah Blah Blah
|
||||
Artist: blah blah
|
||||
Album: blah blah
|
||||
Track: 18/24
|
||||
|
||||
##### Url
|
||||
|
||||
The URL which should be attached to the notification.
|
||||
This will trigger a redirect when on the user's device launched, and is viewable in the notification list.
|
||||
|
||||
##### Priority
|
||||
|
||||
Priority goes from -2 (lowest) to 2 (highest). the default priority is 0 (normal)
|
||||
|
||||
##### Batch mode
|
||||
|
||||
Batch mode is a boolean value to set if you'd like to push the same message to multiple API keys 5 by 5 (as the actual verion of prowl API allows you). This can reduce the number of call you make to the API which are limited.
|
||||
|
||||
#### Return
|
||||
|
||||
The push method returns a dict containing different values depending of the success of you call:
|
||||
|
||||
##### The call succeed
|
||||
|
||||
you'll have in the dict those keys:
|
||||
|
||||
type: success
|
||||
code: the HTTP like code (200 if success)
|
||||
remaining: the number of API call you can to until the reset
|
||||
resetdate: number of remaining minutes till the hourly reset of your API call limit
|
||||
|
||||
##### The call failed
|
||||
|
||||
For wathever reason, you call failed, the dict key "message" will contains the erro message returned by Prowl API. You'll find those keys:
|
||||
|
||||
code: 400, 401, 402 or 500 (depends of the error kind)
|
||||
message: API error message
|
||||
|
||||
For the code description, please refer to [NMA API documentation][NMA API] for more informations
|
||||
|
||||
##### The python module encountered an unhandled problem (mostly during parsing)
|
||||
|
||||
The return keys will be:
|
||||
|
||||
code: 600
|
||||
type: pynmaerror
|
||||
message: the exception message
|
||||
|
||||
Thanks
|
||||
------
|
||||
|
||||
* **Cev** for URL integration and some fixes in docstring
|
||||
* **ChaoticXSinZ** for UTF-8 integration and other typos
|
||||
|
||||
License (MIT)
|
||||
-------------
|
||||
|
||||
Copyright (c) 2010-2011, Damien Degois.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from .pynma import PyNMA
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from xml.dom.minidom import parseString
|
||||
|
||||
try:
|
||||
from http.client import HTTPSConnection
|
||||
except ImportError:
|
||||
from httplib import HTTPSConnection
|
||||
|
||||
try:
|
||||
from urllib.parse import urlencode
|
||||
except ImportError:
|
||||
from urllib import urlencode
|
||||
|
||||
__version__ = "1.0"
|
||||
|
||||
API_SERVER = 'www.notifymyandroid.com'
|
||||
ADD_PATH = '/publicapi/notify'
|
||||
|
||||
USER_AGENT="PyNMA/v%s"%__version__
|
||||
|
||||
def uniq_preserve(seq): # Dave Kirby
|
||||
# Order preserving
|
||||
seen = set()
|
||||
return [x for x in seq if x not in seen and not seen.add(x)]
|
||||
|
||||
def uniq(seq):
|
||||
# Not order preserving
|
||||
return list({}.fromkeys(seq).keys())
|
||||
|
||||
class PyNMA(object):
|
||||
"""PyNMA(apikey=[], developerkey=None)
|
||||
takes 2 optional arguments:
|
||||
- (opt) apykey: might me a string containing 1 key or an array of keys
|
||||
- (opt) developerkey: where you can store your developer key
|
||||
"""
|
||||
|
||||
def __init__(self, apikey=[], developerkey=None):
|
||||
self._developerkey = None
|
||||
self.developerkey(developerkey)
|
||||
if apikey:
|
||||
if type(apikey) == str:
|
||||
apikey = [apikey]
|
||||
self._apikey = uniq(apikey)
|
||||
|
||||
def addkey(self, key):
|
||||
"Add a key (register ?)"
|
||||
if type(key) == str:
|
||||
if not key in self._apikey:
|
||||
self._apikey.append(key)
|
||||
elif type(key) == list:
|
||||
for k in key:
|
||||
if not k in self._apikey:
|
||||
self._apikey.append(k)
|
||||
|
||||
def delkey(self, key):
|
||||
"Removes a key (unregister ?)"
|
||||
if type(key) == str:
|
||||
if key in self._apikey:
|
||||
self._apikey.remove(key)
|
||||
elif type(key) == list:
|
||||
for k in key:
|
||||
if key in self._apikey:
|
||||
self._apikey.remove(k)
|
||||
|
||||
def developerkey(self, developerkey):
|
||||
"Sets the developer key (and check it has the good length)"
|
||||
if type(developerkey) == str and len(developerkey) == 48:
|
||||
self._developerkey = developerkey
|
||||
|
||||
def pushWithAPIKey(self, apikey=[], application="", event="", description="", url="", contenttype=None, priority=0, batch_mode=False, html=False):
|
||||
"""Special Funktion"""
|
||||
if apikey:
|
||||
if type(apikey) == str:
|
||||
apikey = [apikey]
|
||||
self._apikey = uniq(apikey)
|
||||
return self.push(application, event, description, url, contenttype, priority, batch_mode, html)
|
||||
|
||||
def push(self, application="", event="", description="", url="", contenttype=None, priority=0, batch_mode=False, html=False):
|
||||
"""Pushes a message on the registered API keys.
|
||||
takes 5 arguments:
|
||||
- (req) application: application name [256]
|
||||
- (req) event: event name [1000]
|
||||
- (req) description: description [10000]
|
||||
- (opt) url: url [512]
|
||||
- (opt) contenttype: Content Type (act: None (plain text) or text/html)
|
||||
- (opt) priority: from -2 (lowest) to 2 (highest) (def:0)
|
||||
- (opt) batch_mode: push to all keys at once (def:False)
|
||||
- (opt) html: shortcut for contenttype=text/html
|
||||
Warning: using batch_mode will return error only if all API keys are bad
|
||||
cf: http://nma.usk.bz/api.php
|
||||
"""
|
||||
datas = {
|
||||
'application': application[:256].encode('utf8'),
|
||||
'event': event[:1024].encode('utf8'),
|
||||
'description': description[:10000].encode('utf8'),
|
||||
'priority': priority
|
||||
}
|
||||
|
||||
if url:
|
||||
datas['url'] = url[:512]
|
||||
|
||||
if contenttype == "text/html" or html == True: # Currently only accepted content type
|
||||
datas['content-type'] = "text/html"
|
||||
|
||||
if self._developerkey:
|
||||
datas['developerkey'] = self._developerkey
|
||||
|
||||
results = {}
|
||||
|
||||
if not batch_mode:
|
||||
for key in self._apikey:
|
||||
datas['apikey'] = key
|
||||
res = self.callapi('POST', ADD_PATH, datas)
|
||||
results[key] = res
|
||||
else:
|
||||
datas['apikey'] = ",".join(self._apikey)
|
||||
res = self.callapi('POST', ADD_PATH, datas)
|
||||
results[datas['apikey']] = res
|
||||
return results
|
||||
|
||||
def callapi(self, method, path, args):
|
||||
headers = { 'User-Agent': USER_AGENT }
|
||||
if method == "POST":
|
||||
headers['Content-type'] = "application/x-www-form-urlencoded"
|
||||
http_handler = HTTPSConnection(API_SERVER)
|
||||
http_handler.request(method, path, urlencode(args), headers)
|
||||
resp = http_handler.getresponse()
|
||||
|
||||
try:
|
||||
res = self._parse_reponse(resp.read())
|
||||
except Exception as e:
|
||||
res = {'type': "pynmaerror",
|
||||
'code': 600,
|
||||
'message': str(e)
|
||||
}
|
||||
|
||||
return res
|
||||
|
||||
def _parse_reponse(self, response):
|
||||
root = parseString(response).firstChild
|
||||
for elem in root.childNodes:
|
||||
if elem.nodeType == elem.TEXT_NODE: continue
|
||||
if elem.tagName == 'success':
|
||||
res = dict(list(elem.attributes.items()))
|
||||
res['message'] = ""
|
||||
res['type'] = elem.tagName
|
||||
return res
|
||||
if elem.tagName == 'error':
|
||||
res = dict(list(elem.attributes.items()))
|
||||
res['message'] = elem.firstChild.nodeValue
|
||||
res['type'] = elem.tagName
|
||||
return res
|
||||
|
|
@ -28,7 +28,6 @@ def loadFilters():
|
|||
|
||||
@return: nothing
|
||||
"""
|
||||
global filterList
|
||||
try:
|
||||
logging.debug("loading filters")
|
||||
# For each entry in config.ini [Filters] section
|
||||
|
|
@ -89,7 +88,7 @@ def checkFilters(typ, data, plugin, freq):
|
|||
return False
|
||||
else:
|
||||
logging.debug("no Filter found")
|
||||
return True
|
||||
return False
|
||||
|
||||
except:
|
||||
logging.error("Error in filter checking")
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ def printHeader(args):
|
|||
print " by Bastian Schroll, Jens Herrmann "
|
||||
print ""
|
||||
print "SW Version: "+globalVars.versionNr
|
||||
print "Branch: "+globalVars.branch
|
||||
print "Build Date: "+globalVars.buildDate
|
||||
print ""
|
||||
|
||||
|
|
|
|||
231
install.sh
Normal file → Executable file
231
install.sh
Normal file → Executable file
|
|
@ -6,17 +6,17 @@ function exitcodefunction {
|
|||
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 "Action: $action on $module failed." >> $boswatch_install_path/setup_log.txt
|
||||
echo "Exitcode: $errorcode" >> $boswatch_install_path/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/Schrolli91/BOSWatch/issues"
|
||||
echo " please post the logfile, located at $boswatchpath/install/setup_log.txt"
|
||||
echo " -> If you want to open an issue at https://github.com/Schrolli91/BOSWatch/issues"
|
||||
echo " please post the logfile, located at $boswatch_install_path/setup_log.txt"
|
||||
exit 1
|
||||
else
|
||||
echo "Action: $action on $module ok." >> $boswatchpath/install/setup_log.txt
|
||||
echo "Action: $action on $module ok." >> $boswatch_install_path/setup_log.txt
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -44,8 +44,32 @@ 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/boswatch
|
||||
boswatch_install_path=/opt/boswatch_install
|
||||
reboot=false
|
||||
didBackup=false
|
||||
|
||||
# Checking for Backup
|
||||
# check for old version (for the old ones...)
|
||||
if [ -f $boswatchpath/BOSWatch/boswatch.py ]; then
|
||||
echo "Old installation found!"
|
||||
echo "A backup will be copied to $boswatchpath/old"
|
||||
|
||||
mkdir /tmp/boswatch
|
||||
mv $boswatchpath/BOSWatch/* /tmp/boswatch/
|
||||
didBackup=true
|
||||
fi
|
||||
|
||||
#and the future...
|
||||
if [ -f $boswatchpath/boswatch.py ]; then
|
||||
echo "Old installation found!"
|
||||
echo "A backup will be copied to $boswatchpath/old"
|
||||
|
||||
mkdir /tmp/boswatch
|
||||
mv $boswatchpath/* /tmp/boswatch/
|
||||
didBackup=true
|
||||
fi
|
||||
|
||||
# Check for Flags in command line
|
||||
for (( i=1; i<=$#; i=$i+2 )); do
|
||||
t=$((i + 1))
|
||||
eval arg=\$$i
|
||||
|
|
@ -57,154 +81,149 @@ for (( i=1; i<=$#; i=$i+2 )); do
|
|||
-b|--branch)
|
||||
case $arg2 in
|
||||
dev|develop) echo " !!! WARNING: you are using the DEV BRANCH !!! "; branch=dev ;;
|
||||
beta) echo " !!! WARNING: you are using the BETA BRANCH !!! "; branch=beta ;;
|
||||
*) branch=master ;;
|
||||
esac ;;
|
||||
|
||||
-p|--path) echo " !!! WARNING: you install BOSWATCH to alternative path !!! "; boswatchpath=$arg2 ;;
|
||||
-p|--path) echo " !!! WARNING: you'll install BOSWATCH to alternative path !!! "; boswatchpath=$arg2 ;;
|
||||
|
||||
*) echo "Internal error!" ; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Create default paths
|
||||
mkdir -p $boswatchpath
|
||||
mkdir -p $boswatchpath/install
|
||||
mkdir -p $boswatch_install_path
|
||||
|
||||
echo ""
|
||||
|
||||
# Update of computer
|
||||
tput cup 13 15
|
||||
echo "[ 1/10] [#---------]"
|
||||
echo "[ 1/9] [#--------]"
|
||||
tput cup 15 5
|
||||
echo "-> make an apt-get update................"
|
||||
apt-get update -y > $boswatchpath/install/setup_log.txt 2>&1
|
||||
apt-get update -y > $boswatch_install_path/setup_log.txt 2>&1
|
||||
|
||||
# download software
|
||||
tput cup 13 15
|
||||
echo "[ 2/10] [##--------]"
|
||||
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
|
||||
apt-get -y install git cmake build-essential libusb-1.0 qt4-qmake qt4-default libpulse-dev libx11-dev sox python-pip >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? download stuff
|
||||
|
||||
# download BOSWatch via git
|
||||
tput cup 13 15
|
||||
echo "[ 3/10] [###-------]"
|
||||
tput cup 15 5
|
||||
echo "-> download rtl_fm......................"
|
||||
cd $boswatchpath/install
|
||||
git clone https://github.com/Schrolli91/rtl-sdr.git >> $boswatchpath/install/setup_log.txt 2>&1
|
||||
exitcodefunction $? git-clone rtl-sdr
|
||||
cd rtl-sdr/
|
||||
|
||||
tput cup 13 15
|
||||
echo "[ 4/10] [####------]"
|
||||
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 "[ 5/10] [#####-----]"
|
||||
tput cup 15 5
|
||||
echo "-> download multimon-ng................"
|
||||
cd $boswatchpath/install
|
||||
git clone https://github.com/Schrolli91/multimon-ng.git multimonNG >> $boswatchpath/install/setup_log.txt 2>&1
|
||||
exitcodefunction $? git-clone multimonNG
|
||||
|
||||
|
||||
cd $boswatchpath/install/multimonNG/
|
||||
|
||||
tput cup 13 15
|
||||
echo "[ 6/10] [######----]"
|
||||
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 "[ 7/10] [#######---]"
|
||||
tput cup 15 5
|
||||
echo "-> download MySQL connector for Python."
|
||||
cd $boswatchpath/install
|
||||
wget "http://dev.mysql.com/get/Downloads/Connector-Python/mysql-connector-python-1.0.9.tar.gz/from/http://cdn.mysql.com/" -O mysql-connector.tar >> $boswatchpath/install/setup_log.txt 2>&1
|
||||
exitcodefunction $? download mysql-connector
|
||||
|
||||
tar xfv mysql-connector.tar >> $boswatchpath/install/setup_log.txt 2>&1
|
||||
exitcodefunction $? untar mysql-connector
|
||||
|
||||
cd $boswatchpath/install/mysql-connector-python*
|
||||
|
||||
tput cup 13 15
|
||||
echo "[ 8/10] [########--]"
|
||||
tput cup 15 5
|
||||
echo "-> install MySQL connector for Python.."
|
||||
chmod +x ./setup.py
|
||||
./setup.py install >> $boswatchpath/install/setup_log.txt 2>&1
|
||||
exitcodefunction $? setup mysql-connector
|
||||
|
||||
|
||||
tput cup 13 15
|
||||
echo "[ 9/10] [#########-]"
|
||||
echo "[ 3/9] [###------]"
|
||||
tput cup 15 5
|
||||
echo "-> download BOSWatch..................."
|
||||
cd $boswatchpath/
|
||||
|
||||
case $branch in
|
||||
"dev") git clone -b develop https://github.com/Schrolli91/BOSWatch >> $boswatchpath/install/setup_log.txt 2>&1 && \
|
||||
"dev") git clone -b develop https://github.com/Schrolli91/BOSWatch . >> $boswatch_install_path/setup_log.txt 2>&1 && \
|
||||
exitcodefunction $? git-clone BOSWatch-develop ;;
|
||||
"beta") git clone -b beta https://github.com/Schrolli91/BOSWatch >> $boswatchpath/install/setup_log.txt 2>&1 && \
|
||||
exitcodefunction $? git-clone BOSWatch-beta ;;
|
||||
*) git clone -b master https://github.com/Schrolli91/BOSWatch >> $boswatchpath/install/setup_log.txt 2>&1 && \
|
||||
*) git clone -b master https://github.com/Schrolli91/BOSWatch . >> $boswatch_install_path/setup_log.txt 2>&1 && \
|
||||
exitcodefunction $? git-clone BOSWatch ;;
|
||||
esac
|
||||
|
||||
# Download RTL-SDR
|
||||
tput cup 13 15
|
||||
echo "[10/10] [##########]"
|
||||
echo "[ 4/9] [####-----]"
|
||||
tput cup 15 5
|
||||
echo "-> download rtl_fm......................"
|
||||
cd $boswatch_install_path
|
||||
git clone https://github.com/Schrolli91/rtl-sdr.git >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? git-clone rtl-sdr
|
||||
cd rtl-sdr/
|
||||
|
||||
# Compie RTL-FM
|
||||
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 >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? cmake rtl-sdr
|
||||
|
||||
make >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? make rtl-sdr
|
||||
|
||||
make install >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? make-install rtl-sdr
|
||||
|
||||
ldconfig >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? ldconfig rtl-sdr
|
||||
|
||||
|
||||
# Download Multimon-NG
|
||||
tput cup 13 15
|
||||
echo "[ 6/9] [######---]"
|
||||
tput cup 15 5
|
||||
echo "-> download multimon-ng................"
|
||||
cd $boswatch_install_path
|
||||
git clone https://github.com/Schrolli91/multimon-ng.git multimonNG >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? git-clone multimonNG
|
||||
|
||||
cd $boswatch_install_path/multimonNG/
|
||||
|
||||
# Compile Multimon-NG
|
||||
tput cup 13 15
|
||||
echo "[ 7/9] [#######--]"
|
||||
tput cup 15 5
|
||||
echo "-> compile multimon-ng................."
|
||||
mkdir -p build
|
||||
cd build
|
||||
qmake ../multimon-ng.pro >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? qmake multimonNG
|
||||
|
||||
make >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? make multimonNG
|
||||
|
||||
make install >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? qmakeinstall multimonNG
|
||||
|
||||
# Download & Install MySQL-Connector for Python via pip
|
||||
tput cup 13 15
|
||||
echo "[ 8/9] [########-]"
|
||||
tput cup 15 5
|
||||
echo "-> Download & Install MySQL connector for Python."
|
||||
cd $boswatch_install_path
|
||||
pip install mysql-connector-python >> $boswatch_install_path/setup_log.txt 2>&1
|
||||
exitcodefunction $? install mysql-connector
|
||||
|
||||
# Blacklist DVB-Drivers
|
||||
tput cup 13 15
|
||||
echo "[9/9] [#########]"
|
||||
tput cup 15 5
|
||||
echo "-> configure..........................."
|
||||
cd $boswatchpath/
|
||||
chmod +x *
|
||||
echo $'# BOSWatch - blacklist the DVB drivers to avoid conflict 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
|
||||
echo $'# BOSWatch - 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
|
||||
|
||||
# Installation is ready
|
||||
tput cup 17 1
|
||||
echo "BOSWatch is now installed in $boswatchpath/"
|
||||
echo "Installation ready!"
|
||||
tput cup 19 3
|
||||
echo "Watch out: to run BOSWatch you have to generate and modify the config.ini!"
|
||||
echo "Do the following steps to have a running version of BOSWatch:"
|
||||
echo "sudo cp $boswatchpath/BOSWatch/config/config.template.ini $boswatchpath/BOSWatch/config/config.ini"
|
||||
echo "sudo nano $boswatchpath/BOSWatch/config/config.ini"
|
||||
echo "Watch out: to run BOSWatch you have to modify the config.ini!"
|
||||
echo "Do the following step to do so:"
|
||||
echo "sudo nano $boswatchpath/config/config.ini"
|
||||
echo "and modify the config as you need. This step is optional if you are upgrading an old version of BOSWatch. "
|
||||
|
||||
tput cnorm
|
||||
|
||||
# cleanup
|
||||
mkdir $boswatchpath/log/install -p
|
||||
mv $boswatchpath/install/setup_log.txt $boswatchpath/log/install/
|
||||
rm $boswatchpath/install/ -R
|
||||
mv $boswatch_install_path/setup_log.txt $boswatchpath/log/install/
|
||||
rm $boswatch_install_path/ -R
|
||||
|
||||
mv $boswatchpath/BOSWatch/* $boswatchpath/
|
||||
rm $boswatchpath/BOSWatch -R
|
||||
#copy the template config to run boswatch
|
||||
cp $boswatchpath/config/config.template.ini $boswatchpath/config/config.ini
|
||||
|
||||
|
||||
#replay the backup
|
||||
if [ $didBackup = "true" ]; then
|
||||
mkdir $boswatchpath/old/
|
||||
mv /tmp/boswatch/* $boswatchpath/old/
|
||||
fi
|
||||
|
||||
if [ $reboot = "true" ]; then
|
||||
/sbin/reboot
|
||||
|
|
|
|||
241
plugins/Divera/Divera.py
Normal file
241
plugins/Divera/Divera.py
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
"""
|
||||
Divera-Plugin to send FMS-, ZVEI- and POCSAG - messages to Divera
|
||||
@author: Marco Grosjohann
|
||||
@requires: Divera-Configuration has to be set in the config.ini
|
||||
"""
|
||||
|
||||
import logging # Global logger
|
||||
import httplib # for the HTTP request
|
||||
import urllib
|
||||
from includes import globalVars # Global variables
|
||||
|
||||
# from includes.helper import timeHandler
|
||||
from includes.helper import configHandler
|
||||
from includes.helper import wildcardHandler
|
||||
|
||||
def isSignal(poc_id):
|
||||
"""
|
||||
@type poc_id: string
|
||||
@param poc_id: POCSAG Ric
|
||||
|
||||
@requires: Configuration has to be set in the config.ini
|
||||
|
||||
@return: True if the Ric is Signal, other False
|
||||
@exception: none
|
||||
"""
|
||||
# If RIC is Signal return True, else False
|
||||
if globalVars.config.get("POC", "netIdent_ric"):
|
||||
if poc_id in globalVars.config.get("POC", "netIdent_ric"):
|
||||
logging.info("RIC %s is net ident", poc_id)
|
||||
return True
|
||||
else:
|
||||
logging.info("RIC %s is no net ident", poc_id)
|
||||
return False
|
||||
|
||||
##
|
||||
#
|
||||
# onLoad (init) function of plugin
|
||||
# will be called one time by the pluginLoader on start
|
||||
#
|
||||
def onLoad():
|
||||
"""
|
||||
While loading the plugins by pluginLoader.loadPlugins()
|
||||
this onLoad() routine is called one time for initialize the plugin
|
||||
@requires: nothing
|
||||
@return: nothing
|
||||
"""
|
||||
# nothing to do for this plugin
|
||||
return
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# Main function of Divera-plugin
|
||||
# will be called by the alarmHandler
|
||||
#
|
||||
def run(typ, freq, data):
|
||||
"""
|
||||
This function is the implementation of the Divera-Plugin.
|
||||
It will send the data to Divera API
|
||||
@type typ: string (FMS|ZVEI|POC)
|
||||
@param typ: Typ of the dataset
|
||||
@type data: map of data (structure see readme.md in plugin folder)
|
||||
@param data: Contains the parameter
|
||||
@type freq: string
|
||||
@keyword freq: frequency of the SDR Stick
|
||||
@requires: Divera-Configuration has to be set in the config.ini
|
||||
@return: nothing
|
||||
"""
|
||||
try:
|
||||
if configHandler.checkConfig("Divera"): # read and debug the config
|
||||
|
||||
if typ == "FMS":
|
||||
#
|
||||
# building message for FMS
|
||||
#
|
||||
text = globalVars.config.get("Divera", "fms_text")
|
||||
title = globalVars.config.get("Divera", "fms_title")
|
||||
priority = globalVars.config.get("Divera", "fms_prio")
|
||||
vehicle = globalVars.config.get("Divera", "fms_vehicle")
|
||||
|
||||
elif typ == "ZVEI":
|
||||
#
|
||||
# building message for ZVEI
|
||||
#
|
||||
text = globalVars.config.get("Divera", "zvei_text")
|
||||
title = globalVars.config.get("Divera", "zvei_title")
|
||||
priority = globalVars.config.get("Divera","zvei_prio")
|
||||
zvei_id = globalVars.config.get("Divera","zvei_id")
|
||||
|
||||
elif typ == "POC":
|
||||
if isSignal(data["ric"]):
|
||||
|
||||
logging.debug("RIC is net ident")
|
||||
return
|
||||
else:
|
||||
#
|
||||
# building message for POC
|
||||
#
|
||||
if data["function"] == '1':
|
||||
priority = globalVars.config.get("Divera", "SubA")
|
||||
elif data["function"] == '2':
|
||||
priority = globalVars.config.get("Divera", "SubB")
|
||||
elif data["function"] == '3':
|
||||
priority = globalVars.config.get("Divera", "SubC")
|
||||
elif data["function"] == '4':
|
||||
priority = globalVars.config.get("Divera", "SubD")
|
||||
else:
|
||||
priority = ''
|
||||
|
||||
text = globalVars.config.get("Divera", "poc_text")
|
||||
title = globalVars.config.get("Divera", "poc_title")
|
||||
ric = globalVars.config.get("Divera", "poc_ric")
|
||||
|
||||
|
||||
else:
|
||||
logging.warning("Invalid type: %s", typ)
|
||||
return
|
||||
|
||||
try:
|
||||
#
|
||||
# Divera-Request
|
||||
#
|
||||
logging.debug("send Divera for %s", typ)
|
||||
|
||||
# Replace wildcards & Logging data to send
|
||||
title = wildcardHandler.replaceWildcards(title, data)
|
||||
logging.debug("Title : %s", title)
|
||||
text = wildcardHandler.replaceWildcards(text, data)
|
||||
logging.debug("Text : %s", text)
|
||||
|
||||
if typ == "FMS":
|
||||
vehicle = wildcardHandler.replaceWildcards(vehicle, data)
|
||||
logging.debug("Vehicle : %s", vehicle)
|
||||
elif typ == "POC":
|
||||
ric = wildcardHandler.replaceWildcards(ric, data)
|
||||
logging.debug("RIC : %s", ric)
|
||||
elif typ == "ZVEI":
|
||||
zvei_id = wildcardHandler.replaceWildcards(zvei_id, data)
|
||||
logging.debug("ZVEI_ID : %s", zvei_id)
|
||||
else:
|
||||
logging.info("No wildcards to replace and no Typ selected!")
|
||||
|
||||
# check priority value
|
||||
if (priority != 'false') and (priority != 'true'):
|
||||
logging.info("No Priority set for type '%s'! Skipping Divera-Alarm!", typ)
|
||||
return
|
||||
|
||||
# Check FMS
|
||||
if typ == "FMS":
|
||||
if (vehicle == ''):
|
||||
logging.info("No Vehicle set!")
|
||||
|
||||
# Check POC
|
||||
elif typ == "POC":
|
||||
if (ric == ''):
|
||||
logging.info("No RIC set!")
|
||||
|
||||
# Check ZVEI
|
||||
elif typ == "ZVEI":
|
||||
if (zvei_id == ''):
|
||||
logging.info("No ZVEI_ID set!")
|
||||
|
||||
else:
|
||||
logging.info("No ZVEI, FMS or POC alarm")
|
||||
|
||||
# start connection to Divera
|
||||
if typ == "FMS":
|
||||
# start the connection FMS
|
||||
conn = httplib.HTTPSConnection("www.divera247.com:443")
|
||||
conn.request("GET", "/api/fms",
|
||||
urllib.urlencode({
|
||||
"accesskey": globalVars.config.get("Divera", "accesskey"),
|
||||
"vehicle_ric": vehicle,
|
||||
"status_id": data["status"],
|
||||
"status_note": data["directionText"],
|
||||
"title": title,
|
||||
"text": text,
|
||||
"priority": priority,
|
||||
}))
|
||||
|
||||
elif typ == "ZVEI":
|
||||
# start connection ZVEI; zvei_id in Divera is alarm-RIC!
|
||||
conn = httplib.HTTPSConnection("www.divera247.com:443")
|
||||
conn.request("GET", "/api/alarm",
|
||||
urllib.urlencode({
|
||||
"accesskey": globalVars.config.get("Divera", "accesskey"),
|
||||
"title": title,
|
||||
"ric": zvei_id,
|
||||
"text": text,
|
||||
"priority": priority,
|
||||
}))
|
||||
|
||||
elif typ == "POC":
|
||||
# start connection POC
|
||||
conn = httplib.HTTPSConnection("www.divera247.com:443")
|
||||
conn.request("GET", "/api/alarm",
|
||||
urllib.urlencode({
|
||||
"accesskey": globalVars.config.get("Divera", "accesskey"),
|
||||
"title": title,
|
||||
"ric": ric,
|
||||
"text": text,
|
||||
"priority": priority,
|
||||
}))
|
||||
|
||||
|
||||
else:
|
||||
loggin.debug("No Type is set", exc_info=True)
|
||||
return
|
||||
|
||||
except:
|
||||
logging.error("cannot send Divera request")
|
||||
logging.debug("cannot send Divera request", exc_info=True)
|
||||
return
|
||||
|
||||
try:
|
||||
#
|
||||
# check Divera-Response
|
||||
#
|
||||
response = conn.getresponse()
|
||||
if str(response.status) == "200": # Check Divera Response and print a Log or Error
|
||||
logging.debug("Divera response: %s - %s", str(response.status), str(response.reason))
|
||||
else:
|
||||
logging.warning("Divera response: %s - %s", str(response.status), str(response.reason))
|
||||
except: # otherwise
|
||||
logging.error("cannot get Divera response")
|
||||
logging.debug("cannot get Divera response", exc_info=True)
|
||||
return
|
||||
|
||||
finally:
|
||||
logging.debug("close Divera-Connection")
|
||||
try:
|
||||
request.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
|
|
@ -13,6 +13,8 @@ import logging # Global logger
|
|||
import hmac, hashlib
|
||||
import json, requests
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from includes import globalVars # Global variables
|
||||
|
||||
#from includes.helper import timeHandler
|
||||
|
|
@ -123,8 +125,9 @@ def run(typ,freq,data):
|
|||
}
|
||||
|
||||
alarmData = json.dumps(alarmData)
|
||||
|
||||
logging.debug(alarmData)
|
||||
|
||||
|
||||
alarmHeaders = {
|
||||
"Content-Type": "application/json",
|
||||
"webApiToken": webApiToken,
|
||||
|
|
@ -132,11 +135,30 @@ def run(typ,freq,data):
|
|||
"selectiveCallCode": selectiveCallCode,
|
||||
"hmac": hmac.new(webApiKey, webApiToken + selectiveCallCode + accessToken + alarmData, digestmod=hashlib.sha256).hexdigest()
|
||||
}
|
||||
|
||||
logging.debug(alarmHeaders)
|
||||
|
||||
alarmHeadersOrdered=OrderedDict()
|
||||
alarmHeadersOrdered['webApiToken']=webApiToken
|
||||
alarmHeadersOrdered['accessToken']=accessToken
|
||||
alarmHeadersOrdered['selectiveCallCode']=selectiveCallCode
|
||||
alarmHeadersOrdered['hmac']=hmac.new(webApiKey, webApiToken + selectiveCallCode + accessToken + alarmData, digestmod=hashlib.sha256).hexdigest()
|
||||
|
||||
logging.debug(alarmHeadersOrdered)
|
||||
|
||||
if globalVars.config.get("FFAgent", "live") == "1":
|
||||
r = requests.post(url, data=alarmData, headers=headers, verify=serverCertFile, cert=(clientCertFile, clientCertPass))
|
||||
s = requests.Session()
|
||||
s.headers = OrderedDict([('Content-Type', 'application/json')])
|
||||
logging.debug(s.headers)
|
||||
r = s.post(url, data=alarmData, headers=alarmHeadersOrdered, verify=serverCertFile, cert=(clientCertFile, clientCertPass))
|
||||
|
||||
else:
|
||||
r = requests.post(url, data=alarmData, headers=alarmHeaders, verify=serverCertFile)
|
||||
s = requests.Session()
|
||||
s.headers = OrderedDict([('Content-Type', 'application/json')])
|
||||
logging.debug(s.headers)
|
||||
r = s.post(url, data=alarmData, headers=alarmHeadersOrdered, verify=serverCertFile)
|
||||
|
||||
logging.debug(r.request.headers)
|
||||
|
||||
except:
|
||||
logging.error("cannot send FFAgent request")
|
||||
|
|
|
|||
|
|
@ -21,23 +21,23 @@ from includes import globalVars # Global variables
|
|||
from includes.helper import configHandler
|
||||
|
||||
def isSignal(poc_id):
|
||||
"""
|
||||
@type poc_id: string
|
||||
@param poc_id: POCSAG Ric
|
||||
"""
|
||||
@type poc_id: string
|
||||
@param poc_id: POCSAG Ric
|
||||
|
||||
@requires: Configuration has to be set in the config.ini
|
||||
@requires: Configuration has to be set in the config.ini
|
||||
|
||||
@return: True if the Ric is Signal, other False
|
||||
@exception: none
|
||||
"""
|
||||
# If RIC is Signal return True, else False
|
||||
if globalVars.config.get("POC", "netIdent_ric"):
|
||||
if poc_id in globalVars.config.get("POC", "netIdent_ric"):
|
||||
logging.info("RIC %s is net ident", poc_id)
|
||||
return True
|
||||
else:
|
||||
logging.info("RIC %s is no net ident", poc_id)
|
||||
return False
|
||||
@return: True if the Ric is Signal, other False
|
||||
@exception: none
|
||||
"""
|
||||
# If RIC is Signal return True, else False
|
||||
if globalVars.config.get("POC", "netIdent_ric"):
|
||||
if poc_id in globalVars.config.get("POC", "netIdent_ric"):
|
||||
logging.info("RIC %s is net ident", poc_id)
|
||||
return True
|
||||
else:
|
||||
logging.info("RIC %s is no net ident", poc_id)
|
||||
return False
|
||||
|
||||
|
||||
##
|
||||
|
|
@ -87,11 +87,11 @@ def run(typ,freq,data):
|
|||
if configHandler.checkConfig("MySQL"): #read and debug the config
|
||||
|
||||
try:
|
||||
#
|
||||
#
|
||||
# Connect to MySQL
|
||||
#
|
||||
logging.debug("connect to MySQL")
|
||||
connection = mysql.connector.connect(host = globalVars.config.get("MySQL","dbserver"), user = globalVars.config.get("MySQL","dbuser"), passwd = globalVars.config.get("MySQL","dbpassword"), db = globalVars.config.get("MySQL","database"), charset='utf8')
|
||||
connection = mysql.connector.connect(host = globalVars.config.get("MySQL","dbserver"), port = globalVars.config.get("MySQL","dbport"), user = globalVars.config.get("MySQL","dbuser"), passwd = globalVars.config.get("MySQL","dbpassword"), db = globalVars.config.get("MySQL","database"), charset = 'utf8mb4', collation = 'utf8mb4_general_ci')
|
||||
cursor = connection.cursor()
|
||||
except:
|
||||
logging.error("cannot connect to MySQL")
|
||||
|
|
@ -104,18 +104,21 @@ def run(typ,freq,data):
|
|||
logging.debug("Insert %s", typ)
|
||||
|
||||
if typ == "FMS":
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tableFMS")+" (time, fms, status, direction, directionText, tsi, description) VALUES (FROM_UNIXTIME(%s),%s,%s,%s,%s,%s,%s)", (data["timestamp"], data["fms"], data["status"], data["direction"], data["directionText"], data["tsi"], data["description"]))
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tableFMS")+" (`time`, `fms`, `status`, `direction`, `directionText`, `tsi`, `description`) VALUES (FROM_UNIXTIME(%s),%s,%s,%s,%s,%s,%s)", (data["timestamp"], data["fms"], data["status"], data["direction"], data["directionText"], data["tsi"], data["description"]))
|
||||
|
||||
elif typ == "ZVEI":
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tableZVEI")+" (time, zvei, description) VALUES (FROM_UNIXTIME(%s),%s,%s)", (data["timestamp"], data["zvei"], data["description"]))
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tableZVEI")+" (`time`, `zvei`, `description`) VALUES (FROM_UNIXTIME(%s),%s,%s)", (data["timestamp"], data["zvei"], data["description"]))
|
||||
|
||||
elif typ == "POC":
|
||||
if isSignal(data["ric"]):
|
||||
cursor.execute("UPDATE "+globalVars.config.get("MySQL","tableSIG")+" SET time = NOW() WHERE ric = "+data["ric"])
|
||||
if cursor.rowcount == 0:
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tableSIG")+" (time,ric) VALUES (NOW(),"+data["ric"]+")")
|
||||
if globalVars.config.getint("POC","netIdent_history"):
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tableSIG")+" (`time`,`ric`) VALUES (NOW(), '"+data["ric"]+"');")
|
||||
else:
|
||||
cursor.execute("UPDATE "+globalVars.config.get("MySQL","tableSIG")+" SET time = NOW() WHERE ric = '"+data["ric"]+"';")
|
||||
if cursor.rowcount == 0:
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tableSIG")+" (`time`,`ric`) VALUES (NOW(), '"+data["ric"]+"');")
|
||||
else:
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tablePOC")+" (time, ric, function, functionChar, msg, bitrate, description) VALUES (FROM_UNIXTIME(%s),%s,%s,%s,%s,%s,%s)", (data["timestamp"], data["ric"], data["function"], data["functionChar"], data["msg"], data["bitrate"], data["description"]))
|
||||
cursor.execute("INSERT INTO "+globalVars.config.get("MySQL","tablePOC")+" (`time`, `ric`, `function`, `functionChar`, `msg`, `bitrate`, `description`) VALUES (FROM_UNIXTIME(%s),%s,%s,%s,%s,%s,%s)", (data["timestamp"], data["ric"], data["function"], data["functionChar"], data["msg"], data["bitrate"], data["description"]))
|
||||
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ SET time_zone = "+00:00";
|
|||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -25,8 +25,8 @@ SET time_zone = "+00:00";
|
|||
-- Datenbank anlegen `boswatch`
|
||||
--
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS boswatch;
|
||||
USE boswatch;
|
||||
CREATE DATABASE IF NOT EXISTS 'boswatch' DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
USE 'boswatch';
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS `bos_fms` (
|
|||
`tsi` VARCHAR(3) NOT NULL,
|
||||
`description` TEXT NOT NULL,
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MYISAM DEFAULT CHARSET=UTF8 AUTO_INCREMENT=1;
|
||||
) ENGINE=MYISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -70,8 +70,9 @@ CREATE TABLE IF NOT EXISTS `bos_pocsag` (
|
|||
`msg` TEXT NOT NULL,
|
||||
`bitrate` INT(4) NOT NULL,
|
||||
`description` TEXT NOT NULL,
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MYISAM DEFAULT CHARSET=UTF8 AUTO_INCREMENT=1;
|
||||
PRIMARY KEY (`ID`),
|
||||
KEY `POCSAG_RIC_IDX` (`ric`)
|
||||
) ENGINE=MYISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1;
|
||||
|
||||
-- rename old columns including little error-prevention
|
||||
#ALTER IGNORE TABLE `bos_pocsag` change `funktion` `function` INT(1);
|
||||
|
|
@ -89,7 +90,7 @@ CREATE TABLE IF NOT EXISTS `bos_zvei` (
|
|||
`zvei` VARCHAR(5) NOT NULL DEFAULT '0',
|
||||
`description` TEXT NOT NULL,
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MYISAM DEFAULT CHARSET=UTF8 AUTO_INCREMENT=1;
|
||||
) ENGINE=MYISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
|
@ -102,45 +103,7 @@ CREATE TABLE IF NOT EXISTS `bos_signal` (
|
|||
`time` DATETIME NOT NULL,
|
||||
`ric` VARCHAR(7) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`ID`)
|
||||
) ENGINE=MYISAM DEFAULT CHARSET=UTF8 AUTO_INCREMENT=1;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Schedule für Tabelle `bos_pocsag`
|
||||
--
|
||||
CREATE EVENT IF NOT EXISTS `Delete POCSAG Entries > 3 Months`
|
||||
ON SCHEDULE EVERY 1 DAY
|
||||
STARTS '2016-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE ENABLE
|
||||
DO
|
||||
DELETE FROM bos_pocsag WHERE time < DATE_SUB(NOW(),INTERVAL 3 MONTH);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Schedule für Tabelle `bos_fms`
|
||||
--
|
||||
|
||||
CREATE EVENT IF NOT EXISTS `Delete FMS Entries > 3 Months`
|
||||
ON SCHEDULE EVERY 1 DAY
|
||||
STARTS '2016-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE ENABLE
|
||||
DO
|
||||
DELETE FROM bos_fms WHERE time < DATE_SUB(NOW(),INTERVAL 3 MONTH);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Schedule für Tabelle `bos_zvei`
|
||||
--
|
||||
|
||||
CREATE EVENT IF NOT EXISTS `Delete ZVEI Entries > 3 Months`
|
||||
ON SCHEDULE EVERY 1 DAY
|
||||
STARTS '2016-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE ENABLE
|
||||
DO
|
||||
DELETE FROM bos_zvei WHERE time < DATE_SUB(NOW(),INTERVAL 3 MONTH);
|
||||
) ENGINE=MYISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1;
|
||||
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
|
|
|
|||
40
plugins/MySQL/boswatch_cleanup.sql
Normal file
40
plugins/MySQL/boswatch_cleanup.sql
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
-- Cleanup-routines for boswatch-tables
|
||||
|
||||
use boswatch;
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Schedule für Tabelle `bos_pocsag`
|
||||
--
|
||||
CREATE EVENT IF NOT EXISTS `Delete POCSAG Entries > 3 Months`
|
||||
ON SCHEDULE EVERY 1 DAY
|
||||
STARTS '2016-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE ENABLE
|
||||
DO
|
||||
DELETE FROM bos_pocsag WHERE time < DATE_SUB(NOW(),INTERVAL 3 MONTH);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Schedule für Tabelle `bos_fms`
|
||||
--
|
||||
|
||||
CREATE EVENT IF NOT EXISTS `Delete FMS Entries > 3 Months`
|
||||
ON SCHEDULE EVERY 1 DAY
|
||||
STARTS '2016-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE ENABLE
|
||||
DO
|
||||
DELETE FROM bos_fms WHERE time < DATE_SUB(NOW(),INTERVAL 3 MONTH);
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Schedule für Tabelle `bos_zvei`
|
||||
--
|
||||
|
||||
CREATE EVENT IF NOT EXISTS `Delete ZVEI Entries > 3 Months`
|
||||
ON SCHEDULE EVERY 1 DAY
|
||||
STARTS '2016-01-01 00:00:00'
|
||||
ON COMPLETION PRESERVE ENABLE
|
||||
DO
|
||||
DELETE FROM bos_zvei WHERE time < DATE_SUB(NOW(),INTERVAL 3 MONTH);
|
||||
|
|
@ -9,13 +9,15 @@ Pushover-Plugin to send FMS-, ZVEI- and POCSAG - messages to Pushover Clients
|
|||
@requires: Pushover-Configuration has to be set in the config.ini
|
||||
"""
|
||||
|
||||
import logging # Global logger
|
||||
import httplib #for the HTTP request
|
||||
import logging # Global logger
|
||||
import httplib # for the HTTP request
|
||||
import urllib
|
||||
from includes import globalVars # Global variables
|
||||
|
||||
#from includes.helper import timeHandler
|
||||
# from includes.helper import timeHandler
|
||||
from includes.helper import configHandler
|
||||
from includes.helper import wildcardHandler
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
|
|
@ -23,16 +25,16 @@ from includes.helper import configHandler
|
|||
# will be called one time by the pluginLoader on start
|
||||
#
|
||||
def onLoad():
|
||||
"""
|
||||
While loading the plugins by pluginLoader.loadPlugins()
|
||||
this onLoad() routine is called one time for initialize the plugin
|
||||
"""
|
||||
While loading the plugins by pluginLoader.loadPlugins()
|
||||
this onLoad() routine is called one time for initialize the plugin
|
||||
|
||||
@requires: nothing
|
||||
@requires: nothing
|
||||
|
||||
@return: nothing
|
||||
"""
|
||||
# nothing to do for this plugin
|
||||
return
|
||||
@return: nothing
|
||||
"""
|
||||
# nothing to do for this plugin
|
||||
return
|
||||
|
||||
|
||||
##
|
||||
|
|
@ -40,82 +42,138 @@ def onLoad():
|
|||
# Main function of Pushover-plugin
|
||||
# will be called by the alarmHandler
|
||||
#
|
||||
def run(typ,freq,data):
|
||||
"""
|
||||
This function is the implementation of the Pushover-Plugin.
|
||||
It will send the data to Pushover API
|
||||
def run(typ, freq, data):
|
||||
"""
|
||||
This function is the implementation of the Pushover-Plugin.
|
||||
It will send the data to Pushover API
|
||||
|
||||
@type typ: string (FMS|ZVEI|POC)
|
||||
@param typ: Typ of the dataset
|
||||
@type data: map of data (structure see readme.md in plugin folder)
|
||||
@param data: Contains the parameter
|
||||
@type freq: string
|
||||
@keyword freq: frequency of the SDR Stick
|
||||
@type typ: string (FMS|ZVEI|POC)
|
||||
@param typ: Typ of the dataset
|
||||
@type data: map of data (structure see readme.md in plugin folder)
|
||||
@param data: Contains the parameter
|
||||
@type freq: string
|
||||
@keyword freq: frequency of the SDR Stick
|
||||
|
||||
@requires: Pushover-Configuration has to be set in the config.ini
|
||||
@requires: Pushover-Configuration has to be set in the config.ini
|
||||
|
||||
@return: nothing
|
||||
"""
|
||||
try:
|
||||
if configHandler.checkConfig("Pushover"): #read and debug the config
|
||||
@return: nothing
|
||||
"""
|
||||
try:
|
||||
if configHandler.checkConfig("Pushover"): # read and debug the config
|
||||
|
||||
try:
|
||||
#
|
||||
# Pushover-Request
|
||||
#
|
||||
logging.debug("send Pushover %s", typ)
|
||||
if typ == "FMS":
|
||||
#
|
||||
# building message for FMS
|
||||
#
|
||||
|
||||
if data["function"] == '1':
|
||||
priority = globalVars.config.get("Pushover", "SubA")
|
||||
elif data["function"] == '2':
|
||||
priority = globalVars.config.get("Pushover", "SubB")
|
||||
elif data["function"] == '3':
|
||||
priority = globalVars.config.get("Pushover", "SubC")
|
||||
elif data["function"] == '4':
|
||||
priority = globalVars.config.get("Pushover", "SubD")
|
||||
else:
|
||||
priority = 0
|
||||
|
||||
conn = httplib.HTTPSConnection("api.pushover.net:443")
|
||||
conn.request("POST", "/1/messages.json",
|
||||
urllib.urlencode({
|
||||
"token": globalVars.config.get("Pushover", "api_key"),
|
||||
"user": globalVars.config.get("Pushover", "user_key"),
|
||||
"message": "<b>"+data["description"]+"</b><br>"+data["msg"].replace(";", "<br>"),
|
||||
"html": globalVars.config.get("Pushover", "html"),
|
||||
"title": globalVars.config.get("Pushover", "title"),
|
||||
"priority": priority,
|
||||
"retry": globalVars.config.get("Pushover", "retry"),
|
||||
"expire": globalVars.config.get("Pushover", "expire")
|
||||
}),{"Content-type": "application/x-www-form-urlencoded"})
|
||||
|
||||
except:
|
||||
logging.error("cannot send Pushover request")
|
||||
logging.debug("cannot send Pushover request", exc_info=True)
|
||||
return
|
||||
message = globalVars.config.get("Pushover", "fms_message")
|
||||
title = globalVars.config.get("Pushover", "fms_title")
|
||||
priority = globalVars.config.get("Pushover", "fms_prio")
|
||||
logging.debug("Sending message: %s", message)
|
||||
|
||||
elif typ == "ZVEI":
|
||||
#
|
||||
# building message for ZVEI
|
||||
#
|
||||
if globalVars.config.get("Pushover", "zvei_sep_prio") == '1':
|
||||
if data["zvei"] in globalVars.config.get("Pushover", "zvei_prio2"):
|
||||
priority = '2'
|
||||
elif data["zvei"] in globalVars.config.get("Pushover","zvei_prio1"):
|
||||
priority = '1'
|
||||
elif data["zvei"] in globalVars.config.get("Pushover","zvei_prio0"):
|
||||
priority = '0'
|
||||
else:
|
||||
try:
|
||||
#
|
||||
# check Pushover-Response
|
||||
#
|
||||
response = conn.getresponse()
|
||||
if str(response.status) == "200": #Check Pushover Response and print a Log or Error
|
||||
logging.debug("Pushover response: %s - %s" , str(response.status), str(response.reason))
|
||||
else:
|
||||
logging.warning("Pushover response: %s - %s" , str(response.status), str(response.reason))
|
||||
except: #otherwise
|
||||
logging.error("cannot get Pushover response")
|
||||
logging.debug("cannot get Pushover response", exc_info=True)
|
||||
return
|
||||
priority = '-1'
|
||||
else:
|
||||
priority = globalVars.config.get("Pushover","zvei_std_prio")
|
||||
|
||||
finally:
|
||||
logging.debug("close Pushover-Connection")
|
||||
try:
|
||||
request.close()
|
||||
except:
|
||||
pass
|
||||
message = globalVars.config.get("Pushover", "zvei_message")
|
||||
title = globalVars.config.get("Pushover", "zvei_title")
|
||||
logging.debug("Sending message: %s", message)
|
||||
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
elif typ == "POC":
|
||||
|
||||
#
|
||||
# Pushover-Request
|
||||
#
|
||||
logging.debug("send Pushover for %s", typ)
|
||||
if globalVars.config.get("Pushover", "poc_spec_ric") == '0':
|
||||
if data["function"] == '1':
|
||||
priority = globalVars.config.get("Pushover", "SubA")
|
||||
elif data["function"] == '2':
|
||||
priority = globalVars.config.get("Pushover", "SubB")
|
||||
elif data["function"] == '3':
|
||||
priority = globalVars.config.get("Pushover", "SubC")
|
||||
elif data["function"] == '4':
|
||||
priority = globalVars.config.get("Pushover", "SubD")
|
||||
else:
|
||||
priority = 0
|
||||
else:
|
||||
if data["ric"] in globalVars.config.get("Pushover", "poc_prio2"):
|
||||
priority = 2
|
||||
elif data["ric"] in globalVars.config.get("Pushover","poc_prio1"):
|
||||
priority = 1
|
||||
elif data["ric"] in globalVars.config.get("Pushover","poc_prio0"):
|
||||
priority = 0
|
||||
else:
|
||||
priority = -1
|
||||
|
||||
message = globalVars.config.get("Pushover", "poc_message")
|
||||
title = globalVars.config.get("Pushover", "poc_title")
|
||||
|
||||
else:
|
||||
logging.warning("Invalid type: %s", typ)
|
||||
|
||||
try:
|
||||
# replace the wildcards
|
||||
message = wildcardHandler.replaceWildcards(message, data)
|
||||
title = wildcardHandler.replaceWildcards(title, data)
|
||||
sound = globalVars.config.get("Pushover", "sound")
|
||||
# set Default-Sound
|
||||
if not sound:
|
||||
sound = "pushover"
|
||||
|
||||
# start the connection
|
||||
conn = httplib.HTTPSConnection("api.pushover.net:443")
|
||||
conn.request("POST", "/1/messages.json",
|
||||
urllib.urlencode({
|
||||
"token": globalVars.config.get("Pushover", "api_key"),
|
||||
"user": globalVars.config.get("Pushover", "user_key"),
|
||||
"message": message,
|
||||
"html": globalVars.config.get("Pushover", "html"),
|
||||
"title": title,
|
||||
"sound": sound,
|
||||
"priority": priority,
|
||||
"retry": globalVars.config.get("Pushover", "retry"),
|
||||
"expire": globalVars.config.get("Pushover", "expire")
|
||||
}), {"Content-type": "application/x-www-form-urlencoded"})
|
||||
|
||||
except:
|
||||
logging.error("cannot send Pushover request")
|
||||
logging.debug("cannot send Pushover request", exc_info=True)
|
||||
return
|
||||
|
||||
try:
|
||||
#
|
||||
# check Pushover-Response
|
||||
#
|
||||
response = conn.getresponse()
|
||||
if str(response.status) == "200": # Check Pushover Response and print a Log or Error
|
||||
logging.debug("Pushover response: %s - %s", str(response.status), str(response.reason))
|
||||
else:
|
||||
logging.warning("Pushover response: %s - %s", str(response.status), str(response.reason))
|
||||
except: # otherwise
|
||||
logging.error("cannot get Pushover response")
|
||||
logging.debug("cannot get Pushover response", exc_info=True)
|
||||
return
|
||||
|
||||
finally:
|
||||
logging.debug("close Pushover-Connection")
|
||||
try:
|
||||
request.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,16 @@ This `.run()` routine is called every time an alarm comes in
|
|||
|
||||
Here are the information from BOSWatch available. See section `5. Process the data from BOSWatch`
|
||||
|
||||
#### 1.4 Requirements
|
||||
Add all required (which need to be installed separately) python packages to a requirements.txt in the plugin directory so that the user can simply install all requirements for this plugin.
|
||||
|
||||
For examples look at [the Telegram plugin](Telegram/requirements.txt)
|
||||
|
||||
##### 1.4.1 Requirement installation
|
||||
To install the packages from the requirements.txt run
|
||||
`pip install -r /path/to/plugin/directory/requirements.txt`
|
||||
Or because for the current version (2.5) Python2 is required
|
||||
`pip2 install -r /path/to/plungin/directory/requirements.txt` will work for sure
|
||||
|
||||
## 2. Use Global Logging
|
||||
#### 2.1 Init and Use
|
||||
|
|
@ -193,6 +203,7 @@ In the data map are the folowing informations:
|
|||
- ric
|
||||
- function
|
||||
- functionChar
|
||||
- ricFuncChar
|
||||
- msg
|
||||
- bitrate
|
||||
- description
|
||||
|
|
|
|||
|
|
@ -59,6 +59,20 @@ def run(typ,freq,data):
|
|||
try:
|
||||
if configHandler.checkConfig("Sms77"): #read and debug the config
|
||||
|
||||
# create an empty message an fill it with the required information
|
||||
message = "Alarm"
|
||||
if typ == "FMS":
|
||||
logging.debug("FMS detected, building message")
|
||||
message = data["description"]+"<br>"+data["status"]
|
||||
elif typ == "ZVEI":
|
||||
logging.debug("ZVEI detected, building message")
|
||||
message = data["zvei"]+" - "+data["description"]
|
||||
elif typ == "POC":
|
||||
logging.debug("POC detected, building message")
|
||||
message = data["description"]+"<br>"+data["msg"].replace(";", "<br>")
|
||||
else:
|
||||
logging.warning("Invalid typ - use empty message")
|
||||
|
||||
try:
|
||||
|
||||
#
|
||||
|
|
@ -66,15 +80,15 @@ def run(typ,freq,data):
|
|||
#
|
||||
logging.debug("send Sms77 %s", typ)
|
||||
|
||||
conn = httplib.HTTPSConnection("gateway.sms77.de:443")
|
||||
conn.request("POST", "",
|
||||
conn = httplib.HTTPSConnection("gateway.sms77.io",443)
|
||||
conn.request("POST", "/api/sms",
|
||||
urllib.urlencode({
|
||||
"u": globalVars.config.get("Sms77", "user"),
|
||||
"p": globalVars.config.get("Sms77", "password"),
|
||||
"to": globalVars.config.get("Sms77", "to"),
|
||||
"from": globalVars.config.get("Sms77", "from"),
|
||||
"type": globalVars.config.get("Sms77", "type"),
|
||||
"text": data["description"]+"<br>"+data["msg"].replace(";", "<br>")
|
||||
"text": message
|
||||
}),{"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"})
|
||||
|
||||
except:
|
||||
|
|
|
|||
|
|
@ -4,26 +4,29 @@
|
|||
"""
|
||||
Plugin to send FMS-, ZVEI- and POCSAG-messages via Telegram
|
||||
@author: Peter Laemmle
|
||||
@requires: Telegram BOT token, Telegram chat ID, library python-telegram-bot and optional googlemaps
|
||||
@requires: Telegram BOT token, Telegram chat ID, library python-telegram-bot and optional requests and json
|
||||
"""
|
||||
|
||||
#
|
||||
# Imports
|
||||
#
|
||||
import logging # Global logger
|
||||
import urllib, telegram, googlemaps
|
||||
import telegram
|
||||
from telegram.error import (TelegramError, Unauthorized, BadRequest, NetworkError)
|
||||
from includes import globalVars # Global variables
|
||||
if globalVars.config.get("Telegram","RICforLocationAPIKey"):
|
||||
import requests, json
|
||||
|
||||
# Helper function, uncomment to use
|
||||
from includes.helper import wildcardHandler
|
||||
from includes.helper import configHandler
|
||||
from includes.helper import timeHandler
|
||||
|
||||
# local variables
|
||||
BOTTokenAPIKey = None
|
||||
BOTChatIDAPIKey = None
|
||||
RICforLocationAPIKey = None
|
||||
GoogleAPIKey = None
|
||||
RoutingOrigin = None
|
||||
|
||||
##
|
||||
#
|
||||
|
|
@ -41,12 +44,14 @@ def onLoad():
|
|||
global BOTChatIDAPIKey
|
||||
global RICforLocationAPIKey
|
||||
global GoogleAPIKey
|
||||
global RoutingOrigin
|
||||
|
||||
configHandler.checkConfig("Telegram")
|
||||
BOTTokenAPIKey = globalVars.config.get("Telegram","BOTTokenAPIKey")
|
||||
BOTChatIDAPIKey = globalVars.config.get("Telegram","BOTChatIDAPIKey")
|
||||
RICforLocationAPIKey = globalVars.config.get("Telegram","RICforLocationAPIKey")
|
||||
GoogleAPIKey = globalVars.config.get("Telegram","GoogleAPIKey")
|
||||
RoutingOrigin = globalVars.config.get("Telegram","RoutingOrigin")
|
||||
|
||||
return
|
||||
|
||||
|
|
@ -78,29 +83,38 @@ def run(typ,freq,data):
|
|||
try:
|
||||
########## User Plugin CODE ##########
|
||||
try:
|
||||
if typ == "POC":
|
||||
logging.debug("Compose output from POCSAG-message")
|
||||
if typ in ("POC", "FMS", "ZVEI"):
|
||||
logging.debug("Read format and compose output for %s-message" % typ)
|
||||
# compose message content
|
||||
output = timeHandler.curtime()+"\n"+data["ric"]+"("+data["functionChar"]+")\n"+data["description"]+"\n"+data["msg"]
|
||||
text = globalVars.config.get("Telegram", "%s_message" % typ)
|
||||
text = wildcardHandler.replaceWildcards(text, data)
|
||||
|
||||
# Initiate Telegram Bot
|
||||
logging.debug("Initiate Telegram BOT")
|
||||
bot = telegram.Bot(token='%s' % BOTTokenAPIKey)
|
||||
# Send message to chat via Telegram BOT API
|
||||
logging.debug("Send message to chat via Telegram BOT API")
|
||||
bot.sendMessage('%s' % BOTChatIDAPIKey, output)
|
||||
bot.sendMessage('%s' % BOTChatIDAPIKey, text, parse_mode=telegram.ParseMode.HTML)
|
||||
|
||||
# Generate location information only for specific RIC
|
||||
if data["ric"] == RICforLocationAPIKey:
|
||||
if typ == "POC" and data["ric"] == RICforLocationAPIKey:
|
||||
# Generate map
|
||||
logging.debug("Extract address from POCSAG message")
|
||||
address = "+".join(data["msg"].split(')')[0].split('/',1)[1].replace('(',' ').split())
|
||||
|
||||
# Retrieve directions using Google API
|
||||
logging.debug("Retrieve polylines from Directions API")
|
||||
url = "".join(["https://maps.googleapis.com/maps/api/directions/json?origin=",
|
||||
RoutingOrigin, "&destination=", address, "&mode=driving&key=", GoogleAPIKey])
|
||||
response = json.loads(requests.get(url).content.decode('utf-8'))
|
||||
logging.debug("Directions API return status: %s" % response['status'])
|
||||
# Retrieve static maps using Google API
|
||||
logging.debug("Retrieve maps from Google")
|
||||
url = "+".join(["http://maps.googleapis.com/maps/api/staticmap?markers=", address, "&size=480x640&maptype=roadmap&zoom=16&key=", GoogleAPIKey])
|
||||
urllib.urlretrieve(url, "overview_map.png")
|
||||
url = "+".join(["http://maps.googleapis.com/maps/api/staticmap?markers=", address, "&size=240x320&scale=2&maptype=hybrid&zoom=17&key=", GoogleAPIKey])
|
||||
urllib.urlretrieve(url, "detail_map.png")
|
||||
url = "".join(["https://maps.googleapis.com/maps/api/staticmap?&size=480x640&maptype=roadmap&path=enc:",
|
||||
response['routes'][0]['overview_polyline']['points'], "&language=de&key=", GoogleAPIKey])
|
||||
with open("overview_map.png", "wb") as img: img.write(requests.get(url).content)
|
||||
url = "".join(["https://maps.googleapis.com/maps/api/staticmap?markers=",
|
||||
address, "&size=240x320&scale=2&maptype=hybrid&zoom=17&language=de&key=", GoogleAPIKey])
|
||||
with open("detail_map.png", "wb") as img: img.write(requests.get(url).content)
|
||||
|
||||
# Send message and map with Telegram
|
||||
logging.debug("Send message and maps via Telegram BOT")
|
||||
|
|
@ -109,32 +123,15 @@ def run(typ,freq,data):
|
|||
|
||||
# Geocoding of address
|
||||
logging.debug("Geocode address")
|
||||
gcode = googlemaps.Client(key='%s' % GoogleAPIKey)
|
||||
gcode_result = gcode.geocode(address)
|
||||
url = "".join(["https://maps.googleapis.com/maps/api/geocode/json?address=",
|
||||
address, "&language=de&key=", GoogleAPIKey])
|
||||
gcode_result = json.loads(requests.get(url).content)
|
||||
logging.debug("Geocoding API return status: %s" % gcode_result['status'])
|
||||
logging.debug("Send location via Telegram BOT API")
|
||||
bot.sendLocation('%s' % BOTChatIDAPIKey, gcode_result[0]['geometry']['location']['lat'], gcode_result[0]['geometry']['location']['lng'], disable_notification='true')
|
||||
elif typ == "FMS":
|
||||
logging.debug("Compose output from FMS-message")
|
||||
# compose message content
|
||||
output = timeHandler.curtime()+"\n"+data["fms"]+"\n"+data["description"]+"\n"+data["status"]
|
||||
|
||||
# Initiate Telegram Bot
|
||||
logging.debug("Initiate Telegram BOT")
|
||||
bot = telegram.Bot(token='%s' % BOTTokenAPIKey)
|
||||
# Send message to chat via Telegram BOT API
|
||||
logging.debug("Send message to chat via Telegram BOT API")
|
||||
bot.sendMessage('%s' % BOTChatIDAPIKey, output)
|
||||
elif typ == "ZVEI":
|
||||
logging.debug("Compose output from ZVEI-message")
|
||||
# compose message content
|
||||
output = timeHandler.curtime()+"\n"+data["zvei"]+"\n"+data["description"]
|
||||
|
||||
# Initiate Telegram Bot
|
||||
logging.debug("Initiate Telegram BOT")
|
||||
bot = telegram.Bot(token='%s' % BOTTokenAPIKey)
|
||||
# Send message to chat via Telegram BOT API
|
||||
logging.debug("Send message to chat via Telegram BOT API")
|
||||
bot.sendMessage('%s' % BOTChatIDAPIKey, output)
|
||||
bot.sendLocation('%s' % BOTChatIDAPIKey,
|
||||
gcode_result[results][0]['geometry']['location']['lat'],
|
||||
gcode_result[results][0]['geometry']['location']['lng'],
|
||||
disable_notification='true')
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
except Unauthorized:
|
||||
|
|
|
|||
2
plugins/Telegram/requirements.txt
Normal file
2
plugins/Telegram/requirements.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
python-telegram-bot
|
||||
requests
|
||||
|
|
@ -13,6 +13,7 @@ import logging # Global logger
|
|||
|
||||
import smtplib #for the SMTP client
|
||||
from email.mime.text import MIMEText # Import the email modules we'll need
|
||||
from email.header import Header # Import the email modules we'll need
|
||||
from email.utils import formatdate # need for confirm to RFC2822 standard
|
||||
from email.utils import make_msgid # need for confirm to RFC2822 standard
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ def doSendmail(server, subject, mailtext):
|
|||
msg = MIMEText(mailtext, 'plain', 'UTF-8')
|
||||
msg['From'] = globalVars.config.get("eMail", "from")
|
||||
msg['To'] = globalVars.config.get("eMail", "to")
|
||||
msg['Subject'] = subject
|
||||
msg['Subject'] = Header(subject, 'UTF-8')
|
||||
msg['Date'] = formatdate()
|
||||
msg['Message-Id'] = make_msgid()
|
||||
msg['Priority'] = globalVars.config.get("eMail", "priority")
|
||||
|
|
@ -137,7 +138,7 @@ def run(typ,freq,data):
|
|||
# read mailtext-structure from config.ini
|
||||
mailtext = globalVars.config.get("eMail", "fms_message")
|
||||
# replace wildcards with helper function
|
||||
mailtext = wildcardHandler.replaceWildcards(mailtext, data, lineBrakeAllowed=True)
|
||||
mailtext = wildcardHandler.replaceWildcards(mailtext, data)
|
||||
|
||||
# send eMail
|
||||
doSendmail(server, subject, mailtext)
|
||||
|
|
@ -157,7 +158,7 @@ def run(typ,freq,data):
|
|||
# read mailtext-structure from config.ini
|
||||
mailtext = globalVars.config.get("eMail", "zvei_message")
|
||||
# replace wildcards with helper function
|
||||
mailtext = wildcardHandler.replaceWildcards(mailtext, data, lineBrakeAllowed=True)
|
||||
mailtext = wildcardHandler.replaceWildcards(mailtext, data)
|
||||
|
||||
# send eMail
|
||||
doSendmail(server, subject, mailtext)
|
||||
|
|
@ -177,7 +178,7 @@ def run(typ,freq,data):
|
|||
# read mailtext-structure from config.ini
|
||||
mailtext = globalVars.config.get("eMail", "poc_message")
|
||||
# replace wildcards with helper function
|
||||
mailtext = wildcardHandler.replaceWildcards(mailtext, data, lineBrakeAllowed=True)
|
||||
mailtext = wildcardHandler.replaceWildcards(mailtext, data)
|
||||
|
||||
# send eMail
|
||||
doSendmail(server, subject, mailtext)
|
||||
|
|
|
|||
113
plugins/fhemCmd/fhemCmd.py
Normal file
113
plugins/fhemCmd/fhemCmd.py
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
"""
|
||||
Plugin for calling FHEM home automation
|
||||
|
||||
@author: Marco Schotthöfer
|
||||
|
||||
@requires: python-fhem (pip install fhem)
|
||||
"""
|
||||
|
||||
#
|
||||
# Imports
|
||||
#
|
||||
import logging # Global logger
|
||||
from includes import globalVars # Global variables
|
||||
|
||||
# Helper function, uncomment to use
|
||||
#from includes.helper import timeHandler
|
||||
#from includes.helper import wildcardHandler
|
||||
from includes.helper import configHandler
|
||||
from includes.helper import wildcardHandler
|
||||
import fhem
|
||||
|
||||
##
|
||||
#
|
||||
# onLoad (init) function of plugin
|
||||
# will be called one time by the pluginLoader on start
|
||||
#
|
||||
def onLoad():
|
||||
"""
|
||||
While loading the plugins by pluginLoader.loadPlugins()
|
||||
this onLoad() routine is called one time for initialize the plugin
|
||||
|
||||
@requires: nothing
|
||||
|
||||
@return: nothing
|
||||
@exception: Exception if init has an fatal error so that the plugin couldn't work
|
||||
|
||||
"""
|
||||
try:
|
||||
########## User onLoad CODE ##########
|
||||
pass
|
||||
########## User onLoad CODE ##########
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
raise
|
||||
|
||||
##
|
||||
#
|
||||
# Main function of plugin
|
||||
# will be called by the alarmHandler
|
||||
#
|
||||
def run(typ,freq,data):
|
||||
"""
|
||||
This function is the implementation of the Plugin.
|
||||
|
||||
If necessary the configuration hast to be set in the config.ini.
|
||||
|
||||
@type typ: string (FMS|ZVEI|POC)
|
||||
@param typ: Typ of the dataset
|
||||
@type data: map of data (structure see readme.md in plugin folder)
|
||||
@param data: Contains the parameter for dispatch
|
||||
@type freq: string
|
||||
@keyword freq: frequency of the SDR Stick
|
||||
|
||||
@requires: If necessary the configuration hast to be set in the config.ini.
|
||||
|
||||
@return: nothing
|
||||
@exception: nothing, make sure this function will never thrown an exception
|
||||
"""
|
||||
try:
|
||||
if configHandler.checkConfig("fhemCmd"): #read and debug the config (let empty if no config used)
|
||||
|
||||
protocol = globalVars.config.get("fhemCmd", "protocol")
|
||||
logging.debug("protocol: %s", protocol)
|
||||
|
||||
server = globalVars.config.get("fhemCmd", "server")
|
||||
logging.debug("server: %s", server)
|
||||
|
||||
port = globalVars.config.get("fhemCmd", "port")
|
||||
logging.debug("port: %s", port)
|
||||
|
||||
username = globalVars.config.get("fhemCmd", "username")
|
||||
logging.debug("username: %s", username)
|
||||
|
||||
password = globalVars.config.get("fhemCmd", "password")
|
||||
logging.debug("password: %s", password)
|
||||
|
||||
########## User Plugin CODE ##########
|
||||
if typ == "FMS":
|
||||
fhemCommand = globalVars.config.get("fhemCmd", "commandFMS")
|
||||
elif typ == "ZVEI":
|
||||
fhemCommand = globalVars.config.get("fhemCmd", "commandZVEI")
|
||||
elif typ == "POC":
|
||||
fhemCommand = globalVars.config.get("fhemCmd", "commandPOC")
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
return False
|
||||
|
||||
fhemCommand = wildcardHandler.replaceWildcards(fhemCommand, data)
|
||||
logging.debug("fhemCommand: %s", fhemCommand)
|
||||
|
||||
fh = fhem.Fhem(server=server, protocol=protocol, port=port, username=username, password=password)
|
||||
|
||||
fh.send_cmd(fhemCommand)
|
||||
del fh
|
||||
########## User Plugin CODE ##########
|
||||
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
1
plugins/fhemCmd/requirements.txt
Normal file
1
plugins/fhemCmd/requirements.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
fhem
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
firEmergency-Plugin to dispatch ZVEI- and POCSAG - messages to firEmergency
|
||||
|
||||
firEmergency configuration:
|
||||
- set input to "FMS32" at Port 5555
|
||||
- set input to "Standartschnittstelle" at Port 5555
|
||||
|
||||
@autor: Smith-fms
|
||||
|
||||
|
|
|
|||
118
plugins/gpiocontrol/gpiocontrol.py
Normal file
118
plugins/gpiocontrol/gpiocontrol.py
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
"""
|
||||
|
||||
@author: KS
|
||||
|
||||
@requires: none
|
||||
"""
|
||||
|
||||
# Imports
|
||||
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
import threading
|
||||
|
||||
import logging # Global logger
|
||||
from includes import globalVars # Global variables
|
||||
|
||||
# Helper function, uncomment to use
|
||||
from includes.helper import timeHandler
|
||||
from includes.helper import wildcardHandler
|
||||
from includes.helper import configHandler
|
||||
|
||||
##
|
||||
#
|
||||
# onLoad (init) function of plugin
|
||||
# will be called one time by the pluginLoader on start
|
||||
#
|
||||
def onLoad():
|
||||
"""
|
||||
While loading the plugins by pluginLoader.loadPlugins()
|
||||
this onLoad() routine is called one time for initialize the plugin
|
||||
|
||||
@requires: nothing
|
||||
|
||||
@return: nothing
|
||||
@exception: Exception if init has an fatal error so that the plugin couldn't work
|
||||
|
||||
"""
|
||||
global GPIOPIN
|
||||
global waitTime
|
||||
|
||||
GPIOPIN = globalVars.config.getint("gpiocontrol","pin")
|
||||
waitTime = globalVars.config.getint("gpiocontrol","triggertime")
|
||||
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setup(GPIOPIN, GPIO.OUT)
|
||||
|
||||
#GPIO schalten beim START
|
||||
#GPIO.output(GPIOPIN, GPIO.LOW)
|
||||
#time.sleep(1)
|
||||
|
||||
GPIO.output(GPIOPIN, GPIO.HIGH)
|
||||
|
||||
return
|
||||
|
||||
#
|
||||
#
|
||||
# Main function of plugin
|
||||
# will be called by the alarmHandler
|
||||
#
|
||||
def run(typ,freq,data):
|
||||
"""
|
||||
@type typ: string (FMS|ZVEI|POC)
|
||||
@param typ: Typ of the dataset
|
||||
@type data: map of data (structure see readme.md in plugin folder)
|
||||
@param data: Contains the parameter for dispatch
|
||||
@type freq: string
|
||||
@keyword freq: frequency of the SDR Stick
|
||||
|
||||
@requires: If necessary the configuration hast to be set in the config.ini.
|
||||
|
||||
@return: nothing
|
||||
@exception: nothing, make sure this function will never thrown an exception
|
||||
"""
|
||||
try:
|
||||
if configHandler.checkConfig("gpiocontrol"): #read and debug the config (let empty if no config used)
|
||||
|
||||
logging.debug(globalVars.config.get("gpiocontrol", "pin"))
|
||||
logging.debug(globalVars.config.get("gpiocontrol", "triggertime"))
|
||||
|
||||
########## User Plugin CODE ##########
|
||||
if typ == "FMS":
|
||||
th = threading.Thread(target = trigger)
|
||||
th.start()
|
||||
#logging.warning("%s not supported", typ)
|
||||
elif typ == "ZVEI":
|
||||
th = threading.Thread(target = trigger)
|
||||
th.start()
|
||||
#logging.warning("%s not supported", typ)
|
||||
elif typ == "POC":
|
||||
if globalVars.config.get("gpiocontrol", "activerics") == "":
|
||||
th = threading.Thread(target = trigger)
|
||||
th.start()
|
||||
else:
|
||||
if data["ric"] in globalVars.config.get("gpiocontrol", "activerics"):
|
||||
th = threading.Thread(target = trigger)
|
||||
th.start()
|
||||
else:
|
||||
logging.info("Ric not in activerics")
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
########## User Plugin CODE ##########
|
||||
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
|
||||
def trigger():
|
||||
GPIO.output(GPIOPIN, GPIO.LOW)
|
||||
logging.info("GPIOPIN %s angeschaltet", GPIOPIN)
|
||||
time.sleep(waitTime)
|
||||
GPIO.output(GPIOPIN, GPIO.HIGH)
|
||||
logging.info("GPIOPIN %s ausgeschaltet", GPIOPIN)
|
||||
|
||||
return
|
||||
|
|
@ -14,6 +14,7 @@ httpRequest-Plugin to dispatch FMS-, ZVEI- and POCSAG - messages to an URL
|
|||
#
|
||||
# Imports
|
||||
#
|
||||
import urllib
|
||||
import urllib2
|
||||
import logging # Global logger
|
||||
from includes import globalVars # Global variables
|
||||
|
|
@ -67,36 +68,43 @@ def run(typ,freq,data):
|
|||
|
||||
try:
|
||||
#
|
||||
# Create URL
|
||||
# Make a copy of the data field to not overwrite the data in it
|
||||
# Replace special characters in dataCopy Strings for URL
|
||||
#
|
||||
dataCopy = dict(data)
|
||||
for key in dataCopy:
|
||||
if isinstance(dataCopy[key], basestring):
|
||||
dataCopy[key] = urllib.quote(dataCopy[key])
|
||||
#
|
||||
# Get URLs
|
||||
#
|
||||
if typ == "FMS":
|
||||
url = globalVars.config.get("httpRequest", "fms_url") #Get URL
|
||||
url = wildcardHandler.replaceWildcards(url, data) # replace wildcards with helper function
|
||||
url = url.replace(" ","%20") # replace space with %20 to be a vaild http request
|
||||
urls = globalVars.config.get("httpRequest", "fms_url").split(",")
|
||||
elif typ == "ZVEI":
|
||||
url = globalVars.config.get("httpRequest", "zvei_url") #Get URL
|
||||
url = wildcardHandler.replaceWildcards(url, data) # replace wildcards with helper function
|
||||
url = url.replace(" ","%20") # replace space with %20 to be a vaild http request
|
||||
urls = globalVars.config.get("httpRequest", "zvei_url").split(",")
|
||||
elif typ == "POC":
|
||||
url = globalVars.config.get("httpRequest", "poc_url") #Get URL
|
||||
url = wildcardHandler.replaceWildcards(url, data) # replace wildcards with helper function
|
||||
url = url.replace(" ","%20") # replace space with %20 to be a vaild http request
|
||||
urls = globalVars.config.get("httpRequest", "poc_url").split(",")
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
return
|
||||
|
||||
#
|
||||
# replace wildcards
|
||||
#
|
||||
for (i, url) in enumerate(urls):
|
||||
urls[i] = wildcardHandler.replaceWildcards(urls[i].strip(), dataCopy)
|
||||
#
|
||||
# HTTP-Request
|
||||
#
|
||||
logging.debug("send %s HTTP request", typ)
|
||||
logging.debug("send %s HTTP requests", typ)
|
||||
|
||||
try:
|
||||
#resp = urllib2.urlopen(url)
|
||||
urllib2.urlopen(url)
|
||||
except urllib2.HTTPError as e:
|
||||
logging.warning("HTTP response: %s", e.code)
|
||||
except urllib2.URLError as e:
|
||||
logging.warning("HTTP-specific error: %s", e.args)
|
||||
for url in urls:
|
||||
try:
|
||||
urllib2.urlopen(url)
|
||||
except urllib2.HTTPError as e:
|
||||
logging.warning("HTTP response: %s", e.code)
|
||||
except urllib2.URLError as e:
|
||||
logging.warning("HTTP-specific error: %s", e.args)
|
||||
|
||||
except:
|
||||
logging.error("cannot send HTTP request")
|
||||
|
|
|
|||
122
plugins/hue/hue.py
Normal file
122
plugins/hue/hue.py
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
"""
|
||||
|
||||
Plugin to control Philips hue lights and switches
|
||||
|
||||
@author: Fabian Kessler
|
||||
|
||||
@requires: none
|
||||
"""
|
||||
|
||||
#
|
||||
# Imports
|
||||
#
|
||||
import logging # Global logger
|
||||
from includes import globalVars # Global variables
|
||||
import json
|
||||
import requests
|
||||
import time
|
||||
|
||||
# Helper function, uncomment to use
|
||||
#from includes.helper import timeHandler
|
||||
#from includes.helper import wildcardHandler
|
||||
from includes.helper import configHandler
|
||||
|
||||
##
|
||||
#
|
||||
# onLoad (init) function of plugin
|
||||
# will be called one time by the pluginLoader on start
|
||||
#
|
||||
def onLoad():
|
||||
"""
|
||||
While loading the plugins by pluginLoader.loadPlugins()
|
||||
this onLoad() routine is called one time for initialize the plugin
|
||||
@requires: nothing
|
||||
@return: nothing
|
||||
@exception: Exception if init has an fatal error so that the plugin couldn't work
|
||||
"""
|
||||
try:
|
||||
########## User onLoad CODE ##########
|
||||
pass
|
||||
########## User onLoad CODE ##########
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
raise
|
||||
|
||||
##
|
||||
#
|
||||
# Main function of plugin
|
||||
# will be called by the alarmHandler
|
||||
#
|
||||
def run(typ,freq,data):
|
||||
"""
|
||||
This function is the implementation of the Plugin.
|
||||
If necessary the configuration hast to be set in the config.ini.
|
||||
@type typ: string (FMS|ZVEI|POC)
|
||||
@param typ: Typ of the dataset
|
||||
@type data: map of data (structure see readme.md in plugin folder)
|
||||
@param data: Contains the parameter for dispatch
|
||||
@type freq: string
|
||||
@keyword freq: frequency of the SDR Stick
|
||||
@requires: If necessary the configuration hast to be set in the config.ini.
|
||||
@return: nothing
|
||||
@exception: nothing, make sure this function will never thrown an exception
|
||||
"""
|
||||
try:
|
||||
if configHandler.checkConfig("hue"): #read and debug the config
|
||||
#for debugging
|
||||
"""logging.debug(globalVars.config.get("hue", "bridgeip"))
|
||||
logging.debug(globalVars.config.get("hue", "deviceid"))
|
||||
logging.debug(globalVars.config.get("hue", "apikey"))
|
||||
logging.debug(globalVars.config.getint("hue", "repeat"))
|
||||
logging.debug(globalVars.config.getint("hue", "timeon"))
|
||||
logging.debug(globalVars.config.getint("hue", "timeoff"))
|
||||
logging.debug(globalVars.config.getint("hue", "keepon"))"""
|
||||
|
||||
########## User Plugin CODE ##########
|
||||
if typ == "FMS":
|
||||
logging.warning("%s not supported", typ)
|
||||
elif typ == "ZVEI":
|
||||
logging.warning("%s not supported", typ)
|
||||
elif typ == "POC":
|
||||
#logging.warning("%s not supported", typ)
|
||||
logging.debug("POC received")
|
||||
bridgeip = globalVars.config.get("hue", "bridgeip")
|
||||
deviceid = globalVars.config.get("hue", "deviceid")
|
||||
apikey = globalVars.config.get("hue", "apikey")
|
||||
repeat = globalVars.config.getint("hue", "repeat")
|
||||
timeon = globalVars.config.getint("hue", "timeon")
|
||||
timeoff = globalVars.config.getint("hue", "timeoff")
|
||||
keepon = globalVars.config.getint("hue", "keepon")
|
||||
data_on = '{"on":true}'
|
||||
data_off = '{"on":false}'
|
||||
url = "http://" + bridgeip + "/api/" + apikey + "/lights/" + deviceid + "/state"
|
||||
logging.debug("hue REST API URL: %s", url)
|
||||
|
||||
#blinking
|
||||
for _ in xrange(repeat):
|
||||
requests.put(url, data=data_on)
|
||||
logging.debug("on for %s seconds", timeon)
|
||||
time.sleep(timeon)
|
||||
requests.put(url, data=data_off)
|
||||
logging.debug("off for %s seconds", timeoff)
|
||||
time.sleep(timeoff)
|
||||
if keepon > 0:
|
||||
logging.debug("switch to on and wait for keepon to expire")
|
||||
requests.put(url, data=data_on)
|
||||
logging.debug("keep on for %s seconds", keepon)
|
||||
time.sleep(keepon)
|
||||
requests.put(url, data=data_off)
|
||||
else:
|
||||
logging.debug("switch to on and exit plugin")
|
||||
requests.put(url, data=data_on)
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
########## User Plugin CODE ##########
|
||||
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
121
plugins/mqtt/mqtt.py
Normal file
121
plugins/mqtt/mqtt.py
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
"""
|
||||
@author: KS
|
||||
|
||||
@requires: paho-mqtt
|
||||
"""
|
||||
|
||||
#
|
||||
# Imports
|
||||
#
|
||||
import logging # Global logger
|
||||
from includes import globalVars # Global variables
|
||||
|
||||
# Helper function, uncomment to use
|
||||
from includes.helper import timeHandler
|
||||
from includes.helper import wildcardHandler
|
||||
from includes.helper import configHandler
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
import json
|
||||
|
||||
##
|
||||
#
|
||||
# onLoad (init) function of plugin
|
||||
# will be called one time by the pluginLoader on start
|
||||
#
|
||||
def onLoad():
|
||||
"""
|
||||
While loading the plugins by pluginLoader.loadPlugins()
|
||||
this onLoad() routine is called one time for initialize the plugin
|
||||
|
||||
@requires: nothing
|
||||
|
||||
@return: nothing
|
||||
@exception: Exception if init has an fatal error so that the plugin couldn't work
|
||||
|
||||
"""
|
||||
try:
|
||||
########## User onLoad CODE ##########
|
||||
pass
|
||||
########## User onLoad CODE ##########
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
raise
|
||||
|
||||
##
|
||||
#
|
||||
# Main function of plugin
|
||||
# will be called by the alarmHandler
|
||||
#
|
||||
def run(typ,freq,data):
|
||||
"""
|
||||
This function is the implementation of the Plugin.
|
||||
|
||||
If necessary the configuration hast to be set in the config.ini.
|
||||
|
||||
@type typ: string (FMS|ZVEI|POC)
|
||||
@param typ: Typ of the dataset
|
||||
@type data: map of data (structure see readme.md in plugin folder)
|
||||
@param data: Contains the parameter for dispatch
|
||||
@type freq: string
|
||||
@keyword freq: frequency of the SDR Stick
|
||||
|
||||
@requires: If necessary the configuration hast to be set in the config.ini.
|
||||
|
||||
@return: nothing
|
||||
@exception: nothing, make sure this function will never thrown an exception
|
||||
"""
|
||||
try:
|
||||
if configHandler.checkConfig("mqtt"): #read and debug the config (let empty if no config used)
|
||||
|
||||
logging.debug(globalVars.config.get("mqtt", "brokeraddress"))
|
||||
logging.debug(globalVars.config.get("mqtt", "topic"))
|
||||
########## User Plugin CODE ##########
|
||||
broker_address = globalVars.config.get("mqtt", "brokeraddress")
|
||||
topic = globalVars.config.get("mqtt", "topic")
|
||||
mqttClient = mqtt.Client()
|
||||
|
||||
if typ == "FMS":
|
||||
x = {
|
||||
"fms": data["fms"],
|
||||
"status": data["status"],
|
||||
"direction": data["direction"],
|
||||
"directionText": data["directionText"],
|
||||
"tsi": data["tsi"],
|
||||
"description": data["description"],
|
||||
"timestamp": timeHandler.curtime()
|
||||
}
|
||||
elif typ == "ZVEI":
|
||||
x = {
|
||||
"zvei": data["zvei"],
|
||||
"description": data["description"],
|
||||
"timestamp": timeHandler.curtime()
|
||||
}
|
||||
elif typ == "POC":
|
||||
functionText = "%FUNCTEXT%"
|
||||
functionText = wildcardHandler.replaceWildcards(functionText, data)
|
||||
x = {
|
||||
"ric": data["ric"],
|
||||
"function": data["function"],
|
||||
"functionText": functionText,
|
||||
"functionChar": data["functionChar"],
|
||||
"msg": data["msg"],
|
||||
"bitrate": data["bitrate"],
|
||||
"description": data["description"],
|
||||
"timestamp": timeHandler.curtime()
|
||||
}
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
|
||||
y = json.dumps(x)
|
||||
mqttClient.connect(broker_address)
|
||||
mqttClient.publish(topic,y)
|
||||
########## User Plugin CODE ##########
|
||||
|
||||
except:
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
1
plugins/mqtt/requirements.txt
Normal file
1
plugins/mqtt/requirements.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
paho-mqtt
|
||||
|
|
@ -1,304 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
notifyMyAndroid-Plugin to dispatch FMS-, ZVEI- and POCSAG-messages via UDP/TCP
|
||||
|
||||
@author: Jens Herrmann
|
||||
|
||||
@requires: notifyMyAndroid-Configuration has to be set in the config.ini
|
||||
"""
|
||||
|
||||
import logging # Global logger
|
||||
import csv # for loading the APIKeys
|
||||
|
||||
|
||||
from includes import globalVars # Global variables
|
||||
|
||||
from includes.helper import configHandler
|
||||
from includes.helper import timeHandler
|
||||
from includes.helper import stringConverter
|
||||
from includes.pynma import pynma
|
||||
|
||||
|
||||
# local variables
|
||||
application = "BOSWatch"
|
||||
APIKey = None
|
||||
remainingMsgs = None
|
||||
usecsv = False
|
||||
# data structures: xAPIKeyList[id][i] = (APIKey, priority, eventPrefix)
|
||||
fmsAPIKeyList = {}
|
||||
zveiAPIKeyList = {}
|
||||
pocAPIKeyList = {}
|
||||
|
||||
|
||||
def checkResponse(response, APIKey):
|
||||
"""
|
||||
Helper function to check the response of NMA
|
||||
|
||||
@type response: dict
|
||||
@param response: Response of the pyNMA.push() method
|
||||
@type data: string / array
|
||||
@param data: a string containing 1 key or an array of keys
|
||||
|
||||
@return: nothing
|
||||
"""
|
||||
# local variables
|
||||
global remainingMsgs
|
||||
try:
|
||||
#
|
||||
# check HTTP-Response
|
||||
#
|
||||
if str(response[APIKey]['code']) == "200": #Check HTTP Response an print a Log or Error
|
||||
logging.debug("NMA response: %s" , str(response[APIKey]['code']))
|
||||
remainingMsgs = response[APIKey]['remaining']
|
||||
if int(remainingMsgs) == 0:
|
||||
logging.error("NMA remaining msgs: %s" , str(remainingMsgs))
|
||||
if int(response[APIKey]['remaining']) < 20:
|
||||
logging.warning("NMA remaining msgs: %s" , str(remainingMsgs))
|
||||
else:
|
||||
logging.debug("NMA remaining msgs: %s" , str(remainingMsgs))
|
||||
else:
|
||||
logging.warning("NMA response: %s - %s" , str(response[APIKey]['code']), str(response[APIKey]['message']))
|
||||
except:
|
||||
logging.error("cannot read pynma response")
|
||||
logging.debug("cannot read pynma response", exc_info=True)
|
||||
return
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# onLoad (init) function of plugin
|
||||
# will be called one time by the pluginLoader on start
|
||||
#
|
||||
def onLoad():
|
||||
"""
|
||||
While loading the plugins by pluginLoader.loadPlugins()
|
||||
this onLoad() routine is called one time for initialize the plugin
|
||||
|
||||
@requires: nothing
|
||||
|
||||
@return: nothing
|
||||
"""
|
||||
# local variables
|
||||
global application
|
||||
global APIKey
|
||||
global usecsv
|
||||
|
||||
# load config:
|
||||
configHandler.checkConfig("notifyMyAndroid")
|
||||
application = stringConverter.convertToUnicode(globalVars.config.get("notifyMyAndroid","appName"))
|
||||
usecsv = globalVars.config.getboolean("notifyMyAndroid","usecsv")
|
||||
|
||||
# if no csv should use, we take the APIKey directly
|
||||
if usecsv == False:
|
||||
APIKey = globalVars.config.get("notifyMyAndroid","APIKey")
|
||||
else:
|
||||
# import the csv-file
|
||||
try:
|
||||
logging.debug("-- loading nma.csv")
|
||||
with open(globalVars.script_path+'/csv/nma.csv') as csvfile:
|
||||
# DictReader expected structure described in first line of csv-file
|
||||
reader = csv.DictReader(csvfile)
|
||||
for row in reader:
|
||||
logging.debug(row)
|
||||
# only import rows with an supported types
|
||||
supportedTypes = ["FMS", "ZVEI", "POC"]
|
||||
if row['typ'] in supportedTypes:
|
||||
try:
|
||||
if "FMS" in row['typ']:
|
||||
# if len for id in mainList raise an KeyErrorException, we have to init it...
|
||||
try:
|
||||
if len(fmsAPIKeyList[row['id']]) > 0:
|
||||
pass
|
||||
except KeyError:
|
||||
fmsAPIKeyList[row['id']] = []
|
||||
# data structure: fmsAPIKeyList[fms][i] = (APIKey, priority)
|
||||
fmsAPIKeyList[row['id']].append((row['APIKey'], row['priority'], row['eventPrefix']))
|
||||
|
||||
elif "ZVEI" in row['typ']:
|
||||
# if len for id in mainList raise an KeyErrorException, we have to init it...
|
||||
try:
|
||||
if len(zveiAPIKeyList[row['id']]) > 0:
|
||||
pass
|
||||
except KeyError:
|
||||
zveiAPIKeyList[row['id']] = []
|
||||
# data structure: zveiAPIKeyList[zvei][i] = (APIKey, priority)
|
||||
zveiAPIKeyList[row['id']].append((row['APIKey'], row['priority'], row['eventPrefix']))
|
||||
|
||||
elif "POC" in row['typ']:
|
||||
# if len for id in mainList raise an KeyErrorException, we have to init it...
|
||||
try:
|
||||
if len(pocAPIKeyList[row['id']]) > 0:
|
||||
pass
|
||||
except KeyError:
|
||||
pocAPIKeyList[row['id']] = []
|
||||
# data structure: zveiAPIKeyList[ric][i] = (APIKey, priority)
|
||||
pocAPIKeyList[row['id']].append((row['APIKey'], row['priority'], row['eventPrefix']))
|
||||
|
||||
except:
|
||||
# skip entry in case of an exception
|
||||
logging.debug("error in shifting...", exc_info=True)
|
||||
# if row['typ'] in supportedTypes
|
||||
# for row in reader:
|
||||
logging.debug("-- loading csv finished")
|
||||
except:
|
||||
logging.error("loading csvList for nma failed")
|
||||
logging.debug("loading csvList for nma failed", exc_info=True)
|
||||
raise
|
||||
# and if usecsv == True
|
||||
return
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# Main function of jsonSocket-plugin
|
||||
# will be called by the alarmHandler
|
||||
#
|
||||
def run(typ,freq,data):
|
||||
"""
|
||||
This function is the implementation of the notifyMyAndroid-Plugin.
|
||||
|
||||
The configuration is set in the config.ini.
|
||||
|
||||
@type typ: string (FMS|ZVEI|POC)
|
||||
@param typ: Typ of the dataset for sending via UDP/TCP
|
||||
@type data: map of data (structure see readme.md in plugin folder)
|
||||
@param data: Contains the parameter for dispatch to UDP.
|
||||
@type freq: string
|
||||
@keyword freq: frequency of the SDR Stick
|
||||
|
||||
@requires: notifyMyAndroid-Configuration has to be set in the config.ini
|
||||
|
||||
@return: nothing
|
||||
"""
|
||||
# local variables
|
||||
global fmsAPIKeyList
|
||||
global zveiAPIKeyList
|
||||
global pocAPIKeyList
|
||||
|
||||
try:
|
||||
try:
|
||||
#
|
||||
# initialize to pyNMA
|
||||
#
|
||||
nma = pynma.PyNMA()
|
||||
except:
|
||||
logging.error("cannot initialize pyNMA")
|
||||
logging.debug("cannot initialize pyNMA", exc_info=True)
|
||||
# Without class, plugin couldn't work
|
||||
return
|
||||
|
||||
else:
|
||||
# toDo is equals for all types, so only check if typ is supported
|
||||
supportedTypes = ["FMS", "ZVEI", "POC"]
|
||||
if typ in supportedTypes:
|
||||
logging.debug("Start %s to NMA", typ)
|
||||
try:
|
||||
# build event and msg
|
||||
# pyNMA expect strings are not in UTF-8
|
||||
event = stringConverter.convertToUnicode(data['description'])
|
||||
msg = timeHandler.getDateTime(data['timestamp'])
|
||||
if ("POC" in typ) and (len(data['msg']) > 0):
|
||||
msg += "\n" + data['msg']
|
||||
msg = stringConverter.convertToUnicode(msg)
|
||||
|
||||
# if not using csv-import, all is simple...
|
||||
if usecsv == False:
|
||||
response = nma.pushWithAPIKey(APIKey, application, event, msg, priority=globalVars.config.getint("notifyMyAndroid","priority"))
|
||||
checkResponse(response, APIKey)
|
||||
else:
|
||||
if "FMS" in typ:
|
||||
# lets look for fms in fmsAPIKeyList
|
||||
xID = data['fms']
|
||||
try:
|
||||
# data structure: fmsAPIKeyList[xID][i] = (xAPIKey, xPriority, xEventPrefix)
|
||||
for i in range(len(fmsAPIKeyList[xID])):
|
||||
xEvent = event
|
||||
(xAPIKey, xPriority, xEventPrefix) = fmsAPIKeyList[xID][i]
|
||||
if len(xEventPrefix) > 0:
|
||||
xEvent = xEventPrefix + ": " + xEvent
|
||||
response = nma.pushWithAPIKey(xAPIKey, application, xEvent, msg, priority=xPriority)
|
||||
checkResponse(response, xAPIKey)
|
||||
except KeyError:
|
||||
# nothing found
|
||||
pass
|
||||
|
||||
elif "ZVEI" in typ:
|
||||
# lets look for zvei in zveiAPIKeyList
|
||||
xID = data['zvei']
|
||||
try:
|
||||
# data structure: zveiAPIKeyList[xID][i] = (xAPIKey, xPriority, xEventPrefix)
|
||||
for i in range(len(zveiAPIKeyList[xID])):
|
||||
xEvent = event
|
||||
(xAPIKey, xPriority, xEventPrefix) = zveiAPIKeyList[xID][i]
|
||||
if len(xEventPrefix) > 0:
|
||||
xEvent = xEventPrefix + ": " + xEvent
|
||||
response = nma.pushWithAPIKey(xAPIKey, application, xEvent, msg, priority=xPriority)
|
||||
checkResponse(response, xAPIKey)
|
||||
except KeyError:
|
||||
# nothing found
|
||||
pass
|
||||
|
||||
elif "POC" in typ:
|
||||
xID = ""
|
||||
# 1. lets look for ric+functionChar in pocAPIKeyList
|
||||
try:
|
||||
xID = data['ric'] + data['functionChar']
|
||||
# data structure: pocAPIKeyList[xID][i] = (xAPIKey, xPriority, xEventPrefix)
|
||||
for i in range(len(pocAPIKeyList[xID])):
|
||||
xEvent = event
|
||||
(xAPIKey, xPriority, xEventPrefix) = pocAPIKeyList[xID][i]
|
||||
if len(xEventPrefix) > 0:
|
||||
xEvent = xEventPrefix + ": " + xEvent
|
||||
response = nma.pushWithAPIKey(xAPIKey, application, xEvent, msg, priority=xPriority)
|
||||
checkResponse(response, xAPIKey)
|
||||
except KeyError:
|
||||
# nothing found
|
||||
pass
|
||||
# 2. lets look for ric* in pocAPIKeyList
|
||||
try:
|
||||
xID = data['ric'] + "*"
|
||||
# data structure: pocAPIKeyList[xID][i] = (xAPIKey, xPriority, xEventPrefix)
|
||||
for i in range(len(pocAPIKeyList[xID])):
|
||||
xEvent = event
|
||||
(xAPIKey, xPriority, xEventPrefix) = pocAPIKeyList[xID][i]
|
||||
if len(xEventPrefix) > 0:
|
||||
xEvent = xEventPrefix + ": " + xEvent
|
||||
response = nma.pushWithAPIKey(xAPIKey, application, xEvent, msg, priority=xPriority)
|
||||
checkResponse(response, xAPIKey)
|
||||
except KeyError:
|
||||
# nothing found
|
||||
pass
|
||||
# 3. lets look for ric prefixes in pocAPIKeyList
|
||||
for prefixLength in reversed(range(6)):
|
||||
ricPrefix = data['ric'][:prefixLength]
|
||||
#fill the ric with stars
|
||||
ricPrefix = ricPrefix.ljust(8,'*')
|
||||
try:
|
||||
xID = ricPrefix
|
||||
# data structure: pocAPIKeyList[xID][i] = (xAPIKey, xPriority, xEventPrefix)
|
||||
for i in range(len(pocAPIKeyList[xID])):
|
||||
xEvent = event
|
||||
(xAPIKey, xPriority, xEventPrefix) = pocAPIKeyList[xID][i]
|
||||
if len(xEventPrefix) > 0:
|
||||
xEvent = xEventPrefix + ": " + xEvent
|
||||
response = nma.pushWithAPIKey(xAPIKey, application, xEvent, msg, priority=xPriority)
|
||||
checkResponse(response, xAPIKey)
|
||||
except KeyError:
|
||||
# nothing found
|
||||
pass
|
||||
|
||||
# end if "POC" in typ
|
||||
# end if usecsv == True
|
||||
except:
|
||||
logging.error("%s to NMA failed", typ)
|
||||
logging.debug("%s to NMA failed", typ, exc_info=True)
|
||||
return
|
||||
else:
|
||||
logging.warning("Invalid Typ: %s", typ)
|
||||
|
||||
except:
|
||||
# something very mysterious
|
||||
logging.error("unknown error")
|
||||
logging.debug("unknown error", exc_info=True)
|
||||
1
plugins/yowsup/requirements.txt
Normal file
1
plugins/yowsup/requirements.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
yowsup2
|
||||
|
|
@ -1,3 +1,24 @@
|
|||
### Use BOSWatch as service ###
|
||||
|
||||
Old description below
|
||||
|
||||
We assume that BOSWatch is installed to /opt/boswatch! Otherwise you need to adapt all the pathes in this description and in the service-file itself.
|
||||
|
||||
#### Adapt the script
|
||||
Enter the frequency and the decoder(s) you want to use in line 7; you can add more specific switches if you need to
|
||||
|
||||
### Install the service
|
||||
1. Use the install-script install_service.sh as sudo: `sudo bash install_service.sh` (self explaining)
|
||||
|
||||
OR
|
||||
|
||||
1. Copy the file to /etc/systemd/system: sudo cp /opt/boswatch/service/boswatch.service /etc/systemd/system/
|
||||
2. Enable the service: sudo systemctl enable boswatch.service
|
||||
3. Start the service: sudo systemctl start boswatch.service
|
||||
4. Check the status: sudo systemctl status boswatch.service
|
||||
|
||||
---
|
||||
|
||||
### Start BOSWatch as a daemon
|
||||
|
||||
##### Changing the init script
|
||||
|
|
|
|||
11
service/boswatch.service
Normal file
11
service/boswatch.service
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[Unit]
|
||||
Description=BOSWatch
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/python /opt/boswatch/boswatch.py -f 123.45M -a POC512
|
||||
Restart=on-abort
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
### END INIT INFO
|
||||
|
||||
# Change the next 3 lines to suit where you install your script and what you want to call it
|
||||
DIR=/opt/boswatch/BOSWatch
|
||||
DIR=/opt/boswatch
|
||||
DAEMON=$DIR/boswatch.py
|
||||
DAEMON_NAME=boswatch
|
||||
|
||||
|
|
|
|||
52
service/install_service.sh
Normal file
52
service/install_service.sh
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Tiny script to install BOSWatch-service via systemctl
|
||||
# Just a few simple steps are required to (un)register your service
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root!" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
read -p"Do you want to install (i) or remove (r) the service? " action
|
||||
|
||||
if [ "$action" == "i" ]; then
|
||||
|
||||
# 1 Check whether the right data are in the service-file
|
||||
|
||||
read -p"Did you adapt the file boswatch.service (y/n)? " response
|
||||
|
||||
if [ "$response" == "y" ]; then
|
||||
# 2 Copy the file
|
||||
cp boswatch.service /etc/systemd/system
|
||||
|
||||
# 3 Enable the service and check status
|
||||
systemctl enable boswatch.service
|
||||
systemctl is-enabled boswatch.service
|
||||
|
||||
# 4 fire it up
|
||||
systemctl start boswatch.service
|
||||
|
||||
# 5 post the status
|
||||
systemctl status boswatch.service
|
||||
elif [ "$response" == "n" ]; then
|
||||
echo "Please adapt your personal boswatch.service-file"
|
||||
exit 1
|
||||
else
|
||||
echo "Invalid input - please try again"
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$action" == "r" ]; then # we want to remove the service
|
||||
# stop it...
|
||||
systemctl stop boswatch.service
|
||||
|
||||
# disable it
|
||||
systemctl disable boswatch.service
|
||||
|
||||
# and remove it
|
||||
rm /etc/systemd/system/boswatch.service
|
||||
echo "BosWatch service removed"
|
||||
else # error handling
|
||||
echo "Invalid input - please try again"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Reference in a new issue