Skip to content

Commit

Permalink
Merge pull request #426 from LKuemmel/changes_snaptec_repo
Browse files Browse the repository at this point in the history
Changes snaptec repo
  • Loading branch information
LKuemmel committed May 31, 2022
2 parents edda3da + b5645cb commit 8a3e5f7
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 70 deletions.
2 changes: 1 addition & 1 deletion packages/modules/common/component_type.py
Expand Up @@ -18,7 +18,7 @@ def special_to_general_type_mapping(component_type: str) -> ComponentType:
elif "cp" in component_type:
return ComponentType.CHARGEPOINT
else:
raise TypeError(f"Typ {component_type} konnte keinem bekannten Komponenten-Typ zugeordnet werden.")
raise TypeError("Typ "+component_type+" konnte keinem bekannten Komponenten-Typ zugeordnet werden.")


def type_to_topic_mapping(component_type: str) -> str:
Expand Down
5 changes: 2 additions & 3 deletions packages/modules/fronius/device.py
Expand Up @@ -109,12 +109,11 @@ def read_legacy(
dev.update()
elif component_type == "inverter" and num:
inverter1 = inverter.FroniusInverter(num, component_config, dev.device_config.configuration)
if ip_address2 != "none":
device_config["configuration"]["ip_address"] = ip_address2
inverter2 = inverter.FroniusInverter(num, component_config, dev.device_config.configuration)
with SingleComponentUpdateContext(inverter1.component_info):
total_power = inverter1.read_power()
if ip_address2 != "none":
dev.device_config.configuration.ip_address = ip_address2
inverter2 = inverter.FroniusInverter(num, component_config, dev.device_config.configuration)
total_power += inverter2.read_power()
get_inverter_value_store(num).set(inverter1.fill_inverter_state(total_power))
else:
Expand Down
6 changes: 3 additions & 3 deletions packages/modules/http/api.py
Expand Up @@ -17,8 +17,8 @@ def request_value(url: str) -> Optional[float]:
return float(response.text.replace("\n", ""))


def create_request_function(domain: str, path: str) -> Callable[[], Optional[float]]:
if path == "none":
def create_request_function(url: str, path: str) -> Callable[[], Optional[float]]:
if path == "none" or path is None:
return lambda: 0
else:
return functools.partial(request_value, domain + path)
return functools.partial(request_value, url + path)
18 changes: 9 additions & 9 deletions packages/modules/http/bat.py
Expand Up @@ -12,20 +12,20 @@ def get_default_config() -> dict:
"id": 0,
"type": "bat",
"configuration": {
"power_path": "",
"imported_path": "none",
"exported_path": "none",
"soc_path": ""
"power_path": None,
"imported_path": None,
"exported_path": None,
"soc_path": None
}
}


class HttpBat:
def __init__(self, device_id: int, component_config: dict, domain: str) -> None:
self.__get_power = create_request_function(domain, component_config["configuration"]["power_path"])
self.__get_imported = create_request_function(domain, component_config["configuration"]["imported_path"])
self.__get_exported = create_request_function(domain, component_config["configuration"]["exported_path"])
self.__get_soc = create_request_function(domain, component_config["configuration"]["soc_path"])
def __init__(self, device_id: int, component_config: dict, url: str) -> None:
self.__get_power = create_request_function(url, component_config["configuration"]["power_path"])
self.__get_imported = create_request_function(url, component_config["configuration"]["imported_path"])
self.__get_exported = create_request_function(url, component_config["configuration"]["exported_path"])
self.__get_soc = create_request_function(url, component_config["configuration"]["soc_path"])

self.__device_id = device_id
self.component_config = component_config
Expand Down
22 changes: 11 additions & 11 deletions packages/modules/http/counter.py
Expand Up @@ -12,23 +12,23 @@ def get_default_config() -> dict:
"id": 0,
"type": "counter",
"configuration": {
"power_path": "",
"imported_path": "none",
"exported_path": "none",
"current_l1_path": "none",
"current_l2_path": "none",
"current_l3_path": "none",
"power_path": None,
"imported_path": None,
"exported_path": None,
"current_l1_path": None,
"current_l2_path": None,
"current_l3_path": None,
}
}


