28 Commits

Author SHA1 Message Date
2cead40a74 Correctie schrijf test
All checks were successful
build / build (push) Successful in 1m8s
2025-03-15 21:12:38 +01:00
ee8ca45a59 Version update for stat command
All checks were successful
build / build (push) Successful in 1m22s
2024-09-21 10:54:02 +02:00
af04830dfb Update python docstrins 2024-09-21 10:53:23 +02:00
a8e70e793f Run tox paralel to speedup tests 2024-09-21 10:50:04 +02:00
0c07dcfd66 Added stat command to find last measurement/forecast times 2024-09-21 10:48:34 +02:00
ef778c3e0a BUG FIX: cmdWrite fix
All checks were successful
build / build (push) Successful in 1m34s
2024-04-24 16:07:58 +02:00
49eb1522b6 Versie update: cmdWrite fix
Some checks failed
build / build (push) Has been cancelled
2024-04-24 16:06:15 +02:00
cdeeceeb55 Werkende upload
All checks were successful
build / build (push) Successful in 1m33s
2024-04-07 22:59:11 +02:00
64089ce72c Versie 0.9.7 2024-04-05 16:35:37 +02:00
7683ec29e9 Cleanup of module documentation
Some checks failed
build / build (push) Failing after 1m29s
2024-04-05 16:27:54 +02:00
285b3514a8 Added cmdWrite 2024-04-05 16:19:55 +02:00
f32c007b3f lmwParameter comment in class comment geplaats
All checks were successful
build / build (push) Successful in 1m45s
2024-04-04 21:52:34 +02:00
014dc507cc Commentaar toegevoegd voor lmwParamers 2024-04-04 21:39:47 +02:00
cec151e564 Overgang gitea action
All checks were successful
build / build (push) Successful in 1m44s
2024-02-18 22:08:14 +01:00
26f1caa60e Aanpassing pre-commit 2024-02-18 22:05:47 +01:00
7092e69e6a Nieuwe python versies toegevoegd in tox test 2024-01-21 20:42:51 +01:00
b32bce956f Extra parameters aan lijst toegevoegd
All checks were successful
continuous-integration/drone/push Build is passing
2022-11-02 10:47:47 +01:00
22bb4e6bd3 Updates .drone
Some checks failed
continuous-integration/drone/push Build is failing
2022-06-30 10:52:31 +02:00
49954d762b Updates .drone
Some checks failed
continuous-integration/drone/push Build is failing
2022-06-30 10:24:31 +02:00
30504239e1 Versie verhogen na cleartelnet fix
Some checks failed
continuous-integration/drone/push Build is failing
2022-06-29 18:20:27 +02:00
Marcel Nijenhof
42799296a9 Bug fix: Cleartelnet code werkte niet omdat deze in de if stond voor 0 bytes ontvangen.
Some checks failed
continuous-integration/drone/push Build is failing
2022-06-29 14:23:40 +00:00
Marcel Nijenhof
ac54b7cd0d Upload naar pypi org prod
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2022-01-03 18:56:28 +01:00
Marcel Nijenhof
1df2a42196 Correctie .drone
Some checks reported errors
continuous-integration/drone/push Build is passing
continuous-integration/drone Build was killed
2022-01-03 18:42:44 +01:00
Marcel Nijenhof
2909ea7ed4 PYTHONPATH=src zodat lmwsip gevonden word
Some checks failed
continuous-integration/drone/push Build is failing
2022-01-03 18:39:16 +01:00
Marcel Nijenhof
f55d6c2e19 PYTHONPATH=. zodat llmwsip gevonden word
Some checks failed
continuous-integration/drone/push Build is failing
2022-01-03 18:38:08 +01:00
Marcel Nijenhof
664b215f16 Verplaatsen test directory
Some checks failed
continuous-integration/drone/push Build is failing
2022-01-03 18:32:08 +01:00
Marcel Nijenhof
5fe756ce97 Small corrections setup.cfg 2022-01-03 18:14:40 +01:00
Marcel Nijenhof
bf28862f1f Update README: install via pypi 2022-01-03 18:03:03 +01:00
9 changed files with 144 additions and 220 deletions

View File

