91 Commits

Author SHA1 Message Date
Marcel Nijenhof
047bb783b7 Versie update
Some checks failed
continuous-integration/drone/push Build is failing
2021-12-29 15:14:53 +01:00
Marcel Nijenhof
281bbfdac4 Correctie setup.cfg voor upload pypi 2021-12-28 22:47:03 +01:00
Marcel Nijenhof
bcd761653f Aanpassing precommit hoek op setup.cfg 2021-12-28 22:27:42 +01:00
Marcel Nijenhof
f521992f58 pyproject.toml & setup.cfg toegevoegd 2021-12-28 22:22:39 +01:00
Marcel Nijenhof
230b929b4c Correctie druine build
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2021-12-08 17:46:24 +01:00
Marcel Nijenhof
a884a5295b BUG Bix:
Some checks failed
continuous-integration/drone/push Build is failing
LmwSip().lasttime("H10") --> LmwSip(host=None).lasttime("H10")

  Dit voorkomt het opzetten van een connectie.
  Dit veroorzaakte ook problemen in de zelftest.
2021-12-08 16:58:00 +01:00
Marcel Nijenhof
3414fde39c SYNTAX Correctie: log --> logging 2021-12-08 16:57:06 +01:00
Marcel Nijenhof
da6a9c3584 Correctie drone pipeline fedora 35
Some checks failed
continuous-integration/drone/push Build is failing
2021-12-01 23:06:45 +01:00
Marcel Nijenhof
73b15f58ca License toegevoegd
Some checks failed
continuous-integration/drone Build is failing
2021-12-01 22:01:05 +01:00
Marcel Nijenhof
f8f374569d Fix issue 12: lmwsip.run geeft stack trace.
All checks were successful
continuous-integration/drone/push Build is passing
- LmwSip object aangemaakt om tijd te bepalen.
 - Nog geen test code geschreven.
   Vergt uitzoeken hoe we door argparse heen kunnen testen.
2021-09-13 18:02:07 +02:00
Marcel Nijenhof
8d4a40389c valueStr added with quality
All checks were successful
continuous-integration/drone/push Build is passing
2021-08-30 21:41:34 +02:00
Marcel Nijenhof
6a732a33c8 New version
All checks were successful
continuous-integration/drone/push Build is passing
2021-08-30 16:29:36 +02:00
Marcel Nijenhof
f87e571e46 Merge branch 'master' of https://git.marceln.org/Werk/lmwsip
Some checks failed
continuous-integration/drone/push Build is failing
2021-08-30 16:26:01 +02:00
Marcel Nijenhof
4f593b008b Close issue 3 2021-08-30 16:21:54 +02:00
Marcel Nijenhof
34fe39371b use of lmwParameter for perion parameter.
Extra parameter xBS1x
2021-08-30 16:20:29 +02:00
Marcel Nijenhof
beadb51698 Fix issue 3 tijd voor 60 seconde parameters 2021-08-30 16:12:16 +02:00
Marcel Nijenhof
a7bc8a51c4 Test voor issue 3 2021-08-30 16:08:35 +02:00
Marcel Nijenhof
2f4f2eef3f Issue 3: Build H1 test 2021-08-30 16:05:25 +02:00
Marcel Nijenhof
d711b51ce5 use --extraindex-url for installation 2021-08-30 16:04:52 +02:00
Marcel Nijenhof
f2b7723210 Run install checck only on master 2021-08-30 16:04:05 +02:00
Marcel Nijenhof
7df03add42 Correctie email adres
All checks were successful
continuous-integration/drone/push Build is passing
2021-08-08 14:25:39 +02:00
Marcel Nijenhof
9bd1d668da Correctie git hook
All checks were successful
continuous-integration/drone/push Build is passing
2021-08-08 13:50:27 +02:00
Marcel Nijenhof
e9a65af74d Update README
Some checks failed
continuous-integration/drone/push Build is failing
2021-08-08 13:46:35 +02:00
Marcel Nijenhof
d7799db8fb Correctie .drone
Some checks failed
continuous-integration/drone/push Build is failing
2021-07-25 17:33:13 +02:00
Marcel Nijenhof
3b22676048 Correctie .drone version --> __version__
Some checks failed
continuous-integration/drone/push Build is failing
2021-07-25 17:25:07 +02:00
Marcel Nijenhof
0b8e763344 Correctie .drone depend --> depends
Some checks failed
continuous-integration/drone/push Build is failing
2021-07-25 17:22:51 +02:00
Marcel Nijenhof
707d4fc13a Correctie .drone.yml
Some checks failed
continuous-integration/drone/push Build is failing
2021-07-25 17:04:13 +02:00
Marcel Nijenhof
f29d49fafa Extra check yamllint .drone.yml 2021-07-25 17:03:51 +02:00
Marcel Nijenhof
3219139041 .drone yaml correctie
Some checks reported errors
continuous-integration/drone/push Build encountered an error
2021-07-25 16:53:10 +02:00
Marcel Nijenhof
62c8b2021e Correctie .drone voor installCheck 2021-07-25 16:49:35 +02:00
Marcel Nijenhof
7091efe006 Correctie: UserWarning: Normalizing '0.1.05' to '0.1.5' 2021-07-25 16:47:13 +02:00
Marcel Nijenhof
2ae37db7a8 Nieuwe versie 2021-07-25 16:37:48 +02:00
Marcel Nijenhof
1556832ab2 Install check toegevoegd 2021-07-25 16:37:25 +02:00
Marcel Nijenhof
0b201743ba test.sip vervangen door io.StringIO file 2021-07-25 15:49:41 +02:00
Marcel Nijenhof
8e85c8ab3a Test voor docker python:3.6 en latest
Some checks failed
continuous-integration/drone/push Build is failing
2021-07-25 10:42:38 +02:00
Marcel Nijenhof
9feac5c8eb Copy fout drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-19 00:04:53 +02:00
Marcel Nijenhof
aa7ae08863 Test voor CentOS8 en Ubuntu 18.04 2021-07-19 00:01:05 +02:00
Marcel Nijenhof
3890abb479 Versie update: test CentOS7 & python 3.6
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-18 15:17:21 +02:00
Marcel Nijenhof
2181afeb2a Correctie test op centos 7 2021-07-18 15:16:11 +02:00
Marcel Nijenhof
69dc25fcba Syntax correctie & keep yamlint happy
Some checks failed
continuous-integration/drone/push Build is failing
2021-07-18 14:38:56 +02:00
Marcel Nijenhof
b5e2dad196 Test nu op f34 en CentOS7 2021-07-18 14:26:53 +02:00
Marcel Nijenhof
fe564e5721 Bug fix: hang/loop in sendrecv
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-25 15:19:57 +01:00
Marcel Nijenhof
2b2aaa7336 Extra commentaar
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-18 14:39:45 +01:00
Marcel Nijenhof
00d9d64f50 Versie nummer in de module 2021-02-16 16:16:42 +01:00
830aebdfa4 Fix voor: #8 Bug timeSerie("WN", "MWAD", xHm0")
Some checks failed
continuous-integration/drone/push Build is failing
- Tabel met lmw parameters opgenomen.
 - Period functie aangemaakt
 - Aanpassingen timeSerie en _roundtime_
 - Aanpassingen testen D10 --> H10 (D10 bestaat niet in lmw parameter tabel)
2020-12-04 11:25:23 +01:00
Marcel Nijenhof
08af855c45 Correctie issue 6 & 7
All checks were successful
continuous-integration/drone/push Build is passing
2020-11-08 14:23:38 +01:00
Marcel Nijenhof
23f9723d27 Test met cleartelnet 2020-11-08 14:00:21 +01:00
Marcel Nijenhof
3001b434a6 Aanpassingen reconnectcheck
- reconnectcheck naar sendrecv
 - idleconnect check
 - test voor idleconnect