class HttpCounter:
def __init__(self, device_id: int, component_config: dict, domain: str) -> None:
self.__get_power = create_request_function(domain, component_config["configuration"]["power_path"])
self.__get_imported = create_request_function(domain, component_config["configuration"]["imported_path"])
self.__get_exported = create_request_function(domain, component_config["configuration"]["exported_path"])
def __init__(self, device_id: int, component_config: dict, url: str) -> None:
self.__get_power = create_request_function(url, component_config["configuration"]["power_path"])
self.__get_imported = create_request_function(url, component_config["configuration"]["imported_path"])
self.__get_exported = create_request_function(url, component_config["configuration"]["exported_path"])
self.__get_currents = [
create_request_function(domain,
create_request_function(url,
component_config["configuration"]["current_l" + str(i) + "_path"])
for i in range(1, 4)
]
Expand Down
73 changes: 53 additions & 20 deletions packages/modules/http/device.py
Expand Up @@ -3,8 +3,6 @@
import re
from typing import Dict, Union, List

from urllib3.util import parse_url

from helpermodules.cli import run_using_positional_cli_args
from modules.common.abstract_device import AbstractDevice
from modules.common.component_context import SingleComponentUpdateContext
Expand All @@ -21,13 +19,52 @@ def get_default_config() -> dict:
"type": "http",
"id": 0,
"configuration": {
"protocol": "http",
"domain": None,
"port": 80
"url": None
}
}


class HttpConfiguration:
def __init__(self, url: str):
self.url = url

@staticmethod
def from_dict(device_config: dict):
keys = ["url"]
try:
values = [device_config[key] for key in keys]
except KeyError as e:
raise Exception(
"Illegal configuration <{}>: Expected object with properties: {}".format(device_config, keys)
) from e
return HttpConfiguration(*values)


class Http:
def __init__(self, name: str, type: str, id: int, configuration: HttpConfiguration) -> None:
self.name = name
self.type = type
self.id = id
self.configuration = configuration

@staticmethod
def from_dict(device_config: dict):
keys = ["name", "type", "id", "configuration"]
try:
values = [device_config[key] for key in keys]
values = []
for key in keys:
if isinstance(device_config[key], Dict):
values.append(HttpConfiguration.from_dict(device_config[key]))
else:
values.append(device_config[key])
except KeyError as e:
raise Exception(
"Illegal configuration <{}>: Expected object with properties: {}".format(device_config, keys)
) from e
return Http(*values)


http_component_classes = Union[bat.HttpBat, counter.HttpCounter, inverter.HttpInverter]


Expand All @@ -41,20 +78,17 @@ class Device(AbstractDevice):
def __init__(self, device_config: dict) -> None:
self.components = {} # type: Dict[str, http_component_classes]
try:
self.device_config = device_config
port = self.device_config["configuration"]["port"]
self.domain = self.device_config["configuration"]["protocol"] + \
"://" + self.device_config["configuration"]["domain"]
if port is not None:
self.domain = self.domain + ":" + str(port)
self.device_config = device_config \
if isinstance(device_config, Http) \
else Http.from_dict(device_config)
except Exception:
log.exception("Fehler im Modul "+device_config["name"])

def add_component(self, component_config: dict) -> None:
component_type = component_config["type"]
if component_type in self.COMPONENT_TYPE_TO_CLASS:
self.components["component"+str(component_config["id"])] = self.COMPONENT_TYPE_TO_CLASS[component_type](
self.device_config["id"], component_config, self.domain)
self.device_config.id, component_config, self.device_config.configuration.url)
else:
raise Exception(
"illegal component type " + component_type + ". Allowed values: " +
Expand All @@ -70,7 +104,7 @@ def update(self) -> None:
self.components[component].update()
else:
log.warning(
self.device_config["name"] +
self.device_config.name +
": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden."
)

Expand Down Expand Up @@ -104,14 +138,13 @@ def run_device_legacy(device_config: dict, component_config: dict):


def create_legacy_device_config(url: str):
parsed_url = parse_url(url)
regex = re.compile("^(https?://[^/]+)(.*)")
match = regex.search(url)
if match is None:
raise Exception("Invalid URL <" + url + ">: Absolute HTTP or HTTPS URL required")
host_scheme = match.group(1)
device_config = get_default_config()
device_config["configuration"]["protocol"] = parsed_url.scheme
device_config["configuration"]["domain"] = parsed_url.hostname
if parsed_url.port is not None:
device_config["configuration"]["port"] = int(parsed_url.port)
else:
device_config["configuration"]["port"] = None
device_config["configuration"]["url"] = host_scheme
return device_config


Expand Down
10 changes: 5 additions & 5 deletions packages/modules/http/inverter.py
Expand Up @@ -14,16 +14,16 @@ def get_default_config() -> dict:
"id": 0,
"type": "inverter",
"configuration": {
"power_path": "",
"counter_path": "none",
"power_path": None,
"counter_path": None
}
}