@@ -1,181 +0,0 @@
---
kind: pipeline
type: exec
name: CentOS7_test
platform:
os: linux
arch: amd64
variant: CentOS7
steps:
- name: Run unit test
environment:
PYTHONPATH: ..
commands:
- cd src
- python3 -m unittest -v lmwsip.tests
---
kind: pipeline
type: exec
name: CentOS8_test
platform:
os: linux
arch: amd64
variant: CentOS8
steps:
- name: Run unit test
environment:
PYTHONPATH: .
commands:
- cd src
- python3 -m unittest -v lmwsip.tests
---
kind: pipeline
type: exec
name: Ubuntu1804_test
platform:
os: linux
arch: amd64
variant: Ubuntu1804
steps:
- name: Run unit test
environment:
PYTHONPATH: .
commands:
- cd src
- python3 -m unittest -v lmwsip.tests
---
kind: pipeline
type: exec
name: Fedora_test
platform:
os: linux
arch: amd64
variant: Fedora
steps:
- name: Run unit test
environment:
PYTHONPATH: .
commands:
- tox
---
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
- cd src
- python -m unittest -v lmwsip.tests
---
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
- cd src
- python -m unittest -v lmwsip.tests
---
kind: pipeline
type: exec
name: Build
platform:
os: linux
arch: amd64
variant: Fedora
steps:
- name: Build package files
commands:
- python3 -m build
- name: Run final test after build
commands:
- tox
- 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}"
- name: Versie upload naar pypi test
environment:
TWINE_USERNAME:
from_secret: twine_username
TWINE_PASSWORD:
from_secret: twine_password
commands:
- python3 -m twine upload --repository testpypi dist/*
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 src
- 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

View File

@@ -0,0 +1,21 @@
---
name: build
on:
- push
jobs:
build:
runs-on: fedora-builder
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Build package
run: python3 -m build
- name: run tox
run: tox
- name: Upload na pypi
env:
TWINE_USERNAME: ${{ secrets.PYPI_USER }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
if: github.ref_type == 'tag'
run: python3 -m twine upload dist/*

View File

@@ -12,12 +12,10 @@ how to use it.
## Installing ## Installing
The package is not available on [PyPI](https://pypi.org/). Just install the package with 'pip':
At the moment the package is hosted at https://marceln.org/download/python.
You can install the package with pip:
``` ```
pip install --extra-index-url https://marceln.org/download/python lmwsip pip install lmwsip
``` ```
## Examples ## Examples

View File

@@ -2,9 +2,10 @@
set -e set -e
yamllint .gitea/workflows/*yml
VERSION=$(grep version setup.cfg | sed 's/.*= *//') VERSION=$(grep version setup.cfg | sed 's/.*= *//')
sed -i "s/^__version__ = .*/__version__ = '${VERSION}'/" src/lmwsip/__init__.py sed -i "s/^__version__ = .*/__version__ = '${VERSION}'/" src/lmwsip/__init__.py
git add src/lmwsip/__init__.py git add src/lmwsip/__init__.py
tox tox -p
yamllint .drone.yml

View File

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

View File