2020-11-08 13:49:12 +01:00
Marcel Nijenhof
17301b70b3 reconnect test 2020-11-08 13:12:53 +01:00
Marcel Nijenhof
57f6619c80 Reconnect on socket failure 2020-11-08 12:32:37 +01:00
Marcel Nijenhof
5968b6ff5b Exception response in recv na close 2020-11-07 13:47:54 +01:00
Marcel Nijenhof
ad1fed8340 Extra close commando om timeouts te simuleren 2020-11-07 13:47:16 +01:00
Marcel Nijenhof
42133b80bd Logger in debug mode tijdens testen 2020-11-07 13:12:38 +01:00
Marcel Nijenhof
13fea782d7 Close socket na login failure 2020-11-07 12:27:28 +01:00
Marcel Nijenhof
bf1996931e BUG Fix: reconnect time > 0 toegevoegd
All checks were successful
continuous-integration/drone/push Build is passing
2020-10-16 08:50:38 +02:00
eccd9011a3 Correctie een regel te veel verwijderd in reconnect
Some checks failed
continuous-integration/drone/push Build is failing
2020-10-15 19:25:07 +02:00
872f77037b Vereenvoudiging reconnect mechanisme
Some checks failed
continuous-integration/drone/push Build is failing
2020-10-15 19:21:39 +02:00
Marcel Nijenhof
4422dd4fe5 Versie verhoogt naar 0.0.7 naar verbeteringen
All checks were successful
continuous-integration/drone/push Build is passing
2020-10-03 17:08:44 +02:00
Marcel Nijenhof
0d44e053cf Fix test voor extra argument git run 2020-10-03 17:08:09 +02:00
Marcel Nijenhof
5b296a1da7 Vlag voor accepteren certificaat 2020-10-03 17:03:01 +02:00
Marcel Nijenhof
81511300bf Extra test login fout 2020-10-03 15:27:19 +02:00
Marcel Nijenhof
6dd1d36add Fix argument raise LmwLoginFailure 2020-10-03 14:49:40 +02:00
Marcel Nijenhof
640c058d98 Versie verhoogd
All checks were successful
continuous-integration/drone/push Build is passing
2020-10-01 16:32:03 +02:00
Marcel Nijenhof
a8583d3eec Merge branch 'master' of https://git.marceln.org/Werk/lmwsip
Some checks failed
continuous-integration/drone/push Build is failing
2020-10-01 16:28:41 +02:00
Marcel Nijenhof
6c7a505775 Type: waring --> warning 2020-10-01 16:28:32 +02:00
Marcel Nijenhof
3d66a31792 Versie verhoogd
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-16 23:15:21 +02:00
Marcel Nijenhof
b79438209b Extra test voor value toegevoegd 2020-09-16 23:14:57 +02:00
Marcel Nijenhof
5b45b077f6 Afhankelijkheid dateutil toegevoegd aan setup 2020-09-16 23:14:31 +02:00
Marcel Nijenhof
5f4b5d7d7d drone: Correctie
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 17:25:20 +02:00
Marcel Nijenhof
6e3a21c6c4 test: Correctie import
Some checks failed
continuous-integration/drone/push Build is failing
2020-09-08 17:22:56 +02:00
Marcel Nijenhof
2281ef9427 Cleanup & correctie tests
Some checks failed
continuous-integration/drone/push Build is failing
2020-09-08 17:19:47 +02:00
Marcel Nijenhof
1bfa73a0f7 Update versie na correctie test folder
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 16:53:10 +02:00
Marcel Nijenhof
04667dc28c Correctie locatie tests directory
Some checks failed
continuous-integration/drone/push Build is failing
2020-09-08 16:52:28 +02:00
Marcel Nijenhof
dea73c249f Correctie lokatie test sip file na hernoemen
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 16:41:27 +02:00
Marcel Nijenhof
62456fd35b Type: test --> tests
Some checks failed
continuous-integration/drone/push Build is failing
2020-09-08 16:40:04 +02:00
Marcel Nijenhof
7ba9e27e14 Drone: ls -l van packagedir na file copy
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 15:13:53 +02:00
Marcel Nijenhof
dd47094b75 Correctie naam package in setup
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 15:12:39 +02:00
Marcel Nijenhof
da5da044ef Drone: correctie pipeline
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 15:08:46 +02:00
Marcel Nijenhof
8159dc83da Drone: correctie pipeline
Some checks failed
continuous-integration/drone/push Build is failing
2020-09-08 15:06:01 +02:00
Marcel Nijenhof
6900b9fc57 Drone: correctie pipeline 2020-09-08 15:05:33 +02:00
Marcel Nijenhof
7aa6ffc3d4 Drone: Correctie
Some checks failed
continuous-integration/drone/push Build is failing
2020-09-08 15:00:55 +02:00
Marcel Nijenhof
03503da5a4 Drone step toegevoegd voor klaar zetten in download
Some checks failed
continuous-integration/drone/push Build is failing
2020-09-08 14:59:39 +02:00
Marcel Nijenhof
80b8ebe4ff Test sip file toegevoegd
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 14:44:07 +02:00
Marcel Nijenhof
7e6751f60d Aanpassing drone pipeline test stap
Some checks failed
continuous-integration/drone/push Build is failing
2020-09-08 14:41:06 +02:00
Marcel Nijenhof
76407e2a86 Extra test voor lmwsip.run.run()
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 14:36:07 +02:00
Marcel Nijenhof
6885b03d40 Extra test voor lmwsip.run.run() 2020-09-08 14:35:40 +02:00
Marcel Nijenhof
3a07310e86 lmwsip.run close van socket 2020-09-08 14:35:14 +02:00
Marcel Nijenhof
8acaf98e4b logging warn --> warning 2020-09-08 14:34:36 +02:00
Marcel Nijenhof
a2b8a52d47 Logging toegevoegd 2020-09-08 13:39:32 +02:00
Marcel Nijenhof
df36ae495c Aanpassing siprun naar lmwsip.run module
All checks were successful
continuous-integration/drone/push Build is passing
- Splitsing losse run functie
 - Aanpassing documentatie
2020-09-08 13:11:15 +02:00
Marcel Nijenhof
827807be73 Build package toegevoegd aan pipeline
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-04 22:56:19 +02:00
13 changed files with 1103 additions and 211 deletions

View File

@@ -1,13 +1,166 @@
--- ---
kind: pipeline kind: pipeline
type: exec type: exec
name: default name: CentOS7_test
platform: platform:
os: linux os: linux
arch: amd64 arch: amd64
variant: CentOS7
steps: steps:
- name: Run unit test - name: Run unit test
commands: environment:
- python -m unittest lmwsip PYTHONPATH: .
commands:
- python3 setup.py test
---
kind: pipeline
type: exec
name: CentOS8_test
platform:
os: linux
arch: amd64
variant: CentOS8
steps:
- name: Run unit test
environment:
PYTHONPATH: .
commands:
- python3 setup.py test
---
kind: pipeline
type: exec
name: Ubuntu1804_test
platform:
os: linux
arch: amd64
variant: Ubuntu1804
steps:
- name: Run unit test
environment:
PYTHONPATH: .
commands:
- python3 setup.py test
---
kind: pipeline
type: exec
name: Fedora_test
platform:
os: linux
arch: amd64
variant: Fedora
steps:
- name: Run unit test
environment:
PYTHONPATH: .
commands:
- python3 setup.py test
---
kind: pipeline
type: docker
name: docker_python:3.6
steps:
- name: Run unit test
image: python:3.6
environment:
PYTHONPATH: .
commands:
- pip install python-dateutil
- python setup.py test
---
kind: pipeline
type: docker
name: docker_python:latest
steps:
- name: Run unit test
image: python:latest
environment:
PYTHONPATH: .
commands:
- pip install python-dateutil
- python --version
- python setup.py test
---
kind: pipeline
type: exec
name: Build
platform:
os: linux
arch: amd64
variant: Fedora
steps:
- name: Build package files
commands:
- python3 setup.py sdist bdist_wheel
- name: Versie toevoegen aan download
environment:
DOWNLOADDIR: /usr/share/nginx/html/download/python/lmwsip
commands:
- mkdir -p "$${DOWNLOADDIR}"
- cd dist
- |
for f in *
do
if [ -f "$${DOWNLOADDIR}/$${f}" ]
then
echo version error
exit 1
else
cp "$${f}" "$${DOWNLOADDIR}";
fi
done
- ls -l "$${DOWNLOADDIR}"
when:
branch:
- master
depends_on:
- CentOS7_test
- CentOS8_test
- Ubuntu1804_test
- Fedora_test
- docker_python:latest
- docker_python:3.6
---
kind: pipeline
type: docker
name: installCheck
steps:
- name: install Check
image: python:3.6
# Make sure we run the pip installed version
commands:
- rm -rf lmwsip
- pip install --extra-index-url https://marceln.org/download/python lmwsip
- python -c "import lmwsip"
- python -c "import lmwsip; print(lmwsip.__version__)"
- >
[ $(python -c "import lmwsip; print(lmwsip.__version__)") =
$(python setup.py --version) ]
- python -m unittest -v lmwsip.tests
when:
branch:
- master
depends_on:
- Build

3
.gitignore vendored
View File

@@ -1,8 +1,9 @@
*.pyc *.pyc
*.sip
tmp tmp
__pycache__ __pycache__
build build
dist dist
lmwsip_marceln.egg-info lmwsip_marceln.egg-info
test/__pycache__ test/__pycache__
lmwsip.egg-info
*.swp

21
LICENSE
View File

@@ -1 +1,20 @@
TODO Copyright (c) 2021 Rijkswaterstaat
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.

View File

