1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-30 00:00:11 +01:00

python: flake8 liniting

This commit is contained in:
Steffen Vogel 2020-06-07 23:24:21 +02:00
parent c7fd20e478
commit f6ef7265ce
7 changed files with 177 additions and 142 deletions

View file

@ -1,4 +1,3 @@
import os
from setuptools import setup, find_namespace_packages
from glob import glob
@ -6,33 +5,33 @@ with open('README.md') as f:
long_description = f.read()
setup(
name = 'villas-node',
version = '0.10.0',
author = 'Steffen Vogel',
author_email = 'acs-software@eonerc.rwth-aachen.de',
description = 'Python-support for VILLASnode simulation-data gateway',
license = 'GPL-3.0',
keywords = 'simulation power system real-time villas',
url = 'https://git.rwth-aachen.de/acs/public/villas/VILLASnode',
packages = find_namespace_packages(include=['villas.*']),
long_description = long_description,
long_description_content_type = 'text/markdown',
classifiers = [
name='villas-node',
version='0.10.0',
author='Steffen Vogel',
author_email='acs-software@eonerc.rwth-aachen.de',
description='Python-support for VILLASnode simulation-data gateway',
license='GPL-3.0',
keywords='simulation power system real-time villas',
url='https://git.rwth-aachen.de/acs/public/villas/VILLASnode',
packages=find_namespace_packages(include=['villas.*']),
long_description=long_description,
long_description_content_type='text/markdown',
classifiers=[
'Development Status :: 4 - Beta',
'Topic :: Scientific/Engineering',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
'License :: OSI Approved :: '
'GNU General Public License v3 or later (GPLv3+)',
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python :: 3'
],
install_requires = [
install_requires=[
'requests',
'linuxfd'
],
setup_requires = [
setup_requires=[
'm2r'
],
scripts = glob('bin/*')
scripts=glob('bin/*')
)

View file

@ -1,2 +1,2 @@
from message import Message
from timestamp import Timestamp
from message import Message # noqa F401
from timestamp import Timestamp # noqa F401

View file

@ -1,24 +1,30 @@
import .timestamp
import villas.human.timestamp as ts
from functools import total_ordering
@total_ordering
class Message:
"""Parsing a VILLASnode sample from a file (not a UDP package!!)"""
"""Parsing a VILLASnode sample from a file (not a UDP package!!)"""
def __init__(self, ts, values, source = None):
self.source = source
self.ts = ts
self.values = values
def __init__(self, ts, values, source=None):
self.source = source
self.ts = ts
self.values = values
@classmethod
def parse(self, line, source = None):
csv = line.split()
@classmethod
def parse(cls, line, source=None):
csv = line.split()
t = ts.Timestamp.parse(csv[0])
v = map(float, csv[1:])
t = ts.Timestamp.parse(csv[0])
v = map(float, csv[1:])
return Message(t, v, source)
return Message(t, v, source)
def __str__(self):
return '%s %s' % (self.ts, " ".join(map(str, self.values)))
def __str__(self):
return '%s %s' % (self.ts, " ".join(map(str, self.values)))
def __cmp__(self, other):
return cmp(self.ts, other.ts)
def __eq__(self, other):
return self.ts == other.ts
def __lt__(self, other):
return self.ts < other.ts

View file

@ -1,46 +1,54 @@
import re
from functools import total_ordering
@total_ordering
class Timestamp:
"""Parsing the VILLASnode human-readable timestamp format"""
"""Parsing the VILLASnode human-readable timestamp format"""
def __init__(self, seconds = 0, nanoseconds = None, offset = None, sequence = None):
self.seconds = seconds
self.nanoseconds = nanoseconds
self.offset = offset
self.sequence = sequence
def __init__(self, seconds=0, nanoseconds=None,
offset=None, sequence=None):
self.seconds = seconds
self.nanoseconds = nanoseconds
self.offset = offset
self.sequence = sequence
@classmethod
def parse(self, ts):
m = re.match('(\d+)(?:\.(\d+))?([-+]\d+(?:\.\d+)?(?:e[+-]?\d+)?)?(?:\((\d+)\))?', ts)
@classmethod
def parse(cls, ts):
m = re.match(r'(\d+)(?:\.(\d+))?([-+]\d+(?:\.\d+)?'
r'(?:e[+-]?\d+)?)?(?:\((\d+)\))?', ts)
seconds = int(m.group(1)); # Mandatory
nanoseconds = int(m.group(2)) if m.group(2) else None
offset = float(m.group(3)) if m.group(3) else None
sequence = int(m.group(4)) if m.group(4) else None
seconds = int(m.group(1)) # Mandatory
nanoseconds = int(m.group(2)) if m.group(2) else None
offset = float(m.group(3)) if m.group(3) else None
sequence = int(m.group(4)) if m.group(4) else None
return Timestamp(seconds, nanoseconds, offset, sequence)
return Timestamp(seconds, nanoseconds, offset, sequence)
def __str__(self):
str = "%u" % (self.seconds)
def __str__(self):
str = "%u" % (self.seconds)
if self.nanoseconds is not None:
str += ".%09u" % self.nanoseconds
if self.offset is not None:
str += "+%u" % self.offset
if self.sequence is not None:
str += "(%u)" % self.sequence
if self.nanoseconds is not None:
str += ".%09u" % self.nanoseconds
if self.offset is not None:
str += "+%u" % self.offset
if self.sequence is not None:
str += "(%u)" % self.sequence
return str
return str
def __float__(self):
sum = float(self.seconds)
def __float__(self):
sum = float(self.seconds)
if self.nanoseconds is not None:
sum += self.nanoseconds * 1e-9
if self.offset is not None:
sum += self.offset
if self.nanoseconds is not None:
sum += self.nanoseconds * 1e-9
if self.offset is not None:
sum += self.offset
return sum
return sum
def __cmp__(self, other):
return cmp(float(self), float(other))
def __eg__(self, other):
return float(self) == float(other)
def __lt__(self, other):
return float(self) < float(other)

View file

@ -7,6 +7,7 @@ from threading import Thread
logger = logging.getLogger(__name__)
class RecvThread(Thread):
def __init__(self, cb):
@ -78,4 +79,4 @@ def communicate(rate, recv_cb=None, send_cb=None, wait=True):
logger.info('Received Ctrl+C. Stopping send/recv threads')
# Threads are daemon threads
# and therefore killed with program termination
# and therefore killed with program termination

View file

@ -9,9 +9,12 @@ import datetime
LOGGER = logging.getLogger('villas.node')
class Node(object):
def __init__(self, log_filename = None, config_filename = None, config = { }, api = 'http://localhost:8080', executable = 'villas-node', **kwargs):
def __init__(self, log_filename=None, config_filename=None,
config={}, api='http://localhost:8080',
executable='villas-node', **kwargs):
self.config = config
self.config_filename = config_filename
self.log_filename = log_filename
@ -21,7 +24,8 @@ class Node(object):
self.child = None
def start(self):
self.config_file = tempfile.NamedTemporaryFile(mode='w+', suffix='.json')
self.config_file = tempfile.NamedTemporaryFile(mode='w+',
suffix='.json')
if self.config_filename:
with open(self.config_filename) as f:
@ -33,13 +37,16 @@ class Node(object):
if self.log_filename is None:
now = datetime.datetime.now()
self.log_filename = now.strftime('villas-node_%Y-%m-%d_%H-%M-%S.log')
self.log_filename = now.strftime(
'villas-node_%Y-%m-%d_%H-%M-%S.log')
self.log = open(self.log_filename, 'w+')
LOGGER.info("Starting VILLASnode instance with config: %s", self.config_file.name)
LOGGER.info("Starting VILLASnode instance with config: %s",
self.config_file.name)
self.child = subprocess.Popen([self.executable, self.config_file.name], stdout=self.log, stderr=self.log)
self.child = subprocess.Popen([self.executable, self.config_file.name],
stdout=self.log, stderr=self.log)
def pause(self):
LOGGER.info("Pausing VILLASnode instance")
@ -74,10 +81,10 @@ class Node(object):
def paths(self):
return self.request('paths')['response']
def request(self, action, req = None):
def request(self, action, req=None):
body = {
'action' : action,
'id' : str(uuid.uuid4())
'action': action,
'id': str(uuid.uuid4())
}
if req is not None:

View file

@ -1,93 +1,107 @@
import re
from datetime import datetime
from functools import total_ordering
@total_ordering
class Timestamp:
"""Parsing the VILLASnode human-readable timestamp format"""
"""Parsing the VILLASnode human-readable timestamp format"""
def __init__(self, seconds=None, nanoseconds=None, offset=None, sequence=None):
self.seconds = seconds
self.nanoseconds = nanoseconds
self.offset = offset
self.sequence = sequence
def __init__(self, seconds=None, nanoseconds=None,
offset=None, sequence=None):
self.seconds = seconds
self.nanoseconds = nanoseconds
self.offset = offset
self.sequence = sequence
@classmethod
def now(self, offset=None, sequence=None):
n = datetime.utcnow()
@classmethod
def now(cls, offset=None, sequence=None):
n = datetime.utcnow()
secs = int(n.timestamp())
nsecs = 1000 * n.microsecond
secs = int(n.timestamp())
nsecs = 1000 * n.microsecond
return Timestamp(seconds=secs, nanoseconds=nsecs, offset=offset, sequence=sequence)
return Timestamp(seconds=secs, nanoseconds=nsecs,
offset=offset, sequence=sequence)
@classmethod
def parse(self, ts):
m = re.match('(\d+)(?:\.(\d+))?([-+]\d+(?:\.\d+)?(?:e[+-]?\d+)?)?(?:\((\d+)\))?', ts)
@classmethod
def parse(cls, ts):
m = re.match(r'(\d+)(?:\.(\d+))?([-+]\d+(?:\.\d+)?'
r'(?:e[+-]?\d+)?)?(?:\((\d+)\))?', ts)
seconds = int(m.group(1)); # Mandatory
nanoseconds = int(m.group(2)) if m.group(2) else None
offset = float(m.group(3)) if m.group(3) else None
sequence = int(m.group(4)) if m.group(4) else None
seconds = int(m.group(1)) # Mandatory
nanoseconds = int(m.group(2)) if m.group(2) else None
offset = float(m.group(3)) if m.group(3) else None
sequence = int(m.group(4)) if m.group(4) else None
return Timestamp(seconds, nanoseconds, offset, sequence)
return Timestamp(seconds, nanoseconds, offset, sequence)
def __str__(self):
str = "%u" % (self.seconds)
def __str__(self):
str = "%u" % (self.seconds)
if self.nanoseconds is not None:
str += ".%09u" % self.nanoseconds
if self.offset is not None:
str += "+%u" % self.offset
if self.sequence is not None:
str += "(%u)" % self.sequence
if self.nanoseconds is not None:
str += ".%09u" % self.nanoseconds
if self.offset is not None:
str += "+%u" % self.offset
if self.sequence is not None:
str += "(%u)" % self.sequence
return str
return str
def __float__(self):
sum = float(self.seconds)
def __float__(self):
sum = float(self.seconds)
if self.nanoseconds is not None:
sum += self.nanoseconds * 1e-9
if self.offset is not None:
sum += self.offset
if self.nanoseconds is not None:
sum += self.nanoseconds * 1e-9
if self.offset is not None:
sum += self.offset
return sum
return sum
def __cmp__(self, other):
return cmp(float(self), float(other))
def __eq__(self, other):
return float(self) == float(other)
def __lt__(self, other):
return float(self) < float(other)
@total_ordering
class Sample:
"""Parsing a VILLASnode sample from a file (not a UDP package!!)"""
"""Parsing a VILLASnode sample from a file (not a UDP package!!)"""
def __init__(self, ts, values):
self.ts = ts
self.values = values
def __init__(self, ts, values):
self.ts = ts
self.values = values
@classmethod
def parse(self, line):
csv = line.split()
@classmethod
def parse(cls, line):
csv = line.split()
ts = Timestamp.parse(csv[0])
vs = [ ]
ts = Timestamp.parse(csv[0])
vs = []
for value in csv[1:]:
try:
v = float(value)
except ValueError:
value = value.lower()
try:
v = complex(value)
except:
if value.endswith('i'):
v = complex(value.replace('i', 'j'))
else:
raise ValueError()
for value in csv[1:]:
try:
v = float(value)
except ValueError:
value = value.lower()
try:
v = complex(value)
except Exception:
if value.endswith('i'):
v = complex(value.replace('i', 'j'))
else:
raise ValueError()
vs.append(v)
vs.append(v)
return Sample(ts, vs)
return Sample(ts, vs)
def __str__(self):
return '%s %s' % (self.ts, " ".join(map(str, self.values)))
def __str__(self):
return '%s %s' % (self.ts, " ".join(map(str, self.values)))
def __cmp__(self, other):
return cmp(self.ts, other.ts)
def __eq__(self, other):
return self.ts == other.ts
def __lt__(self, other):
return self.ts < other.ts