@@ -12,7 +12,7 @@ from datetime import datetime, timedelta
from dateutil import tz from dateutil import tz
""" Version info changed by git hook """ """ Version info changed by git hook """
__version__ = '0.9.2' __version__ = '0.9.9'
class LmwSip: class LmwSip:
"""Class to connect to the LMW Standard Interface prototcol (sip) """Class to connect to the LMW Standard Interface prototcol (sip)
@@ -27,7 +27,12 @@ Support for:
ti ti
cmd(wn, vw, as) cmd(wn, vw, as)
lmwParameters:
- Type: WN, VW, AS
- Array size: [1-201]
- Periode: 1, 10
""" """
lmwParameters = { lmwParameters = {
'Tm02_MV': ('VW', 1, 0), 'Tm02_MV': ('VW', 1, 0),
'xH1': ('WN', 1, 1), 'xH1': ('WN', 1, 1),
@@ -489,7 +494,12 @@ Support for:
'xH60': ('WN', 1, 60), 'xH60': ('WN', 1, 60),
'xNI60': ('WN', 1, 60), 'xNI60': ('WN', 1, 60),
'xQ60': ('WN', 1, 60), 'xQ60': ('WN', 1, 60),
'xH60R': ('WN', 1, 60) 'xH60R': ('WN', 1, 60),
'QfQStt10': ('WN', 1, 10),
'QfQTr10': ('WN', 1, 10),
'QfQSt10': ('WN', 1, 10),
'QfHYS10': ('WN', 1, 10),
'QfQSy10': ('WN', 1, 10)
} }
def __init__(self, user=None, password=None, def __init__(self, user=None, password=None,
@@ -588,7 +598,7 @@ Opens the connection and logs in.
"time_of_day": time.strftime("%H:%M", time.gmtime(now)) } "time_of_day": time.strftime("%H:%M", time.gmtime(now)) }
def connect(self): def connect(self):
"""connect() """Setup the network connection
connects to lmw with tcp using the values of the object creation. connects to lmw with tcp using the values of the object creation.
""" """
@@ -624,7 +634,7 @@ connects to lmw with tcp using the values of the object creation.
self._socket = None self._socket = None
def send(self, sipcmd): def send(self, sipcmd):
"""send(sipcmd) """Send a sip command to the server
send a sip command to the server send a sip command to the server
""" """
@@ -654,7 +664,7 @@ send a sip command to the server
raise LmwSipConnectError("LmwSip.telnetheader: Socket connection lost") raise LmwSipConnectError("LmwSip.telnetheader: Socket connection lost")
def recv(self): def recv(self):
"""recv() """Recieve the results
recieve a answer from the sip server recieve a answer from the sip server
""" """
@@ -668,9 +678,9 @@ recieve a answer from the sip server
if (len(bytebuf) == 0): if (len(bytebuf) == 0):
c+=1 c+=1
self.log.debug("recv: bytebuf: %s" % bytebuf) self.log.debug("recv: bytebuf: %s" % bytebuf)
if self.cleartelnet: if self.cleartelnet:
if bytebuf[0] == 255: if bytebuf[0] == 255:
bytebuf = b'' 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()
@@ -697,7 +707,7 @@ recieve a answer from the sip server
return(stringbuf) return(stringbuf)
def login(self): def login(self):
"""login() """Login the sip server
Login lmw using the object creation user, password. Login lmw using the object creation user, password.
Raises a LmwLoginFailure exception on failure Raises a LmwLoginFailure exception on failure
@@ -721,7 +731,7 @@ Raises a LmwLoginFailure exception on failure
self.login() self.login()
def reconnectcheck(self): def reconnectcheck(self):
"""reconnectcheck() """Check if we need to reconnect.
Checks if a reconnect is nessecery. Checks if a reconnect is nessecery.
@@ -739,7 +749,7 @@ There are two timeouts:
self.reconnect() self.reconnect()
def sendrecv(self, cmd): def sendrecv(self, cmd):
"""sendrecv(cmd) """Send a a command and recieve the result.
send the command and recieve the answer. send the command and recieve the answer.
retry on socket failure. retry on socket failure.
@@ -768,7 +778,7 @@ retry on socket failure.
return(ret) return(ret)
def ti(self): def ti(self):
"""ti() """Recieve the time from the sipserver.
Request the time from lmw and returns the string. Request the time from lmw and returns the string.
@@ -780,7 +790,7 @@ Raises a LmwCmdWarn of failure
def cmd(self, process, location, parameter, time_delta, day, def cmd(self, process, location, parameter, time_delta, day,
time_of_day, cmd_type="DATA"): time_of_day, cmd_type="DATA"):
"""cmd(process, location, parameter, time_delta, day, time_of_day) """Create a sip command from the paramters
Send a cmd to LMW and returns the lmw string Send a cmd to LMW and returns the lmw string
@@ -812,9 +822,35 @@ Returns:
raise LmwCmdWarn(cmdstr, d) raise LmwCmdWarn(cmdstr, d)
return (d[2:-1]) return (d[2:-1])
def cmdWrite(self, process, location, parameter, time_delta, day,
time_of_day, values):
"""Write data to LMW
process: <WNT|VWT|AST>
location: <lmw location (e.g. HOEK)>
parameter: <lmw parameter (e.g. H10)>
time_delta: <Time windows (max 23:59, e.g. +01:00>
day: <Date>
time_of_day: <Time>
data: Values to be writen (e.g. 33/10;35/10).
Example:
lmw.cmdWrite("WNT", "HOEK", "H10", "+00:20", "13-08-2018", "16:00", "33/10;35/10")
Returns:
The LMW answer string
"""
cmdstr=process + " " + self.meetnet + "," + location + "," + \
parameter + "," + time_delta + "," + day + "," + \
time_of_day + "," + values + "\r"
d = self.sendrecv(cmdstr)
if (d[0] != '!'):
raise LmwCmdWarn(cmdstr, d)
return (d[2:-1])
def valueStr(self, process, location, parameter, day = None, def valueStr(self, process, location, parameter, day = None,
time_of_day = None): time_of_day = None):
"""value(process, location, parameter, [day], [time_of_day]): """Get string of values from sip
Parameters: Parameters:
process: <WN|VW|AS> process: <WN|VW|AS>
@@ -826,7 +862,7 @@ Parameters:
The default returns the last value string including quality. The default returns the last value string including quality.
Example: Example:
lmw.data_string("WN", "HOEK", "H10") lmw.valueStr("WN", "HOEK", "H10")
Returns a single string value with quality Returns a single string value with quality
""" """
@@ -841,7 +877,7 @@ Returns a single string value with quality
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]): """Get one value from sip
Parameters: Parameters:
process: <WN|VW|AS> process: <WN|VW|AS>
@@ -853,7 +889,7 @@ Parameters:
The default returns the last value. The default returns the last value.
Example: Example:
lmw.data_string("WN", "HOEK", "H10") lmw.value("WN", "HOEK", "H10")
Returns a single string value or None Returns a single string value or None
""" """
@@ -868,6 +904,26 @@ Returns a single string value or None
# #
return(value) return(value)
def stat(self, process, location, parameter):
"""Get the last measurement or the start en end of forecasts.
Parameters:
process: <WN|VW|AS>
location: <lmw location (e.g. HOEK)>
parameter: <lmw parameter (e.g. H10)>
The default returns the last value.
Example:
lmw.stat("WN", "HOEK", "H10")
Returns a single string value or None
"""
stat="%s %s,%s,%s,STAT\r" % (process, self.meetnet, location, parameter)
d = self.sendrecv(stat)
if d[0] != '!':
raise LmwCmdWarn(stat, d)
return (d[2:-1])
def _lmwdelta_(self, window): def _lmwdelta_(self, window):
h = 24*window.days + window.seconds // 3600 h = 24*window.days + window.seconds // 3600
m = (window.seconds % 3600)//60 m = (window.seconds % 3600)//60
@@ -885,7 +941,7 @@ Returns a single string value or None
def timeSerie(self, process, location, parameter, def timeSerie(self, process, location, parameter,
startTime, endTime, cmd_type="DATB"): startTime, endTime, cmd_type="DATB"):
"""timeSerie(process, location, parameter, startTime, endTime, cmd_type="DATA") """Get a python data structure with the results.
Parameters: Parameters:
process: <WN|VW|AS> process: <WN|VW|AS>
@@ -902,7 +958,7 @@ The times should have correct timezone information. Otherwise local timezone
is assumed. Timezones are converted to 'GMT+1' for the sip commands. is assumed. Timezones are converted to 'GMT+1' for the sip commands.
Example: Example:
lmw.data_string("WN", "HOEK", "H10", ...) lmw.timeSerie("WN", "HOEK", "H10", ...)
Returns a LmwtimeSerie object Returns a LmwtimeSerie object
@@ -954,7 +1010,7 @@ Errors:
return(res) return(res)
def logout(self): def logout(self):
"""logout() """Logut of the sip server,
Logs of Logs of
""" """
@@ -978,7 +1034,7 @@ Note:
""" """
def __init__(self, start, delta, values=""): def __init__(self, start, delta, values=""):
"""lmwTimeSerie(start, delta, values) """lmwTimeSerie init
Create a lmwTimeSerie object with: Create a lmwTimeSerie object with:
start: Start time start: Start time
@@ -991,7 +1047,7 @@ Create a lmwTimeSerie object with:
self.addvalues(start, values) self.addvalues(start, values)
def addvalues(self, start, values): def addvalues(self, start, values):
"""addvalues(start, delta, values) """Add values
Add values to a timeserie Add values to a timeserie
start: Start time start: Start time

View File

@@ -4,10 +4,10 @@ import sys
import io import io
import unittest import unittest
import lmwsip import lmwsip
import lmwsip.tests.stubSipServer import stubSipServer
import logging import logging
from lmwsip.tests.stubSipServer import sipServer from stubSipServer import sipServer
from lmwsip.run import run from lmwsip.run import run
from datetime import datetime, timedelta from datetime import datetime, timedelta
from dateutil import tz from dateutil import tz
@@ -77,10 +77,22 @@ class lmwsipTest(unittest.TestCase):
with self.assertRaises(lmwsip.LmwCmdWarn): with self.assertRaises(lmwsip.LmwCmdWarn):
self.assertEqual(type(self.sip.cmd("NOP", "DUMMY", "H10", "+00:59", "2020-01-01", "00:00")), str) self.assertEqual(type(self.sip.cmd("NOP", "DUMMY", "H10", "+00:59", "2020-01-01", "00:00")), str)
def test_cmdWrite(self):
self.login()
self.assertEqual(type(self.sip.cmdWrite("WNT", "DUMMY", "H10", "+00:20", "2020-01-01", "00:00", "35/10;33/10")), str)
def test_value(self): def test_value(self):
self.login() self.login()
self.assertEqual(type(self.sip.value("WN", "DUMMY", "H10")), str) self.assertEqual(type(self.sip.value("WN", "DUMMY", "H10")), str)
def test_stat_wn(self):
self.login()
self.assertEqual(type(self.sip.stat("WN", "DUMMY", "H10")), str)
def test_stat_vw(self):
self.login()
self.assertEqual(type(self.sip.stat("VW", "DUMMY", "H10V")), str)
def test_value1min(self): def test_value1min(self):
self.login() self.login()
self.assertEqual(type(self.sip.value("WN", "DUMMY", "H1")), str) self.assertEqual(type(self.sip.value("WN", "DUMMY", "H1")), str)

View File

@@ -13,6 +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> WNT LMW,DUMMY,H1,+HH:MM,yyyy-mm-dd,HH:MM,NN/NN;NN/NN
ANS< ! 1/10,;2/10;....
CMD> WN LMW,DUMMY,H10,STAT
ANS< ! 20-JAN-01 00:00
CMD> VW LMW,DUMMY,H10V,STAT
ANS< ! 20-JAN-01 00:00;20-JAN-01 01:00
CMD> WN LMW,DUMMY,H10,+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;....
@@ -48,7 +57,7 @@ logoutcount=0
class sipProtocol(socketserver.BaseRequestHandler): 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()) != -1)
def send(self, a): def send(self, a):
a = "%s\r" % a a = "%s\r" % a
@@ -86,12 +95,21 @@ class sipProtocol(socketserver.BaseRequestHandler):
global logoutcount global logoutcount
self.read() self.read()
while self.data: while self.data:
if self.match("LI USER,PASS"): if self.match("CLOSE"):
self.request.close()
elif 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("WNT LMW,DUMMY,H10,"):
self.send("!")
elif self.match("WN LMW,DUMMY,H10,"): elif self.match("WN LMW,DUMMY,H10,"):
self.meting(10) if self.match("STAT"):
self.send("! 20-JAN-01 00:00")
else:
self.meting(10)
elif self.match("VW LMW,DUMMY,H10V,STAT"):
self.send("! 20-JAN-01 00:00;20-JAN-01 01:00")
elif self.match("WN LMW,DUMMY,H1,"): elif self.match("WN LMW,DUMMY,H1,"):
self.meting(1) self.meting(1)
elif self.match("LOGOUTCOUNT"): elif self.match("LOGOUTCOUNT"):
@@ -99,8 +117,6 @@ class sipProtocol(socketserver.BaseRequestHandler):
elif self.match("LO"): elif self.match("LO"):
logoutcount+=1 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()

View File

@@ -1,6 +1,6 @@
[tox] [tox]
envlist = py36,py37,py38,py310 envlist = py36,py37,py38,py310,py311,py312,py313
[testenv] [testenv]
deps = python-dateutil deps = python-dateutil
commands = python -m unittest -v lmwsip.tests commands = python tests/main.py