class HttpInverter:
def __init__(self, device_id: int, component_config: dict, domain: str) -> None:
self.__get_power = create_request_function(domain, component_config["configuration"]["power_path"])
self.__get_counter = create_request_function(domain, component_config["configuration"]["counter_path"])
def __init__(self, device_id: int, component_config: dict, url: str) -> None:
self.__get_power = create_request_function(url, component_config["configuration"]["power_path"])
self.__get_counter = create_request_function(url, component_config["configuration"]["counter_path"])

self.__device_id = device_id
self.component_config = component_config
Expand Down
68 changes: 50 additions & 18 deletions packages/modules/json/device.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python3
import logging
from typing import Dict, List, Union, Optional
from urllib3.util import parse_url

from helpermodules.cli import run_using_positional_cli_args
from modules.common import req
Expand All @@ -20,13 +19,52 @@ def get_default_config() -> dict:
"type": "json",
"id": 0,
"configuration": {
"protocol": "http",
"domain": None,
"port": 80
"url": None
}
}


class JsonConfiguration:
def __init__(self, url: str):
self.url = url

@staticmethod
def from_dict(device_config: dict):
keys = ["url"]
try:
values = [device_config[key] for key in keys]
except KeyError as e:
raise Exception(
"Illegal configuration <{}>: Expected object with properties: {}".format(device_config, keys)
) from e
return JsonConfiguration(*values)


class Json:
def __init__(self, name: str, type: str, id: int, configuration: JsonConfiguration) -> None:
self.name = name
self.type = type
self.id = id
self.configuration = configuration

@staticmethod
def from_dict(device_config: dict):
keys = ["name", "type", "id", "configuration"]
try:
values = [device_config[key] for key in keys]
values = []
for key in keys:
if isinstance(device_config[key], Dict):
values.append(JsonConfiguration.from_dict(device_config[key]))
else:
values.append(device_config[key])
except KeyError as e:
raise Exception(
"Illegal configuration <{}>: Expected object with properties: {}".format(device_config, keys)
) from e
return Json(*values)


json_component_classes = Union[bat.JsonBat, counter.JsonCounter, inverter.JsonInverter]


Expand All @@ -40,19 +78,17 @@ class Device(AbstractDevice):
def __init__(self, device_config: dict) -> None:
self.components = {} # type: Dict[str, json_component_classes]
try:
self.device_config = device_config
port = self.device_config["configuration"]["port"]
self.domain = self.device_config["configuration"]["protocol"] + \
"://" + self.device_config["configuration"]["domain"] + \
":" + str(port) if port else ""
self.device_config = device_config \
if isinstance(device_config, Json) \
else Json.from_dict(device_config)
except Exception:
log.exception("Fehler im Modul "+device_config["name"])

def add_component(self, component_config: dict) -> None:
component_type = component_config["type"]
if component_type in self.COMPONENT_TYPE_TO_CLASS:
self.components["component"+str(component_config["id"])] = self.COMPONENT_TYPE_TO_CLASS[component_type](
self.device_config["id"], component_config)
self.device_config.id, component_config)
else:
raise Exception(
"illegal component type " + component_type + ". Allowed values: " +
Expand All @@ -63,26 +99,22 @@ def update(self) -> None:
log.debug("Start device reading " + str(self.components))
if self.components:
with MultiComponentUpdateContext(self.components):
response = req.get_http_session().get(self.domain, timeout=5)
response = req.get_http_session().get(self.device_config.configuration.url, timeout=5)
for component in self.components:
self.components[component].update(response.json())
else:
log.warning(
self.device_config["name"] +
self.device_config.name +
": Es konnten keine Werte gelesen werden, da noch keine Komponenten konfiguriert wurden."
)


def read_legacy(ip_address: str, component_config: dict, num: Optional[int] = None, **kwargs) -> None:
def read_legacy(url: str, component_config: dict, num: Optional[int] = None, **kwargs) -> None:
component_config["configuration"].update(kwargs)
component_config["id"] = num

parsed_url = parse_url(ip_address)
device_config = get_default_config()
device_config["configuration"]["protocol"] = parsed_url.scheme
device_config["configuration"]["domain"] = parsed_url.hostname
device_config["configuration"]["port"] = int(parsed_url.port)

device_config["configuration"]["url"] = url
dev = Device(device_config)
dev.add_component(component_config)
dev.update()
Expand Down

0 comments on commit 8a3e5f7

Please sign in to comment.