ITTV-tools / homeassistant-kostalplenticore

Home Assistant Component for Kostal Plenticore
MIT License
14 stars 6 forks source link

FR: enable setting minimal SOC of battery #8

Closed Caibuk closed 3 years ago

Caibuk commented 3 years ago

Let me first thank everyone involved for this wonderful plugin.

I'm using a Kostal Plenticore in combination with a BYD HVM battery. In addition I have two electric cars, that charge at night. As I have a electricity contract with high and low tariff times, I would like to spare some energy of the battery during the night to have enough left for the high tariff time in the morning (and avoid that the charging cars empty the battery). Right now I achieve this by manually setting the minimal SOC to 30 % in the webif (in the evening) and setting it back to 5 % in the morning.

I know from the Plenticore implementation for fhem (https://wiki.fhem.de/wiki/Kostal_Plenticore_10_Plus) that this "Battery_MinSoc" could be set using the web "api". As far as I understand is homeassistant-kostalplenticore using the same "api".

I would love to have this function in home assistant, too. Is there any way this could be added?

Sadly, I'm a total noob regarding coding. But I could be of some help for testing or providing access to my actual installation.

BR Markus

ITTV-tools commented 3 years ago

Hi Markus,

should be possible. Can you capture the API call in your browser, while changing it ? In Firefox press F12 -> Network analsysis -> change your value -> export the request (You should see your change in the request)

Lukas

Caibuk commented 3 years ago

Hi Lukas,

thank you for your response!

I hope, this is the thing you wanted ("request payload" for "Request URL": "http://10.0.1.37/api/v1/settings" in Chrome DevTools under the tab "Headers"):

[{"moduleid":"devices:local","settings":[{"id":"Battery:MinSoc","value":"15"}]}]

br Markus

ITTV-tools commented 3 years ago

Yes that looks good. Is it a GET or POST request ?

Caibuk commented 3 years ago

Sorry for the late reply. Request method is "PUT".

ITTV-tools commented 3 years ago

Perfect, Thanks. I will take a look at it.

ITTV-tools commented 3 years ago

I added the feature to the python module. I also thought about the implementation in HA and I guess the best solution will be to add a service. grafik I never added a service to HA so I need to play around a bit

Caibuk commented 3 years ago

Yes, that seems to be the best solution. One could use input_number and an automation then to set the corresponding value. The currently set MinSoc is provided using a sensor? Thanks much for your efforts!

ITTV-tools commented 3 years ago

Yes. I just added the sensors. You should see if you update to the new release.

Caibuk commented 3 years ago

Both additional sensors are working. Thank you! Did you implement the service to set the MinSoc already?

ITTV-tools commented 3 years ago

No, Im trying to figure out how to create the service with the same session to the inverter as the sensors. At the moment the integration is just a "sensor integration". All happens in one file. The authentication and the requests. To add the service. I need to add a new domain. That means the configuration in the configuration.yaml will change completely. Its then more like the mqtt integration.

Caibuk commented 3 years ago

Oh, I'm sorry for all the fuss my request is causing. Too bad I can't support you in the process, as this is way above my skills... Any way I can buy you a couple of beers/coffees?

ITTV-tools commented 3 years ago

There is a link in the readme file of the repo. I have an idea how you can realize the feature today. A little workaround, until I found a solution. https://github.com/ITTV-tools/kostalplenticorepy Use the module. Write a small script and use the python script integration: https://www.home-assistant.io/integrations/python_script/

The required function is con.setBatteryMinSoc()

Caibuk commented 3 years ago

Great! Thank you for your support. I will give it a try later today. 👍

Caibuk commented 3 years ago

Hallo @ITTV-tools, ich habe jetzt in HA die python_script-Integration aktiviert, kostalplenticore.py unter config/python_scripts abgelegt und in diesem Script PASSWD und self.BASE_URL mit meinen Werten gesetzt. In Entwicklerwerkzeuge/Dienste kann ich den Service python_script.kostalplenticore auswählen. Wie kann ich nun die Funktion con.setBatteryMinSoc() aufrufen und einen Wert übergeben? Da bin ich leider nicht kompetent genug ... 🙁

Grüße Markus

EDIT: die Funktion login muss ich natürlich vorher auch noch ausführen ...

ITTV-tools commented 3 years ago

Hallo Markus,

schau dir die Datei testreq.py an. https://github.com/ITTV-tools/kostalplenticorepy/blob/master/testreq.py Dort siehtst du wie die Funktionen ausgeführt werden. Das print davor brauchst du dafür eig garnicht. Den Wert kannst du übergeben, indem du die Zahl in die Kalmmern setzt. z.B. con.setBatteryMinSoc(30)

Das Modul (für den Import oben) müsste HA schon für die Integration heruntergeladen haben.

Grüße Lukas

Caibuk commented 3 years ago

Hallo Lukas,

nachdem ich jetzt eine Weile herumprobiert habe, habe ich auf https://www.home-assistant.io/integrations/python_script/ folgendes gelesen:

image

Es scheint also so nicht zu klappen. Man könnte das wahrscheinlich alles in ein Python-Script packen oder irgendwie mit AppDeamon machen - aber wie gesagt: da verlässt mich die Kunst ...

VG Markus

zaubererty commented 3 years ago

Bei bedarf kann ich bei der Implementierung des Services helfen. Ich habe das schon für die Go-eCharger gemacht oder verbessert.

Ich wäre auch froh um die Funktionalität.

ITTV-tools commented 3 years ago

Danke für das Anbebot. Sehr gerne.

Wenn ich das richtig verstehe wird der Service in der init.py Datei registriert. Mein Problem ist nur der Login am Inverter. Der ist momentan mit in der sensor.py, müsste aber auch in die init. Wie mache ich das am besten, dass ich einen Login für die Sensoren und den Service habe. In welche funktion passt das am besten und wie übergebe ich das Objekt (con) an andere Files/Bestandteile ?

zaubererty commented 3 years ago

@ITTV-tools Du kannst dir die Implementierung des Data Coordinators in meinem MYPV Projekt ansehen. Hier wird wie ein der Doku empfohlen eine Datencoordinations Klasse gebaut und dann in allen Komponenten auf die Instanz zu gegriffen. Den passenden Dokueintrag findest du hier: https://developers.home-assistant.io/docs/integration_fetching_data

By the way ein Umbau von Config-Eintrag auf UI-Config kannst du dort auch sehen.

ITTV-tools commented 3 years ago

@zaubererty Danke für die Tipps. Ich verstehe aber leider trotzdem nicht ganz wie ich das genau bei mir umsetzen kann. Ich habe ja keinen einheitlichen Requst für alle Sensoren. Sondern einzelne Requests pro Sensor und für den Service

Mein Code sieht momentan so aus: grafik

Das mit dem Config Flow habe ich schonmal mit den Basics für IP und Passwort hinbekommen. Ich habe den Login an der API jetzt einfach mal mit in die async_setup_entry. Sieht so aus als würde das funktionieren, aber laut dem Log ist das wohl nicht richtig so (evtl. weil der Aufruf nicht async ist ?) Wo genau muss ich meine Login funktionen aufrufen? (Einmal bei der Initiallisierung der Integration würde ja reichen. In eine Update Metode würde es also nicht reinpassen. ) Wie übergebe ich das Objekt für den Gebrauch an die Entities?

Danke im Vorraus Grüße Lukas

zaubererty commented 3 years ago

@ITTV-tools Hallo Lukas,

du kannst das Login in den Konstruktor (init) des Datacoordinators verlageren. Durch den Code wird der Coordinator überall zugreifbar.

# zum speichern des coordinators
hass.data[DOMAIN][entry.entry_id] = {
        DATA_COORDINATOR: coordinator,
    }

# zum Abruf des Coordinators
async def async_setup_entry(hass, entry, async_add_entities):
    """Add an MYPV entry."""
    coordinator: MYPVDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][
        DATA_COORDINATOR
    ]

