diff --git a/.bumpversion-edge.toml b/.bumpversion-edge.toml index dc0502b..2314bf8 100644 --- a/.bumpversion-edge.toml +++ b/.bumpversion-edge.toml @@ -1,5 +1,5 @@ [tool.bumpversion] -current_version = "2.8.4" +current_version = "2.8.5" parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)" serialize = ["{major}.{minor}.{patch}"] search = "{current_version}" diff --git a/GridboxConnectorAddon-dev/CHANGELOG.md b/GridboxConnectorAddon-dev/CHANGELOG.md index 036d2bb..ccd67c0 100644 --- a/GridboxConnectorAddon-dev/CHANGELOG.md +++ b/GridboxConnectorAddon-dev/CHANGELOG.md @@ -1,4 +1,45 @@ +## 2.8.4 + +### 🚀 Added + +- sensitive filter + +## 2.8.0 + +### 🚀 Added + +- Heaters with Temperature and power + +### 🔨 Fixed + +- does not show anymore credentials in log + +## 2.7.6 + +### 🔨 Fixed + +- if list of values is empty refresh token + +## 2.7.5 + +### 🔨 Fixed + +- Rounded to 2 decimal places + +## 2.7.3 + +### 🔨 Fixed + +- loading config.json +- check response length + +## 2.7.0 + +### 🚀 Added + +- heaters Consumption +- standalone container ## 2.6.3 diff --git a/GridboxConnectorAddon-dev/GridboxConnector/__main__.py b/GridboxConnectorAddon-dev/GridboxConnector/__main__.py index fe4aea1..4f8c43b 100644 --- a/GridboxConnectorAddon-dev/GridboxConnector/__main__.py +++ b/GridboxConnectorAddon-dev/GridboxConnector/__main__.py @@ -6,7 +6,8 @@ from ha_viessmann_gridbox_connector import HAViessmannGridboxConnector import logging from importlib.resources import files - +from utils import SensitiveDataFilter +opens_file_path = '/data/options.json' #logging.basicConfig(format='%(asctime)s %(filename)s:%(lineno)d %(levelname)s - %(message)s', level=logging.getLevelName(os.getenv('LOG_LEVEL', 'INFO'))) logger = logging.getLogger(__name__) logger.setLevel(logging.getLevelName(os.getenv('LOG_LEVEL', 'INFO'))) @@ -14,6 +15,8 @@ console_handler = logging.StreamHandler() console_handler.setFormatter(formatter) logger.addHandler(console_handler) +# Benutzerdefinierten Filter zum Logger hinzufügen +logger.addFilter(SensitiveDataFilter()) def load_gridbox_config(): config_file = files('viessmann_gridbox_connector').joinpath('config.json') @@ -21,15 +24,16 @@ def load_gridbox_config(): data = json.load(json_file) return data - -if __name__ == '__main__': - +def run_addon(): gridbox_config = load_gridbox_config() - + options_file = '' + WAIT = int(os.getenv('WAITTIME', "60")) + if os.path.exists(opens_file_path): + options_file = open(opens_file_path) + options_json = json.load(options_file) + WAIT = int(options_json["wait_time"]) + - options_file = open('/data/options.json') - options_json = json.load(options_file) - WAIT = int(options_json["wait_time"]) USER = os.getenv('USERNAME', "") PASSWORD = os.environ.get('PASSWORD', "") mqtt_user = os.getenv('MqttUser', "") @@ -46,15 +50,23 @@ def load_gridbox_config(): gridbox_config["login"]["password"] = PASSWORD logger.debug(gridbox_config["login"]) one_time_print = True - mqtt_settings = Settings.MQTT(host=mqtt_server, username=mqtt_user, password=mqtt_pw) + mqtt_settings = Settings.MQTT(host=mqtt_server, username=mqtt_user, password=mqtt_pw, port=mqtt_port) viessmann_gridbox_connector = HAViessmannGridboxConnector(mqtt_settings) gridboxConnector = GridboxConnector(gridbox_config) while True: measurement = gridboxConnector.retrieve_live_data() - result = measurement[0] - viessmann_gridbox_connector.update_sensors(result) - if one_time_print or logger.level == logging.DEBUG: - logger.info(result) - one_time_print = False - # Wait until fetch new values in seconds + if len(measurement) > 0: + result = measurement[0] + viessmann_gridbox_connector.update_sensors(result) + if one_time_print or logger.level == logging.DEBUG: + logger.info(result) + one_time_print = False + # Wait until fetch new values in seconds + else: + logger.warning("No data received") + gridboxConnector.init_auth() time.sleep(WAIT) + +if __name__ == '__main__': + run_addon() + #run_test_log() \ No newline at end of file diff --git a/GridboxConnectorAddon-dev/GridboxConnector/ha_viessmann_gridbox_connector.py b/GridboxConnectorAddon-dev/GridboxConnector/ha_viessmann_gridbox_connector.py index 07eb732..2baf7d1 100644 --- a/GridboxConnectorAddon-dev/GridboxConnector/ha_viessmann_gridbox_connector.py +++ b/GridboxConnectorAddon-dev/GridboxConnector/ha_viessmann_gridbox_connector.py @@ -2,6 +2,7 @@ from ha_mqtt_discoverable.sensors import Sensor, SensorInfo from ha_viessmann_battery import HAViessmannBattery from ha_viessmann_ev_charging_station import HAViessmannEVChargingStation +from ha_viessmann_heater import HAViessmannHeater class HAViessmannGridboxConnector: @@ -16,11 +17,13 @@ class HAViessmannGridboxConnector: direct_consumption_household_sensor: Sensor direct_consumption_heatpump_sensor: Sensor direct_consumption_ev_sensor: Sensor + direct_consumption_heater_sensor: Sensor direct_consumption_rate_sensor: Sensor self_supply_sensor: Sensor self_consumtion_rate_sensor: Sensor self_sufficiency_rate_sensor: Sensor battery_sum: HAViessmannBattery + heater_sensor: HAViessmannHeater def __init__(self, mqtt_settings): self.battery_sensor_dict = {} @@ -76,13 +79,11 @@ def __init__(self, mqtt_settings): self.photovoltaic_sensor = Sensor(photovoltaic_settings) # Battery sum - self.battery_sum = HAViessmannBattery( - mqtt_settings, self.device_info, "sum", "") - + self.battery_sum = HAViessmannBattery(mqtt_settings, self.device_info, "sum", "") + self.heater_sensor = HAViessmannHeater(mqtt_settings, self.device_info, "", "") # EV - self.ev_sum = HAViessmannEVChargingStation( - mqtt_settings, self.device_info, "sum", "") + self.ev_sum = HAViessmannEVChargingStation(mqtt_settings, self.device_info, "sum", "") # Consumption self.consumption_household_sensor = Sensor(consumption_household_settings) @@ -114,14 +115,14 @@ def update_sensors(self, measurement: dict): if "directConsumptionEV" in measurement: self.direct_consumption_ev_sensor.set_state(float(measurement.get("directConsumptionEV", "0"))) if "directConsumptionRate" in measurement: - self.direct_consumption_rate_sensor.set_state(float(measurement.get("directConsumptionRate", "0"))*100) + self.direct_consumption_rate_sensor.set_state(round(float(measurement.get("directConsumptionRate", "0"))*100,2)) if "selfSupply" in measurement: self.self_supply_sensor.set_state(float(measurement.get("selfSupply", ""))) if "selfConsumptionRate" in measurement: - self.self_consumtion_rate_sensor.set_state(float(measurement.get("selfConsumptionRate", "0"))*100) + self.self_consumtion_rate_sensor.set_state(round(float(measurement.get("selfConsumptionRate", "0"))*100,2)) if "selfSufficiencyRate" in measurement: - self.self_sufficiency_rate_sensor.set_state(float(measurement.get("selfSufficiencyRate", "0"))*100) + self.self_sufficiency_rate_sensor.set_state(round(float(measurement.get("selfSufficiencyRate", "0"))*100,2)) if "battery" in measurement: battery: dict = measurement.get("battery", {}) @@ -144,6 +145,14 @@ def update_sensors(self, measurement: dict): remaining_charge = float(battery.get("remainingCharge", "0")) battery_sensor.set_states(state_of_charge, capacity, power, remaining_charge) + if "heaters" in measurement: + heaters: list = measurement.get("heaters", []) + heater = heaters[0] + appliance_id = heater.get("applianceID", "") + power = round(float(heater.get("power", "0")),0) + temperature = round(float(heater.get("temperature", "0")),1) + self.heater_sensor.set_states(power, temperature) + if "evChargingStation" in measurement: ev_charging_station: dict = measurement.get("evChargingStation", {}) power = float(ev_charging_station.get("power", "0")) diff --git a/GridboxConnectorAddon-dev/GridboxConnector/ha_viessmann_heater.py b/GridboxConnectorAddon-dev/GridboxConnector/ha_viessmann_heater.py new file mode 100644 index 0000000..20bdbbd --- /dev/null +++ b/GridboxConnectorAddon-dev/GridboxConnector/ha_viessmann_heater.py @@ -0,0 +1,31 @@ +from ha_mqtt_discoverable.sensors import Sensor, SensorInfo +from ha_mqtt_discoverable import Settings, DeviceInfo + + +class HAViessmannHeater: + def __init__(self, mqtt_settings, device_info, name, id): + self.id: str = id + self.name: str = name + self.device_info: DeviceInfo = device_info + self.mqtt_settings: Settings.MQTT = mqtt_settings + + self.heater_sensor_power = SensorInfo( + name=f"Heater {name} Power", device_class="energy", unique_id=f"gridbox_heater_power_{name}", device=device_info, unit_of_measurement="W") + self.heater_power_settings = Settings( + mqtt=mqtt_settings, entity=self.heater_sensor_power) + self.heater_power = Sensor(self.heater_power_settings) + + self.heater_sensor_temperature = SensorInfo( + name=f"Heater {name} Temperature", device_class="temperature", unique_id=f"gridbox_heater_temperature_{name}", device=device_info, unit_of_measurement="C") + self.heater_temperature_settings = Settings( + mqtt=mqtt_settings, entity=self.heater_sensor_temperature) + self.heater_temperature = Sensor(self.heater_temperature_settings) + + + def get_name(self): + return self.name + + def set_states(self, power, temperature): + self.heater_power.set_state(power) + self.heater_temperature.set_state(temperature) + diff --git a/GridboxConnectorAddon-dev/GridboxConnector/tests/mock_data/mock_data_with_heater.json b/GridboxConnectorAddon-dev/GridboxConnector/tests/mock_data/mock_data_with_heater.json new file mode 100644 index 0000000..d02043e --- /dev/null +++ b/GridboxConnectorAddon-dev/GridboxConnector/tests/mock_data/mock_data_with_heater.json @@ -0,0 +1,45 @@ +{ + "batteries": [ + { + "applianceID": "a1731af4-0399-495b-92c2-523fd61ab681", + "capacity": 10000, + "nominalCapacity": 10000, + "power": -102, + "remainingCharge": 10000, + "stateOfCharge": 1 + } + ], + "battery": { + "capacity": 10000, + "nominalCapacity": 10000, + "power": -102, + "remainingCharge": 10000, + "stateOfCharge": 1 + }, + "consumption": 847, + "directConsumption": 4523, + "directConsumptionEV": 0, + "directConsumptionHeatPump": 0, + "directConsumptionHeater": 3676, + "directConsumptionHousehold": 847, + "directConsumptionRate": 0.5465200579990334, + "grid": -3651, + "gridMeterReadingNegative": 5630400000, + "gridMeterReadingPositive": 5344920000, + "heaters": [ + { + "applianceID": "12bdd8ec-9b1e-465e-8f26-feae00e5af0f", + "power": 3676, + "temperature": 70.9 + } + ], + "heating": 3676, + "measuredAt": "2024-07-12T12:52:47Z", + "photovoltaic": 8276, + "production": 8276, + "selfConsumption": 4625, + "selfConsumptionRate": 0.5588448525857902, + "selfSufficiencyRate": 1, + "selfSupply": 4523, + "totalConsumption": 4523 +} diff --git a/GridboxConnectorAddon-dev/GridboxConnector/utils.py b/GridboxConnectorAddon-dev/GridboxConnector/utils.py new file mode 100644 index 0000000..b42b25b --- /dev/null +++ b/GridboxConnectorAddon-dev/GridboxConnector/utils.py @@ -0,0 +1,26 @@ +import json +import logging +import ast +class SensitiveDataFilter(logging.Filter): + def filter(self, record): + message = record.getMessage() + try: + literal_msg = ast.literal_eval(message) + # Sensible Daten filtern, falls vorhanden + if 'username' in literal_msg: + literal_msg['username'] = '***' + if 'password' in literal_msg: + literal_msg['password'] = '***' + if 'id_token' in literal_msg: + literal_msg['id_token'] = '***' + if 'access_token' in literal_msg: + literal_msg['access_token'] = '***' + if 'client_id' in literal_msg: + literal_msg['client_id'] = '***' + # Das modifizierte Dictionary zurück in einen String konvertieren + record.msg = json.dumps(literal_msg) + except json.JSONDecodeError: + # Wenn die Nachricht kein JSON ist, nichts tun + logging.error('Could not parse message as JSON') + pass + return True \ No newline at end of file diff --git a/GridboxConnectorAddon-dev/cloudSettings.json b/GridboxConnectorAddon-dev/cloudSettings.json index ad275f4..5928089 100644 --- a/GridboxConnectorAddon-dev/cloudSettings.json +++ b/GridboxConnectorAddon-dev/cloudSettings.json @@ -1,5 +1,5 @@ { - "version": "2.6.3", + "version": "2.8.5", "urls": { "login": "https://gridx.eu.auth0.com/oauth/token", "gateways": "https://api.gridx.de/gateways", diff --git a/GridboxConnectorAddon-dev/config.yaml b/GridboxConnectorAddon-dev/config.yaml index 518411e..d940576 100644 --- a/GridboxConnectorAddon-dev/config.yaml +++ b/GridboxConnectorAddon-dev/config.yaml @@ -1,6 +1,6 @@ # https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config name: Viessmann Gridbox Connector (dev) -version: "2.6.3" +version: "2.8.4" slug: "gridbox_connector_dev" description: Development version of Viessmann Gridbox Connector url: "https://github.com/unl0ck/homeassistant-addon-viessmann-gridbox/tree/main/GridboxConnectorAddon-dev" diff --git a/GridboxConnectorAddon-dev/rootfs/etc/s6-overlay/s6-rc.d/gridboxconnector/run b/GridboxConnectorAddon-dev/rootfs/etc/s6-overlay/s6-rc.d/gridboxconnector/run index 6f6f7a4..99d50e3 100755 --- a/GridboxConnectorAddon-dev/rootfs/etc/s6-overlay/s6-rc.d/gridboxconnector/run +++ b/GridboxConnectorAddon-dev/rootfs/etc/s6-overlay/s6-rc.d/gridboxconnector/run @@ -20,7 +20,6 @@ export USERNAME=$(bashio::config 'username') export PASSWORD=$(bashio::config 'password') export LOG_LEVEL=$(bashio::config 'log_level') ls -lash /data -cat /data/options.json cd /build/ ls -lash pwd diff --git a/GridboxConnectorAddon-dev/rootfs/share/cloudSettings.json b/GridboxConnectorAddon-dev/rootfs/share/cloudSettings.json index ad275f4..5928089 100644 --- a/GridboxConnectorAddon-dev/rootfs/share/cloudSettings.json +++ b/GridboxConnectorAddon-dev/rootfs/share/cloudSettings.json @@ -1,5 +1,5 @@ { - "version": "2.6.3", + "version": "2.8.5", "urls": { "login": "https://gridx.eu.auth0.com/oauth/token", "gateways": "https://api.gridx.de/gateways", diff --git a/GridboxConnectorAddon-dev/rootfs/usr/bin/gridboxconnector.sh b/GridboxConnectorAddon-dev/rootfs/usr/bin/gridboxconnector.sh index 3a32a5b..ea3ecc8 100755 --- a/GridboxConnectorAddon-dev/rootfs/usr/bin/gridboxconnector.sh +++ b/GridboxConnectorAddon-dev/rootfs/usr/bin/gridboxconnector.sh @@ -13,7 +13,6 @@ export USERNAME=$(bashio::config 'username') export PASSWORD=$(bashio::config 'password') export LOG_LEVEL=$(bashio::config 'log_level') ls -lash /data -cat /data/options.json cd /build/ ls -lash pwd diff --git a/GridboxConnectorAddon-edge/CHANGELOG.md b/GridboxConnectorAddon-edge/CHANGELOG.md index 84738c9..ccd67c0 100644 --- a/GridboxConnectorAddon-edge/CHANGELOG.md +++ b/GridboxConnectorAddon-edge/CHANGELOG.md @@ -1,5 +1,5 @@ -## 2.8.2 +## 2.8.4 ### 🚀 Added diff --git a/GridboxConnectorAddon-edge/GridboxConnector/ha_viessmann_gridbox_connector.py b/GridboxConnectorAddon-edge/GridboxConnector/ha_viessmann_gridbox_connector.py index 3058d76..2baf7d1 100644 --- a/GridboxConnectorAddon-edge/GridboxConnector/ha_viessmann_gridbox_connector.py +++ b/GridboxConnectorAddon-edge/GridboxConnector/ha_viessmann_gridbox_connector.py @@ -79,13 +79,11 @@ def __init__(self, mqtt_settings): self.photovoltaic_sensor = Sensor(photovoltaic_settings) # Battery sum - self.battery_sum = HAViessmannBattery( - mqtt_settings, self.device_info, "sum", "") - + self.battery_sum = HAViessmannBattery(mqtt_settings, self.device_info, "sum", "") + self.heater_sensor = HAViessmannHeater(mqtt_settings, self.device_info, "", "") # EV - self.ev_sum = HAViessmannEVChargingStation( - mqtt_settings, self.device_info, "sum", "") + self.ev_sum = HAViessmannEVChargingStation(mqtt_settings, self.device_info, "sum", "") # Consumption self.consumption_household_sensor = Sensor(consumption_household_settings) @@ -149,15 +147,11 @@ def update_sensors(self, measurement: dict): if "heaters" in measurement: heaters: list = measurement.get("heaters", []) - for heater in heaters: - appliance_id = heater.get("applianceID", "") - if self.heater_sensor is None: - self.heater_sensor = HAViessmannHeater(self.mqtt_settings, self.device_info, "", appliance_id) - - power = round(float(heater.get("power", "0")),0) - temperature = round(float(heater.get("temperature", "0")),1) - self.heater_sensor.set_states(power, temperature) - + heater = heaters[0] + appliance_id = heater.get("applianceID", "") + power = round(float(heater.get("power", "0")),0) + temperature = round(float(heater.get("temperature", "0")),1) + self.heater_sensor.set_states(power, temperature) if "evChargingStation" in measurement: ev_charging_station: dict = measurement.get("evChargingStation", {}) diff --git a/GridboxConnectorAddon-edge/cloudSettings.json b/GridboxConnectorAddon-edge/cloudSettings.json index dc30e01..5928089 100644 --- a/GridboxConnectorAddon-edge/cloudSettings.json +++ b/GridboxConnectorAddon-edge/cloudSettings.json @@ -1,5 +1,5 @@ { - "version": "2.8.4", + "version": "2.8.5", "urls": { "login": "https://gridx.eu.auth0.com/oauth/token", "gateways": "https://api.gridx.de/gateways", diff --git a/GridboxConnectorAddon-edge/config.yaml b/GridboxConnectorAddon-edge/config.yaml index 4a7d9a0..c2c4b2c 100644 --- a/GridboxConnectorAddon-edge/config.yaml +++ b/GridboxConnectorAddon-edge/config.yaml @@ -1,7 +1,7 @@ # https://developers.home-assistant.io/docs/add-ons/configuration#add-on-config --- name: Viessmann Gridbox Connector (edge) -version: "2.8.4" +version: "2.8.5" slug: "gridbox_connector_edge" description: "Viessmann Gridbox Connector (edge)" url: "https://github.com/unl0ck/homeassistant-addon-viessmann-gridbox/tree/main/GridboxConnectorAddon-edge" diff --git a/GridboxConnectorAddon-edge/rootfs/share/cloudSettings.json b/GridboxConnectorAddon-edge/rootfs/share/cloudSettings.json index dc30e01..5928089 100644 --- a/GridboxConnectorAddon-edge/rootfs/share/cloudSettings.json +++ b/GridboxConnectorAddon-edge/rootfs/share/cloudSettings.json @@ -1,5 +1,5 @@ { - "version": "2.8.4", + "version": "2.8.5", "urls": { "login": "https://gridx.eu.auth0.com/oauth/token", "gateways": "https://api.gridx.de/gateways", diff --git a/copy_to_dev.sh b/copy_to_dev.sh index 3a0c7f1..52a3cf9 100755 --- a/copy_to_dev.sh +++ b/copy_to_dev.sh @@ -8,12 +8,13 @@ target_dir="GridboxConnectorAddon-dev" rsync -av --delete --exclude='config.yaml' --exclude='build.yaml' --exclude='__pycache__' --exclude='.pytest_cache' $src_dir/ $target_dir/ yaml_datei="GridboxConnectorAddon-dev/config.yaml" -current_version=$(yq e '.version' $yaml_datei) +current_version=$(yq -e '.version' $yaml_datei) echo "Current version: $current_version" new_version=$(jq -r '.version' GridboxConnectorAddon-dev/rootfs/share/cloudSettings.json) echo "New version: $new_version" # Update the version in the config.yaml file -# sed -i "s/version: \"$current_version\"/version: \"$new_version\"/g" $yaml_datei -sed -i "" "s/version: \"$current_version\"/version: \"$new_version\"/g" $yaml_datei \ No newline at end of file +#sed -i "s/version: \"$current_version\"/version: \"$new_version\"/g" $yaml_datei +#sed -i "" "s/version: \"$current_version\"/version: \"$new_version\"/g" $yaml_datei +sed -i "s/version: \"$current_version\"/version: \"$new_version\"/g" $yaml_datei \ No newline at end of file