@@ -3,38 +3,32 @@
lmwsip is a python library for the lmw sip protocol. lmwsip is a python library for the lmw sip protocol.
## Library ## Package
The lmwsip.py library contains the class LmwSip to connect to the The lmwsip package contains the class LmwSip to connect to the
LMW meetnet using de SIP protocol. The library contains documentation [LMW](https://waterberichtgeving.rws.nl/water-en-weer/metingen/lmw-info)
meetnet using de SIP protocol. The library contains documentation
how to use it. how to use it.
## Tools ## Installing
### lmwsip-test
A small test program containing some functions to test the library. The package is not available on [PyPI](https://pypi.org/).
At the moment the package is hosted at https://marceln.org/download/python.
### siprun You can install the package with pip:
```
A prgram to run SIP command files. pip install --extra-index-url https://marceln.org/download/python lmwsip
See "siprun -H" for usage information. ```
#### hoek-h10.sip
A sample sip command file to request the waterlevel at hoek van holland
from the last hour
## Username password
All files contain "USER", "PASS".
These values should be replaced by real credentials.
Otherwise the connection fails.
## Examples ## Examples
### Library ### Username password
#### Use send (low level) All examples contain "USER", "PASS".
These values should be replaced by real credentials.
Otherwise the connection fails.
### Use send (low level)
``` python ``` python
from lmwsip import LmwSip from lmwsip import LmwSip
@@ -71,16 +65,29 @@ sip = LmwSip("USER", "PASS")
pprint(sip.timeSerie("WN", "HOEK", "H10", start, end).ts) pprint(sip.timeSerie("WN", "HOEK", "H10", start, end).ts)
``` ```
### siprun ### lmwsip.run
``` ```
$ ./siprun -h sip-lmw.ad.rws.nl -s -p 443 hoek-h10.sip $ python -m lmwsip.run /tmp/hoek-h10.sip
> [LI USER,PASS] > [LI USER,PASS]
< [! ] < [! ]
> [TI LMW] > [TI LMW]
< [! 05-SEP-19 08:24:43] < [! 08-SEP-20 12:03:27]
> [WN LMW,HOEK,H10,-25:00,05-09-2019,08:10,DATA] > [WN LMW,HOEK,H10,-01:00,08-09-2020,11:50,DATA]
< [? 0211 Waarnemingen vallen buiten opslag range] < [! -17/50;-21/50;-24/50;-26/50;-27/50;-28/50;-28/50]
> [LO] > [LO]
< [! ] < [! ]
``` ```
## Unit tests
The code containts a python unittest.
This code runs a dummy sip server and runs a number of test against the dummy
server.
## Git pre commit hook
There is a pre-commit `githooks/pre-commit' with two functions:
* Updating the `__version__` in the module from setup.py
* Running the unit test code.
* Running a syntaxt test.

10
githooks/pre-commit Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/sh
set -e
VERSION=$(grep version setup.cfg | sed 's/.*= *//')
sed -i "s/^__version__ = .*/__version__ = '${VERSION}'/" lmwsip/__init__.py
git add lmwsip/__init__.py
python setup.py test
yamllint .drone.yml

View File

@@ -11,6 +11,9 @@ import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta
from dateutil import tz from dateutil import tz
""" Version info changed by git hook """
__version__ = '0.9.1'
class LmwSip: class LmwSip:
"""Class to connect to the LMW Standard Interface prototcol (sip) """Class to connect to the LMW Standard Interface prototcol (sip)
@@ -25,11 +28,474 @@ Support for:
cmd(wn, vw, as) cmd(wn, vw, as)
""" """
lmwParameters = {
'Tm02_MV': ('VW', 1, 0),
'xH1': ('WN', 1, 1),
'HH1S': ('WN', 1, 1),
'SRV1': ('WN', 1, 1),
'TL1': ('WN', 1, 1),
'SRV1w1': ('WN', 1, 1),
'SRV1w2': ('WN', 1, 1),
'SRV1w3': ('WN', 1, 1),
'xTL1': ('WN', 1, 1),
'DO1': ('WN', 1, 1),
'SSV1': ('WN', 1, 1),
'SSV1w3G': ('WN', 1, 1),
'SSV1w3': ('WN', 1, 1),
'SSV1w2G': ('WN', 1, 1),
'SSV1w2': ('WN', 1, 1),
'SSV1w1G': ('WN', 1, 1),
'H1Z': ('WN', 1, 1),
'SSV1w1': ('WN', 1, 1),
'H1': ('WN', 1, 1),
'bSSVG1': ('WN', 1, 1),
'xWS1': ('WN', 1, 1),
'HG1Z': ('WN', 1, 1),
'WS1': ('WN', 1, 1),
'HG1': ('WN', 1, 1),
'WR1': ('WN', 1, 1),
'ZA1': ('WN', 1, 1),
'ZM1': ('WN', 1, 1),
'H1RC': ('WN', 1, 1),
'bSRV1': ('WN', 1, 1),
'bSSV1': ('WN', 1, 1),
'xWR1': ('WN', 1, 1),
'THmax': ('WN', 1, 10),
'Th0_B4': ('WN', 1, 10),
'Th0': ('WN', 1, 10),
'Th0_G1': ('WN', 1, 10),
'Th0_B3': ('WN', 1, 10),
'Th0_G10': ('WN', 1, 10),
'Th010': ('WN', 51, 10),
'Th0_G7': ('WN', 1, 10),
'Th0_B0': ('WN', 1, 10),
'Th0_G6': ('WN', 1, 10),
'Th0_G2': ('WN', 1, 10),
'Th0_G3': ('WN', 1, 10),
'Th0_B2': ('WN', 1, 10),
'Th0_B1': ('WN', 1, 10),
'Th0_G5': ('WN', 1, 10),
'Th0_G4': ('WN', 1, 10),
'Th0_G8': ('WN', 1, 10),
'Th0_G9': ('WN', 1, 10),
'TW10S': ('WN', 1, 10),
'U10': ('WN', 1, 10),
'UUR10': ('WN', 1, 10),
'Th3V': ('VW', 1, 10),
'V10': ('WN', 1, 10),
'V10S': ('WN', 1, 10),
'WC10': ('WN', 1, 10),
'WC10MXS3': ('WN', 1, 10),
'WC10V': ('VW', 1, 10),
'TW10': ('WN', 1, 10),
'Tm_10_M': ('WN', 1, 10),
'Tmax': ('WN', 1, 10),
'Th3': ('WN', 1, 10),
'Tm_10': ('WN', 1, 10),
'TL10': ('WN', 1, 10),
'TL10MNM1': ('WN', 1, 10),
'TL10MXM1': ('WN', 1, 10),
'Tm02': ('WN', 1, 10),
'Tm02V': ('VW', 1, 10),
'Tm02V_M': ('VW', 1, 10),
'Tm02_M': ('WN', 1, 10),
'WDG10': ('WN', 1, 10),
'TH1d3': ('WN', 1, 10),
'S0bh_G10': ('WN', 1, 10),
'SPGH': ('WN', 1, 10),
'SPGT': ('WN', 1, 10),
'SRV10': ('WN', 1, 10),
'SRV10m': ('WN', 50, 10),
'SRV10STD': ('WN', 1, 10),
'SRV10V': ('VW', 1, 10),
'SRV10w1': ('WN', 1, 10),
'SRV10w2': ('WN', 1, 10),
'SRV10w3': ('WN', 1, 10),
'SS10': ('WN', 1, 10),
'SH10': ('WN', 1, 10),
'SG10': ('WN', 1, 10),
'SEC10': ('WN', 1, 10),
'S0bh_G2': ('WN', 1, 10),
'S0bh_G3': ('WN', 1, 10),
'S0bh_G4': ('WN', 1, 10),
'S0bh_G5': ('WN', 1, 10),
'S0bh_G6': ('WN', 1, 10),
'S0bh_G7': ('WN', 1, 10),
'S0bh_G8': ('WN', 1, 10),
'S0bh_G9': ('WN', 1, 10),
'SAL10': ('WN', 1, 10),
'SD10': ('WN', 1, 10),
'SSG10': ('WN', 1, 10),
'SSV10': ('WN', 1, 10),
'SSV10A': ('AS', 1, 10),
'T10': ('WN', 1, 10),
'T1d3': ('WN', 1, 10),
'T1d3V': ('VW', 1, 10),
'TD10': ('WN', 1, 10),
'TD10M1': ('WN', 1, 10),
'TE0': ('WN', 1, 10),
'TE1': ('WN', 1, 10),
'TE1_M': ('WN', 1, 10),
'TE2': ('WN', 1, 10),
'TE3': ('WN', 1, 10),
'Stat10Sm': ('WN', 50, 10),
'Stat10S': ('WN', 1, 10),
'ST10': ('WN', 1, 10),
'SSV10m': ('WN', 50, 10),
'SSV10V': ('VW', 1, 10),
'SSV10w1': ('WN', 1, 10),
'SSV10w1G': ('WN', 1, 10),
'SSV10w2': ('WN', 1, 10),
'SSV10w2G': ('WN', 1, 10),
'SSV10w3': ('WN', 1, 10),
'SSV10w3G': ('WN', 1, 10),
'SSVG10': ('WN', 1, 10),
'SSVG10V': ('VW', 1, 10),
'TE3V': ('VW', 1, 10),
'xP10': ('WN', 1, 10),
'xSS10': ('WN', 1, 10),
'xSSV10': ('WN', 1, 10),
'xT1d3': ('WN', 1, 10),
'xTD10': ('WN', 1, 10),
'xTD10M1': ('WN', 1, 10),
'xTE1': ('WN', 1, 10),
'xTE2': ('WN', 1, 10),
'xTE3': ('WN', 1, 10),
'xTH1d3': ('WN', 1, 10),
'xTHmax': ('WN', 1, 10),
'xTh0': ('WN', 1, 10),
'xSRV10': ('WN', 1, 10),
'xSPGT': ('WN', 1, 10),
'xSPGH': ('WN', 1, 10),
'xPC10': ('WN', 1, 10),
'xPH': ('WN', 1, 10),
'xPH10': ('WN', 1, 10),
'xPQFE10': ('WN', 1, 10),
'xPQFF10': ('WN', 1, 10),
'xPQNH10': ('WN', 1, 10),
'xQ10': ('WN', 1, 10),
'xQ10B': ('VW', 1, 10),
'xR10': ('WN', 1, 10),
'xRS10': ('WN', 1, 10),
'xSH10P': ('WN', 1, 10),
'xTh3': ('WN', 1, 10),
'xTL10': ('WN', 1, 10),
'xWR10': ('WN', 1, 10),
'xWR10STD': ('WN', 1, 10),
'xWS10': ('WN', 1, 10),
'xWS10MX': ('WN', 1, 10),
'xWS10MXS': ('WN', 1, 10),
'xWS10STD': ('WN', 1, 10),
'xWS10XS1': ('WN', 1, 10),
'xZM10': ('WN', 1, 10),
'ZA10': ('WN', 1, 10),
'ZM10': ('WN', 1, 10),
'ZMT10': ('WN', 1, 10),
'xWC10MXS': ('WN', 1, 10),
'xWC10': ('WN', 1, 10),
'xVE10s': ('WN', 1, 10),
'xTL10MNM': ('WN', 1, 10),
'xTL10MXM': ('WN', 1, 10),
'xTm02': ('WN', 1, 10),
'xTmax': ('WN', 1, 10),
'xTm_10': ('WN', 1, 10),
'xTT10P': ('WN', 1, 10),
'xTW10': ('WN', 1, 10),
'xU10': ('WN', 1, 10),
'xV10': ('WN', 1, 10),
'xVE10': ('WN', 1, 10),
'xVE10S': ('WN', 1, 10),
'ZV10S': ('WN', 1, 10),
'WI': ('BL', 8, 10),
'xBS10S': ('WN', 1, 10),
'xBS1S': ('WN', 1, 1),
'xBS10s': ('WN', 1, 10),
'xC10P': ('WN', 1, 10),
'xCHL10': ('WN', 1, 10),
'xCL10': ('WN', 1, 10),
'xCzz10': ('WN', 51, 10),
'xCzz5': ('WN', 25, 10),
'xD10': ('WN', 1, 10),
'xDO10': ('WN', 1, 10),
'xDO10P': ('WN', 1, 10),
'xFp': ('WN', 1, 10),
'xBM10s': ('WN', 1, 10),
'xBM10S': ('WN', 1, 10),
'xAV10_H': ('WN', 1, 10),
'WNR10': ('WN', 1, 10),
'WR10': ('WN', 1, 10),
'WR10STD': ('WN', 1, 10),
'WR10V': ('VW', 1, 10),
'WS10': ('WN', 1, 10),
'WS10MX10': ('WN', 1, 10),
'WS10MXS3': ('WN', 1, 10),
'WS10STD': ('WN', 1, 10),
'WS10V': ('VW', 1, 10),
'xAG': ('WN', 1, 10),
'xANT10': ('WN', 1, 10),
'xGE10': ('WN', 1, 10),
'xGGH': ('WN', 1, 10),
'xHS7': ('WN', 1, 10),
'xHTE3': ('WN', 1, 10),
'xKH10B': ('VW', 1, 10),
'xM0': ('WN', 1, 10),
'xNdlr_H': ('WN', 1, 10),
'xNd_z': ('WN', 1, 10),
'xNgd_zP': ('WN', 1, 10),
'xNI10': ('WN', 1, 10),
'xNi_z': ('WN', 1, 10),
'xNu_z': ('WN', 1, 10),
'xNv_z': ('WN', 1, 10),
'xHmax': ('WN', 1, 10),
'xHm0': ('WN', 1, 10),
'xHHR10': ('WN', 1, 10),
'xGGT': ('WN', 1, 10),
'xH10': ('WN', 1, 10),
'xH10BV': ('VW', 1, 10),
'xH10R': ('WN', 1, 10),
'xH10Z': ('WN', 1, 10),
'xH1d10': ('WN', 1, 10),
'xH1d3': ('WN', 1, 10),
'xH1d50': ('WN', 1, 10),
'xHCM': ('WN', 1, 10),
'xHH10': ('WN', 1, 10),
'xHH10R': ('WN', 1, 10),
'xNwt_zP': ('WN', 1, 10),
'G1_B0': ('WN', 1, 10),
'G2_B0': ('WN', 1, 10),
'G2_B1': ('WN', 1, 10),
'G2_B2': ('WN', 1, 10),
'G2_B3': ('WN', 1, 10),
'G2_B4': ('WN', 1, 10),
'G2_G1': ('WN', 1, 10),
'G2_G10': ('WN', 1, 10),
'G2_G2': ('WN', 1, 10),
'G2_G3': ('WN', 1, 10),
'G2_G4': ('WN', 1, 10),
'G2_G5': ('WN', 1, 10),
'G1_G9': ('WN', 1, 10),
'G1_G8': ('WN', 1, 10),
'G1_G7': ('WN', 1, 10),
'G1_B1': ('WN', 1, 10),
'G1_B2': ('WN', 1, 10),
'G1_B3': ('WN', 1, 10),
'G1_B4': ('WN', 1, 10),
'G1_G1': ('WN', 1, 10),
'G1_G10': ('WN', 1, 10),
'G1_G2': ('WN', 1, 10),
'G1_G3': ('WN', 1, 10),
'G1_G4': ('WN', 1, 10),
'G1_G5': ('WN', 1, 10),
'G1_G6': ('WN', 1, 10),
'G2_G6': ('WN', 1, 10),
'G2_G7': ('WN', 1, 10),
'G2_G8': ('WN', 1, 10),
'GK': ('BL', 11, 10),
'GKZ': ('BL', 11, 10),
'GO': ('BL', 70, 10),
'GO_H': ('BL', 35, 10),
'GO_L': ('BL', 35, 10),
'GR': ('BL', 107, 10),
'GRZ': ('BL', 107, 10),
'GW': ('BL', 6, 10),
'H10': ('WN', 1, 10),
'H10A': ('AS', 1, 10),
'H10RC': ('WN', 1, 10),
'GH_M': ('BL', 27, 10),
'GHZ': ('BL', 128, 10),
'GHRZ': ('BL', 78, 10),
'G2_G9': ('WN', 1, 10),
'GB': ('BL', 35, 10),
'GE10': ('WN', 1, 10),
'GE10S': ('WN', 1, 10),
'GGH': ('WN', 1, 10),
'GGT': ('WN', 1, 10),
'GH': ('BL', 27, 10),
'GH2': ('BL', 27, 10),
'GHC': ('BL', 76, 10),
'GHC_M': ('BL', 126, 10),
'GHR': ('BL', 128, 10),
'H10V': ('VW', 1, 10),
'AB': ('BL', 256, 10),
'bSSV10': ('WN', 1, 10),
'bSSVG10': ('WN', 1, 10),
'C10P': ('WN', 1, 10),
'C110S': ('WN', 1, 10),
'C210S': ('WN', 1, 10),
'C310S': ('WN', 1, 10),
'CHL10': ('WN', 1, 10),
'CL10': ('WN', 1, 10),
'Cor10': ('WN', 1, 10),
'Cor10m': ('WN', 50, 10),
'CX10S': ('WN', 1, 10),
'bSRV10': ('WN', 1, 10),
'bQ10': ('WN', 1, 10),
'bH10': ('WN', 1, 10),
'AG': ('WN', 1, 10),
'AL': ('BL', 35, 10),
'AV10_H': ('WN', 1, 10),
'AV10_R': ('WN', 1, 10),
'BCor10': ('WN', 1, 10),
'BEcho10': ('WN', 1, 10),
'BH10': ('WN', 1, 10),
'BNgd10P': ('WN', 1, 10),
'BSRV10': ('WN', 1, 10),
'BSSV10': ('WN', 1, 10),
'BT10': ('WN', 1, 10),
'Czz10': ('WN', 51, 10),
'Czz10_M': ('WN', 101, 10),
'Czz5': ('WN', 25, 10),
'Fm01_G1': ('WN', 1, 10),
'Fm01_G10': ('WN', 1, 10),
'Fm01_G2': ('WN', 1, 10),
'Fm01_G3': ('WN', 1, 10),
'Fm01_G4': ('WN', 1, 10),
'Fm01_G5': ('WN', 1, 10),
'Fm01_G6': ('WN', 1, 10),
'Fm01_G7': ('WN', 1, 10),
'Fm01_G8': ('WN', 1, 10),
'Fm01_G9': ('WN', 1, 10),
'Fp': ('WN', 1, 10),
'Fm01_B4': ('WN', 1, 10),
'Fm01_B3': ('WN', 1, 10),
'Fm01_B2': ('WN', 1, 10),
'D10': ('WN', 1, 10),
'D10S': ('WN', 1, 10),
'DH10': ('WN', 1, 10),
'DL_index': ('WN', 1, 10),
'DO10': ('WN', 1, 10),
'DO10P': ('WN', 1, 10),
'DT10': ('WN', 1, 10),
'Echo10': ('WN', 1, 10),
'Echo10m': ('WN', 50, 10),
'Fm01_B0': ('WN', 1, 10),
'Fm01_B1': ('WN', 1, 10),
'Fp_M': ('WN', 1, 10),
'H10Z': ('WN', 1, 10),
'ND10': ('WN', 1, 10),
'Ndlr_H': ('WN', 1, 10),
'Ndlr_R': ('WN', 1, 10),
'Nd_x': ('WN', 1, 10),
'Nd_y': ('WN', 1, 10),
'Nd_z': ('WN', 1, 10),
'Ngd10P': ('WN', 1, 10),
'Ngd10Pm': ('WN', 50, 10),
'Ngd_xP': ('WN', 1, 10),
'Ngd_yP': ('WN', 1, 10),
'Ngd_zP': ('WN', 1, 10),
'NI10': ('WN', 1, 10),
'Ni_x': ('WN', 1, 10),
'Ndfe_G9': ('WN', 1, 10),
'Ndfe_G8': ('WN', 1, 10),
'Ndfe_G7': ('WN', 1, 10),
'Ndfe_B0': ('WN', 1, 10),
'Ndfe_B1': ('WN', 1, 10),
'Ndfe_B2': ('WN', 1, 10),
'Ndfe_B3': ('WN', 1, 10),
'Ndfe_B4': ('WN', 1, 10),
'Ndfe_G1': ('WN', 1, 10),
'Ndfe_G10': ('WN', 1, 10),
'Ndfe_G2': ('WN', 1, 10),
'Ndfe_G3': ('WN', 1, 10),
'Ndfe_G4': ('WN', 1, 10),
'Ndfe_G5': ('WN', 1, 10),
'Ndfe_G6': ('WN', 1, 10),
'Ni_y': ('WN', 1, 10),
'Ni_z': ('WN', 1, 10),
'PQFF10': ('WN', 1, 10),
'PQNH10': ('WN', 1, 10),
'PW10': ('WN', 1, 10),
'Q10': ('WN', 1, 10),
'Q10V': ('VW', 1, 10),
'S0bh': ('WN', 1, 10),
'S0bh10': ('WN', 51, 10),
'S0bh_B0': ('WN', 1, 10),
'S0bh_B1': ('WN', 1, 10),
'S0bh_B2': ('WN', 1, 10),
'S0bh_B3': ('WN', 1, 10),
'S0bh_B4': ('WN', 1, 10),
'PQFE10': ('WN', 1, 10),
'PH': ('WN', 1, 10),
'PC10': ('WN', 1, 10),
'NtrackS': ('WN', 1, 10),
'Nu_x': ('WN', 1, 10),
'Nu_y': ('WN', 1, 10),
'Nu_z': ('WN', 1, 10),
'Nv_x': ('WN', 1, 10),
'Nv_y': ('WN', 1, 10),
'Nv_z': ('WN', 1, 10),
'Nwt_zP': ('WN', 1, 10),
'NzoekS': ('WN', 1, 10),
'OL10S': ('WN', 1, 10),
'OT10': ('WN', 1, 10),
'P10': ('WN', 1, 10),
'S0bh_G1': ('WN', 1, 10),
'H10ZV': ('VW', 1, 10),
'Hm0_B2': ('WN', 1, 10),
'Hm0_B3': ('WN', 1, 10),
'Hm0_B4': ('WN', 1, 10),
'Hm0_G1': ('WN', 1, 10),
'Hm0_G10': ('WN', 1, 10),
'Hm0_G2': ('WN', 1, 10),
'Hm0_G4': ('WN', 1, 10),
'Hm0_G5': ('WN', 1, 10),
'Hm0_G6': ('WN', 1, 10),
'Hm0_G7': ('WN', 1, 10),
'Hm0_G8': ('WN', 1, 10),
'Hm0_G9': ('WN', 1, 10),
'Hm0_B1': ('WN', 1, 10),
'Hm0_B0': ('WN', 1, 10),
'Hm0V': ('VW', 1, 10),
'H1d10': ('WN', 1, 10),
'H1d3': ('WN', 1, 10),
'H1d3V': ('VW', 1, 10),
'H1d50': ('WN', 1, 10),
'Hb10': ('WN', 1, 10),
'HCM': ('WN', 1, 10),
'HG10': ('WN', 1, 10),
'HG10Z': ('WN', 1, 10),
'HH10': ('WN', 1, 10),
'HH10S': ('WN', 1, 10),
'HMR': ('BL', 159, 10),
'Hm0': ('WN', 1, 10),
'Hm0_M': ('WN', 1, 10),
'Hmax': ('WN', 1, 10),
'HS7': ('WN', 1, 10),
'LG10': ('WN', 48, 10),
'LGK10V': ('VW', 1, 10),
'LGNf_z': ('WN', 1, 10),
'LGNik_z': ('WN', 1, 10),
'LGNvd_z': ('WN', 1, 10),
'LGNv_z': ('WN', 1, 10),
'M0': ('WN', 1, 10),
'M0_M': ('WN', 1, 10),
'MDG10': ('WN', 1, 10),
'MIN10': ('WN', 1, 10),
'MNR10': ('WN', 1, 10),
'L10': ('WN', 1, 10),
'KT10P': ('WN', 1, 10),
'HTE3': ('WN', 1, 10),
'Hm0_G3': ('WN', 1, 10),
'NB10S': ('WN', 1, 10),
'HTE3V': ('VW', 1, 10),
'I10': ('WN', 1, 10),
'JNR10': ('WN', 1, 10),
'IL10P': ('WN', 1, 10),
'JDG10': ('WN', 1, 10),
'xQ30': ('WN', 1, 30),
'xNI30': ('WN', 1, 30),
'xH30': ('WN', 1, 30),
'xH30R': ('WN', 1, 30),
'xH60': ('WN', 1, 60),
'xNI60': ('WN', 1, 60),
'xQ60': ('WN', 1, 60),
'xH60R': ('WN', 1, 60)
}
def __init__(self, user=None, password=None, def __init__(self, user=None, password=None,
host="sip-lmw.rws.nl", port=443, meetnet="LMW", ssl = True, host="sip-lmw.rws.nl", port=443, meetnet="LMW", ssl = True,
check_ssl = True, timeout = 10, log = None, cleartelnet = False, check_ssl = True, timeout = 10, log = None, cleartelnet = False,
reconnecttime=540): reconnecttime=540, idlereconnect=45):
"""LmwSip(user, password, [host], [port], [meetnet], [ssl], [check_ssl], [timeout], [log]) """LmwSip(user, password, [host], [port], [meetnet], [ssl], [check_ssl], [timeout], [log])
user(optinal): Lmw user name user(optinal): Lmw user name
@@ -55,25 +521,36 @@ Opens the connection and logs in.
self.check_ssl = check_ssl self.check_ssl = check_ssl
self.timeout = timeout self.timeout = timeout
self.cleartelnet = cleartelnet self.cleartelnet = cleartelnet
self.reconnecttime = reconnecttime self.reconnecttime = 0
self._connecttime = time.time() self.idlereconnect = 0
self._connecttime = time.time()
self._idletime = time.time()
self._socket = None self._socket = None
if (log != None): if (log != None):
self.log = log self.log = log
self.log.debug("LmwSip.init(%s, **********, %s, %s, %s, %s, %s, %s, %s, %s)" %
(user, host, port, meetnet, ssl, check_ssl, timeout, cleartelnet, reconnecttime))
else: else:
try: try:
self.log = logging.getLogger("lmwsip") self.log = logging.getLogger("lmwsip")
self.log.debug("LmwSip.init: Start log") self.log.debug("LmwSip.init: Start log")
except Exception as e: except Exception as e:
print("Logger failed: %s" % e) print("Logger failed: %s" % e)
self.log.debug("LmwSip.init(%s, **********, %s, %s, %s, %s, %s, %s, %s, %s, %s)" %
(user, host, port, meetnet, ssl, check_ssl, timeout,
cleartelnet, reconnecttime, idlereconnect))
if (self.host != None): if (self.host != None):
self.connect() self.connect()
if (self.user != None): if (self.user != None):
self.login() self.login()
else: self.reconnecttime = reconnecttime
self.reconnecttime = 0 self.idlereconnect = idlereconnect
def period(self, parameter):
if parameter in self.lmwParameters:
return(self.lmwParameters[parameter][2])
else:
raise LmwParmWarn(parameter)
return(None)
def lasttime(self, parameter): def lasttime(self, parameter):
# #
@@ -86,22 +563,26 @@ Opens the connection and logs in.
# Also note that we use GMT. So we should add one hour # Also note that we use GMT. So we should add one hour
# because we use GMT +1 (MET, UTC-1) # because we use GMT +1 (MET, UTC-1)
# #
if (parameter.find("10") != -1): now=time.time()
now=time.time() period = self.period(parameter)
if (period == 10):
dt = now%600 dt = now%600
if (dt < 330): if (dt < 330):
now = 3000 + now - dt now = 3000 + now - dt
else: else:
now = 3600 + now - dt now = 3600 + now - dt
else: elif (period == 1):
# #
# e.g. H1 use 30 seconds to calculate the time. # e.g. H1 use 30 seconds to calculate the time.
# #
dt = now%600 dt = now%60
if (dt < 30): if (dt < 30):
now = 3540 + now - dt now = 3540 + now - dt
else: else:
now = 3600 + now - dt now = 3600 + now - dt
else:
# At the moment no support for parameters other than 1 or 10 minutes.
raise LmwParmWarn(parameter)
time_of_day=time.strftime("%H:%M", time.gmtime(now)) time_of_day=time.strftime("%H:%M", time.gmtime(now))
return { "day": time.strftime("%d-%m-%Y", time.gmtime(now)), return { "day": time.strftime("%d-%m-%Y", time.gmtime(now)),
"time_of_day": time.strftime("%H:%M", time.gmtime(now)) } "time_of_day": time.strftime("%H:%M", time.gmtime(now)) }
@@ -112,8 +593,8 @@ Opens the connection and logs in.
connects to lmw with tcp using the values of the object creation. connects to lmw with tcp using the values of the object creation.
""" """
try: try:
self._tcp = socket.create_connection((self.host, self.port)) self._tcp = socket.create_connection((self.host, self.port))
self._connecttime = time.time() self._connecttime = time.time()
except Exception as e: except Exception as e:
self.log.error("LmwSip.connect(%s, %s) failed: %s", self.log.error("LmwSip.connect(%s, %s) failed: %s",
self.host, self.port, e) self.host, self.port, e)
@@ -142,31 +623,12 @@ connects to lmw with tcp using the values of the object creation.
pass pass
self._socket = None self._socket = None
def reconnectcheck(self):
"""Checks if the connection is longer open than the reconnect time.
After this time a logout is sent and a new connection is created.
This prevents the 10 minute server timeout"""
if self.reconnecttime > 0:
ct = time.time() - self._connecttime
if ct > self.reconnecttime:
self.log.debug("LmwSip.reconnectcheck: reconnect after %i seconds" % ct)
#
# Disable check for the reconnect
#
self.reconnecttime = - self.reconnecttime
self.logout()
time.sleep(1)
self.connect()
self.login()
self.reconnecttime = - self.reconnecttime
def send(self, sipcmd): def send(self, sipcmd):
"""send(sipcmd) """send(sipcmd)
send a sip command to the server send a sip command to the server
""" """
self.reconnectcheck() self._idletime = time.time()
if self._socket != None: if self._socket != None:
try: try:
logcmd = sipcmd.strip('\r') logcmd = sipcmd.strip('\r')
@@ -196,16 +658,19 @@ send a sip command to the server
recieve a answer from the sip server recieve a answer from the sip server
""" """
c = 0
bytebuf=b'' bytebuf=b''
stringbuf="" stringbuf=""
while (self._socket != None) and (stringbuf.find("\r") == -1): while (self._socket != None) and (stringbuf.find("\r") == -1) and (c < 3):
try: try:
self.log.debug("LmwSip.recv: %s: Waiting for data" % self.cleartelnet); self.log.debug("LmwSip.recv: %s: Waiting for data" % self.cleartelnet);
bytebuf = self._socket.recv(4096) bytebuf = self._socket.recv(4096)
self.log.debug("recv: bytebuf: %s" % bytebuf) if (len(bytebuf) == 0):
if self.cleartelnet: c+=1
if bytebuf[0] == 255: self.log.debug("recv: bytebuf: %s" % bytebuf)
bytebuf = b'' if self.cleartelnet:
if bytebuf[0] == 255:
bytebuf = b''
except Exception as e: except Exception as e:
self.log.error("SipLmw.recv: socket timeout: %s", e) self.log.error("SipLmw.recv: socket timeout: %s", e)
self.closesocket() self.closesocket()
@@ -217,12 +682,16 @@ recieve a answer from the sip server
self.log.error("SipLmw.recv: decode error: %s", e) self.log.error("SipLmw.recv: decode error: %s", e)
self.closesocket() self.closesocket()
raise LmwSipDecodeError("LmwSip.recv: decode error", bytebuf) raise LmwSipDecodeError("LmwSip.recv: decode error", bytebuf)
if self._socket == None: if (c>=3) and (len(stringbuf) == 0):
self.log.warn("LmwSip.recv: No connection") self.log.warning("LmwSip.recv: No data recieved")
self.closesocket()
raise LmwSipConnectError("LmwSip.recv: socket close")
elif self._socket == None:
self.log.warning("LmwSip.recv: No connection")
elif len(stringbuf) == 0: elif len(stringbuf) == 0:
self.log.warn("LmwSip.recv: No data") self.log.warning("LmwSip.recv: No data")
elif stringbuf[0] != '!': elif stringbuf[0] != '!':
self.log.warn("LmwSip.recv: Sip error: %s" % stringbuf.strip('\r')) self.log.warning("LmwSip.recv: Sip error: %s" % stringbuf.strip('\r'))
else: else:
self.log.debug("LmwSip.recv: result: %s" % stringbuf.strip('\r')) self.log.debug("LmwSip.recv: result: %s" % stringbuf.strip('\r'))
return(stringbuf) return(stringbuf)
@@ -234,10 +703,69 @@ Login lmw using the object creation user, password.
Raises a LmwLoginFailure exception on failure Raises a LmwLoginFailure exception on failure
""" """
li="LI " + self.user + "," + self.password + "\r" li="LI " + self.user + "," + self.password + "\r"
#
# TODO: Check connect
#
# Don't use: sendrecv with reconnect check!
#
self.send(li) self.send(li)
d = self.recv() d = self.recv()
if (d[0] != '!'): if (d[0] != '!'):
raise LmwLoginFailure(self.user + ":" + d) self.closesocket()
raise LmwLoginFailure(self.user, d)
def reconnect(self):
self.logout()
time.sleep(1)
self.connect()
self.login()
def reconnectcheck(self):
"""reconnectcheck()
Checks if a reconnect is nessecery.
There are two timeouts:
The maxium connect time (reconnecttime)
The maxium idle time (idlereconnect)
"""
ct = time.time() - self._connecttime
if (self.reconnecttime > 0) and (ct > self.reconnecttime):
self.log.debug("LmwSip.reconnectcheck: reconnect after %i seconds" % ct)
self.reconnect()
it = time.time() - self._idletime
if (self.idlereconnect > 0) and (it > self.idlereconnect):
self.log.debug("LmwSip.reconnectcheck: idle reconnect after %i seconds" % it)
self.reconnect()
def sendrecv(self, cmd):
"""sendrecv(cmd)
send the command and recieve the answer.
retry on socket failure.
"""
c = 0
ret = ""
self.reconnectcheck()
while (ret == "") and (c < 3):
if (self._socket == None):
time.sleep(10)
self.log.warning("LmwSip.sendrecv: reconnect")
self.connect()
self.login()
try:
self.send(cmd)
ret = self.recv()
except LmwSipConnectError as e:
if (self.user != None):
self.connect()
self.login()
c+=1
ret=""
else:
c=3
raise(e)
return(ret)
def ti(self): def ti(self):
"""ti() """ti()
@@ -247,8 +775,7 @@ Request the time from lmw and returns the string.
Raises a LmwCmdWarn of failure Raises a LmwCmdWarn of failure
""" """
ti="TI " + self.meetnet + "\r" ti="TI " + self.meetnet + "\r"
self.send(ti) d = self.sendrecv(ti)
d = self.recv()
return (d[2:-1]) return (d[2:-1])
def cmd(self, process, location, parameter, time_delta, day, def cmd(self, process, location, parameter, time_delta, day,
@@ -280,12 +807,38 @@ Returns:
parameter + "," + time_delta + "," + day + "," + \ parameter + "," + time_delta + "," + day + "," + \
time_of_day + data + "\r" time_of_day + data + "\r"
self.send(cmdstr) d = self.sendrecv(cmdstr)
d = self.recv()
if (d[0] != '!'): if (d[0] != '!'):
raise LmwCmdWarn(cmdstr, d) raise LmwCmdWarn(cmdstr, d)
return (d[2:-1]) return (d[2:-1])
def valueStr(self, process, location, parameter, day = None,
time_of_day = None):
"""value(process, location, parameter, [day], [time_of_day]):
Parameters:
process: <WN|VW|AS>
location: <lmw location (e.g. HOEK)>
parameter: <lmw parameter (e.g. H10)>
day: [date = now()]
time_of_day: [time = now()]
The default returns the last value string including quality.
Example:
lmw.data_string("WN", "HOEK", "H10")
Returns a single string value with quality
"""
if (day == None or time_of_day == None):
last = self.lasttime(parameter)
if (day==None):
day=last["day"]
if (time_of_day==None):
time_of_day=last["time_of_day"]
return(self.cmd(process, location, parameter, "+00:00", day,
time_of_day, "DATA"))
def value(self, process, location, parameter, day = None, def value(self, process, location, parameter, day = None,
time_of_day = None): time_of_day = None):
"""value(process, location, parameter, [day], [time_of_day]): """value(process, location, parameter, [day], [time_of_day]):
@@ -304,14 +857,7 @@ Example:
Returns a single string value or None Returns a single string value or None
""" """
if (day == None or time_of_day == None): res = self.valueStr(process, location, parameter, day, time_of_day)
last = self.lasttime(parameter)
if (day==None):
day=last["day"]
if (time_of_day==None):
time_of_day=last["time_of_day"]
res = self.cmd(process, location, parameter, "+00:00", day,
time_of_day, "DATA")
value=re.sub("/.*$", "", res) value=re.sub("/.*$", "", res)
if (value == "99999"): if (value == "99999"):
value="" value=""
@@ -327,12 +873,13 @@ Returns a single string value or None
m = (window.seconds % 3600)//60 m = (window.seconds % 3600)//60
return("+%02i:%02i" % (h, m)) return("+%02i:%02i" % (h, m))
def _roundtime_(self, time, parameter): def _roundtime_(self, time, delta):
# Todo check: delta != 1 en delta != 10
if time.microsecond != 0: if time.microsecond != 0:
time += timedelta(microseconds=1000000-time.microsecond) time += timedelta(microseconds=1000000-time.microsecond)
if time.second != 0: if time.second != 0:
time += timedelta(seconds=60-time.second) time += timedelta(seconds=60-time.second)
if (parameter.find("10") != -1) and (time.minute % 10 != 0): if (delta == timedelta(minutes=10)) and (time.minute % 10 != 0):
time += timedelta(minutes=(10-time.minute%10)) time += timedelta(minutes=(10-time.minute%10))
return(time) return(time)
@@ -364,21 +911,22 @@ Errors:
endTime - startTime > 24 hour endTime - startTime > 24 hour
now - startTime < 30 days now - startTime < 30 days
""" """
startTime = self._roundtime_(startTime.astimezone(tz.gettz('GMT+1')), parameter) try:
delta = timedelta(minutes=self.period(parameter))
except Exception as e:
delta = timedelta(minutes=10)
raise(e)
startTime = self._roundtime_(startTime.astimezone(tz.gettz('GMT+1')), delta)
endTime = endTime.astimezone(tz.gettz('GMT+1')) endTime = endTime.astimezone(tz.gettz('GMT+1'))
if (parameter.find("10") != -1):
delta = timedelta(minutes=10)
else:
delta = timedelta(minutes=1)
if startTime > endTime: if startTime > endTime:
self.log.warn("starttime > endtime: %s > %s", startTime, endTime) self.log.warning("starttime > endtime: %s > %s", startTime, endTime)
raise sipTimeSeriesError(startTime, endTime, raise sipTimeSeriesError(startTime, endTime,
"starttime > endtime") "starttime > endtime")
if datetime.now(tz=tz.gettz('GMT+1')) - startTime > timedelta(days=30): if datetime.now(tz=tz.gettz('GMT+1')) - startTime > timedelta(days=30):
self.log.warn("now() - starttime > 30 days: %s", startTime) self.log.warning("now() - starttime > 30 days: %s", startTime)
raise sipTimeSeriesError(startTime, endTime, raise sipTimeSeriesError(startTime, endTime,
"now - starttime > 30 days") "now - starttime > 30 days")
@@ -509,3 +1057,11 @@ class LmwCmdWarn(Warning):
def __str__(self): def __str__(self):
return("Cmd %s failed: %s" %(self.cmd, self.message)) return("Cmd %s failed: %s" %(self.cmd, self.message))
class LmwParmWarn(Warning):
"""Exception for a unknown parameter"""
def __init__(self, parameter):
self.parameter = parameter
def __str__(self):
return("Unknown parameter: %s" % parameter)

View File

@@ -3,33 +3,16 @@
import sys import sys
import getopt import getopt
import argparse import argparse
import logging
from lmwsip import LmwSip from lmwsip import LmwSip
def main(): def run(args):
lastTime=LmwSip.lasttime(None, "H10") logging.basicConfig(level=args.debug)
parser = argparse.ArgumentParser(description="Run a sip file.") logging.debug("lmwsip.run %s" % args)
parser.add_argument("-u", "--unencrypted", action="store_true",
help="Run a sip connection without ssl")
parser.add_argument("-c", "--cleartelnet", action="store_true",
help="Clear telnet protocol in tcp session")
parser.add_argument("-H", "--host", action='store',
default="sip-lmw.rws.nl",
help="Host to connect to")
parser.add_argument("-p", "--port", action='store', type=int, default=443,
help="Port to connect to")
parser.add_argument("-d", "--date", action='store',
default=lastTime["day"],
help="Date replacement string [DD-MM-YYYY]")
parser.add_argument("-t", "--time", action='store',
default=lastTime["time_of_day"],
help="Time replacement string [HH:MM]")
parser.add_argument("files", type=argparse.FileType('r'), nargs="+",
help="Sip files to run")
args = parser.parse_args()
try: try:
lmwsip = LmwSip(host=args.host, port=args.port, lmwsip = LmwSip(host=args.host, port=args.port,
ssl=not args.unencrypted, ssl=not args.unencrypted,
check_ssl=not args.acceptssl,
cleartelnet=args.cleartelnet) cleartelnet=args.cleartelnet)
except Exception as e: except Exception as e:
print("Connect to lmw failed: %s" % e) print("Connect to lmw failed: %s" % e)
@@ -45,6 +28,37 @@ def main():
print("< [%s]" % (lmwsip.recv().strip('\r'))) print("< [%s]" % (lmwsip.recv().strip('\r')))
except: except:
pass pass
try:
lmwsip.closesocket()
except:
pass
def main():
lastTime=LmwSip(host=None).lasttime("H10")
parser = argparse.ArgumentParser(description="Run a sip file.")
parser.add_argument("-u", "--unencrypted", action="store_true",
help="Run a sip connection without ssl")
parser.add_argument("-a", "--acceptssl", action="store_true",
help="Accept ssl certificate")
parser.add_argument("-c", "--cleartelnet", action="store_true",
help="Clear telnet protocol in tcp session")
parser.add_argument("-H", "--host", action='store',
default="sip-lmw.rws.nl",
help="Host to connect to")
parser.add_argument("-p", "--port", action='store', type=int, default=443,
help="Port to connect to")
parser.add_argument("-d", "--date", action='store',
default=lastTime["day"],
help="Date replacement string [DD-MM-YYYY]")
parser.add_argument("-t", "--time", action='store',
default=lastTime["time_of_day"],
help="Time replacement string [HH:MM]")
parser.add_argument("-D", "--debug", action='store',
default="WARN",
help="Debug level")
parser.add_argument("files", type=argparse.FileType('r'), nargs="+",
help="Sip files to run")
run(parser.parse_args())
if __name__ == "__main__": if __name__ == "__main__":
main() main()

164
lmwsip/tests/__init__.py Executable file
View File

@@ -0,0 +1,164 @@
#!/usr/bin/python
import sys
import io
import unittest
import lmwsip
import lmwsip.tests.stubSipServer
import logging
from lmwsip.tests.stubSipServer import sipServer
from lmwsip.run import run
from datetime import datetime, timedelta
from dateutil import tz
from time import sleep
class myTestArgs():
pass
class lmwsipTest(unittest.TestCase):
def setUp(self):
self.sipserver = sipServer()
self.sip = None
self.sipserver.run()
def login(self, **args):
log = logging.basicConfig(level=logging.DEBUG)
self.sip = lmwsip.LmwSip("USER", "PASS", "localhost",
self.sipserver.port, ssl=False,
log=log, **args)
def tearDown(self):
if self.sip:
self.sip.closesocket()
self.sipserver.kill()
def test_sipobj(self):
self.login()
self.assertEqual(type(self.sip), lmwsip.LmwSip)
def test_H1(self):
self.sip = lmwsip.LmwSip(host=None)
self.assertEqual(self.sip.period('H1'), 1)
def test_H10(self):
self.sip = lmwsip.LmwSip(host=None)
self.assertEqual(self.sip.period('H10'), 10)
def test_xHm0(self):
self.sip = lmwsip.LmwSip(host=None)
self.assertEqual(self.sip.period('xHm0'), 10)
def test_Noparm(self):
self.sip = lmwsip.LmwSip(host=None)
with self.assertRaises(lmwsip.LmwParmWarn):
self.assertEqual(self.sip.period('Noparm'), None)
def test_loginfail(self):
with self.assertRaises(lmwsip.LmwLoginFailure):
self.sip = lmwsip.LmwSip("FAIL", "FAIL", "localhost",
self.sipserver.port, ssl=False)
def test_ti(self):
self.login()
self.assertEqual(type(self.sip.ti()), str)
def test_telnetti(self):
self.login(cleartelnet=True)
self.assertEqual(type(self.sip.ti()), str)
def test_cmd(self):
self.login()
self.assertEqual(type(self.sip.cmd("WN", "DUMMY", "H10", "+00:59", "2020-01-01", "00:00")), str)
def test_cmderr(self):
self.login()
with self.assertRaises(lmwsip.LmwCmdWarn):
self.assertEqual(type(self.sip.cmd("NOP", "DUMMY", "H10", "+00:59", "2020-01-01", "00:00")), str)
def test_value(self):
self.login()
self.assertEqual(type(self.sip.value("WN", "DUMMY", "H10")), str)
def test_value1min(self):
self.login()
self.assertEqual(type(self.sip.value("WN", "DUMMY", "H1")), str)
def test_valueStr(self):
self.login()
self.assertEqual(type(self.sip.valueStr("WN", "DUMMY", "H10")), str)
def test_logout(self):
self.login()
self.assertEqual(self.sip.logout(), None)
def test_lmwTimeSerie(self):
self.login()
timezone = tz.gettz('GMT+1')
res = self.sip.timeSerie("WN", "DUMMY", "H10",
datetime.now(timezone)-timedelta(minutes=60),
datetime.now(timezone))
self.assertEqual(type(res.ts), list)
self.assertEqual(len(res.ts), 6)
self.assertEqual(res.ts[1][1][0], '1')
def test_roundtime(self):
self.login()
timezone = tz.gettz('GMT+1')
t1 = datetime(2020, 1, 1, 0, 10, 0, 0, timezone)
t2 = datetime(2020, 1, 1, 0, 0, 0, 1, timezone)
self.assertEqual(self.sip._roundtime_(t1, timedelta(minutes=10)), t1)
self.assertEqual(self.sip._roundtime_(t2, timedelta(minutes=10)), t1)
def test_closerecv(self):
self.login()
self.sip.send("CLOSE")
with self.assertRaises(lmwsip.LmwSipConnectError):
self.sip.recv()
def test_closeti(self):
self.login()
self.sip.send("CLOSE")
self.assertEqual(type(self.sip.ti()), str)
def test_closecmd(self):
self.login()
self.sip.send("CLOSE")
self.assertEqual(type(self.sip.cmd("WN", "DUMMY", "H10", "+00:59", "2020-01-01", "00:00")), str)
def test_reconnect(self):
self.login(reconnecttime=1)
sleep(2)
self.assertEqual(self.sip.sendrecv("LOGOUTCOUNT"), "1\r")
def test_idlereconnect(self):
self.login(idlereconnect=1)
sleep(2)
self.assertEqual(self.sip.sendrecv("LOGOUTCOUNT"), "1\r")
def test_versionstr(self):
self.assertEqual(type(lmwsip.__version__), str)
def test_run(self):
capturedOutput = io.StringIO()
sys.stdout = capturedOutput
testSipFile = io.StringIO("LI USER,PASS\rTI LMW\rLO")
testSipFile.seek(0)
args = myTestArgs()
args.debug = "DEBUG"
args.host = "localhost"
args.port = self.sipserver.port
args.unencrypted = True
args.acceptssl = True
args.cleartelnet = False
args.time = "+00:59"
args.date = "2020-01-01"
args.files = [testSipFile]
run(args)
args.files[0].close()
self.assertEqual(capturedOutput.getvalue().find("!")>= 0, True)
self.assertEqual(capturedOutput.getvalue().find("?"), -1)
if __name__ == '__main__':
unittest.main()

View File

@@ -13,12 +13,15 @@ Implements the following commands:
CMD> TI LMW CMD> TI LMW
ANS< ! 20-JAN-01 00:00:00 ANS< ! 20-JAN-01 00:00:00
CMD> WN LMW,DUMMY,D10,+HH:MM,yyyy-mm-dd,HH:MM,DATA CMD> WN LMW,DUMMY,H10,+HH:MM,yyyy-mm-dd,HH:MM,DATA
ANS< ! 1/10,;2/10;.... ANS< ! 1/10,;2/10;....
CMD> WN LMW,DUMMY,D10,+HH:MM,yyyy-mm-dd,HH:MM,DATB CMD> WN LMW,DUMMY,H10,+HH:MM,yyyy-mm-dd,HH:MM,DATB
ANS< ! 1/10/0;2/10/0;.... ANS< ! 1/10/0;2/10/0;....
CMD> WN LMW,DUMMY,H1,+HH:MM,yyyy-mm-dd,HH:MM,DATA
ANS< ! 1/10,;2/10;....
CMD> LO CMD> LO
ANS< ! ANS< !
@@ -41,8 +44,9 @@ import time
import random import random
import socketserver import socketserver
class sipProtocol(socketserver.BaseRequestHandler): logoutcount=0
class sipProtocol(socketserver.BaseRequestHandler):
def match(self, m): def match(self, m):
return(self.data.find(m.encode()) == 0) return(self.data.find(m.encode()) == 0)
@@ -56,18 +60,19 @@ class sipProtocol(socketserver.BaseRequestHandler):
except: except:
self.data = None self.data = None
def meting(self): def number(self, b):
res = "" if b[0] == b'0':
sep = "! " return(int(b[0:1]))
if self.data[18:19] == b'0': else:
h = int(self.data[19:20].decode()) return(int(b[0:2]))
else:
h = int(self.data[18:20].decode()) def meting(self, delta=10):
if self.data[21:22] == b'0': res = ""
m = int(self.data[22:23].decode()) sep = "! "
else: elem = self.data.decode().split(",")
m = int(self.data[21:23].decode()) h = self.number(elem[3][1:3])
aantal = 1+(60*h+m)//10 m = self.number(elem[3][4:6])
aantal = 1+(60*h+m)//delta
if self.data[-1:] == b'A': if self.data[-1:] == b'A':
data = "%i/10" data = "%i/10"
else: else:
@@ -78,16 +83,24 @@ class sipProtocol(socketserver.BaseRequestHandler):
self.send(res) self.send(res)
def handle(self): def handle(self):
global logoutcount
self.read() self.read()
while self.data: while self.data:
if self.match("LI USER,PASS"): if self.match("LI USER,PASS"):
self.send("!") self.send("!")
elif self.match("TI LMW"): elif self.match("TI LMW"):
self.send("! 20-JAN-01 00:00:00") self.send("! 20-JAN-01 00:00:00")
elif self.match("WN LMW,DUMMY,D10"): elif self.match("WN LMW,DUMMY,H10,"):
self.meting() self.meting(10)
elif self.match("WN LMW,DUMMY,H1,"):
self.meting(1)
elif self.match("LOGOUTCOUNT"):
self.send(str(logoutcount))
elif self.match("LO"): elif self.match("LO"):
logoutcount+=1
self.send("!") self.send("!")
elif self.match("CLOSE"):
self.request.close()
else: else:
self.send("? ERROR") self.send("? ERROR")
self.read() self.read()
@@ -113,4 +126,6 @@ class sipServer(socketserver.TCPServer):
self.server_close() self.server_close()
if __name__ == '__main__': if __name__ == '__main__':
s = sipServer()
s.run()
pass pass

6
pyproject.toml Normal file
View File

@@ -0,0 +1,6 @@
[build-system]
requires = [
"setuptools>=42",
"wheel"
]
build-backend = "setuptools.build_meta"

16
setup.cfg Normal file
View File

@@ -0,0 +1,16 @@
[metadata]
name = lmwsip
version = 0.9.1
author = Marcel Nijenhof
author_email = pypi@marceln.org
description = Interface for the lmw sip protocol
long_description = file: README.md
long_description_content_type = text/markdown
url = https://marceln.org/git/Werk/lmwsip
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
[options]
python_requires = >= 3.6

View File

@@ -1,22 +1,4 @@
import setuptools from setuptools import setup
with open("README.md", "r") as fh: if __name__ == "__main__":
long_description = fh.read() setup()
setuptools.setup(
name="lmwsip-marceln", # Replace with your own username
version="0.0.1",
author="Marcel Nijenhof",
author_email="pip@pion.xs4all.nl",
description="Interface for the lmw sip protocol",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://marceln.org/git/Werk/lmwsip",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: TODO",
"Operating System :: OS Independent",
],
python_requires='>=3.6',
)

View File

@@ -1,51 +0,0 @@
#!/usr/bin/python
import unittest
import lmwsip
import stubSipServer
from datetime import datetime, timedelta
from dateutil import tz
class lmwsipTest(unittest.TestCase):
def setUp(self):
self.sipserver = stubSipServer.sipServer()
self.sipserver.run()
self.sip = lmwsip.LmwSip("USER", "PASS", "localhost",
self.sipserver.port, ssl=False)
def tearDown(self):
self.sipserver.kill()
self.sip.closesocket()
def test_sipobj(self):
self.assertEqual(type(self.sip), lmwsip.LmwSip)
def test_ti(self):
self.assertEqual(type(self.sip.ti()), str)
def test_cmd(self):
self.assertEqual(type(self.sip.cmd("WN", "DUMMY", "D10", "+00:59", "2020-01-01", "00:00")), str)
def test_logout(self):
self.assertEqual(self.sip.logout(), None)
def test_lmwTimeSerie(self):
timezone = tz.gettz('GMT+1')
res = self.sip.timeSerie("WN", "DUMMY", "D10",
datetime.now(timezone)-timedelta(minutes=60),
datetime.now(timezone))
self.assertEqual(type(res.ts), list)
self.assertEqual(len(res.ts), 6)
self.assertEqual(res.ts[1][1][0], '1')
def test_roundtime(self):
timezone = tz.gettz('GMT+1')
t1 = datetime(2020, 1, 1, 0, 10, 0, 0, timezone)
t2 = datetime(2020, 1, 1, 0, 0, 0, 1, timezone)
self.assertEqual(self.sip._roundtime_(t1, "D10"), t1)
self.assertEqual(self.sip._roundtime_(t2, "D10"), t1)
if __name__ == '__main__':
unittest.main()