Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use url for json and http #2222

Merged
merged 1 commit into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/modules/http/api.py
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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