Zum einen ist eine Referenz pro entitiy id gespeichert, was sin macht um mehre Instanzen der gleichen Integration laufen haben zu können. Mit dem Property Device Info kannst du die Sensoren auf eine integration grupieren.

class MYPVDataUpdateCoordinator(DataUpdateCoordinator):
    """Class to manage fetching MYPV data."""

    def __init__(self, hass: HomeAssistantType, *, config: dict, options: dict):
        """Initialize global MYPV data updater."""
        self._host = config[CONF_HOST]

Du hast ja im konstruktor alle Configinformationen in der Variable Config zur Verfügung, somit kannst du eintweder im "init" oder beim ersten Aufruf von "_async_update_data(self)" eine Verbindung aufbauen und in der Instanz speichern.

Ich würde dann noch umbauen, dass alle Sensorwerte (evtl. auch nur die konfigurierten) im coordinator abgefragt werden

Du kannst ja mal einen dev oder feature branch commiten, dann kann ich dir an den jeweiligen stellen die passenen änderungen Vorschlagen.

Gruss, Thomas

ITTV-tools commented 3 years ago

Hallo Thomas, dev branch habe ich erstellt, ebenso wie den coordinator. Beim initialisieren der Integration bekomme ich beim aufruf der API aber weiterhin: [homeassistant.util.async_] Detected I/O inside the event loop. This is causing stability issues. Please report issue for kostal_plenticore doing I/O at homeassistant/components/kostal_plenticore/coordinator.py, line 32: con.login()

Grüße Lukas

zaubererty commented 3 years ago

@ITTV-tools Hallo Lukas,

ich glaube der dev Branch ist unvollständig, zumindest sehe ich den coordinator nicht und die sensor Implementierung sieht mir auch ein wenig dünn aus.

Gruss, Thomas

ITTV-tools commented 3 years ago

@zaubererty Hi Thomas, jetzt sollte mehr da sein. Wäre super wenn du mir bei dem coorinator helfen könntest.

Grüße Lukas

ITTV-tools commented 3 years ago

In HA 2021.5 kommt eine offizielle integration. Da ist das feature drin, soweit ich gesehen habe