evcc-io / evcc

Sonne tanken ☀️🚘
https://evcc.io
MIT License
3.3k stars 602 forks source link

"integrated vehicle" sollte an anderen Loadpoints nicht auswählbar sein #11023

Closed VolkerK62 closed 7 months ago

VolkerK62 commented 9 months ago

Angeregt durch https://github.com/evcc-io/evcc/discussions/11019 habe ich etwas ausprobiert.

Ich habe 4 Loadpoints und 4 Vehicle. 3 Vehicle sind je einem Loadpoint fest zugewiesen und die entsprechenden Charger mit dem feature: integrateddevice versehen.

Am Loadpoint der Wallbox gibt es kein zugewiesenes Vehicle. Dort werden in der Auswahlliste alle Vehicle angezeigt. Wenn ich nun dort eines der andernorts fest zugewiesenen Fahrzeuge auswähle, wird es offensichlich am ursprünglichen Loadpoint entfernt (die Soc Anzeige verändert sich). Da bei integrateddevice keine Vehicleliste verfügbar ist, kann ich das nur durch einen Neustart wieder richtigstellen.

Meiner Erwartung wäre, das "integrated vehicle" an anderen Loadpoints nicht auswählbar sind bzw. gar nicht angezeigt werden.

andig commented 9 months ago

Das ist ein interessanter Punkt.

Wenn ich nun dort eines der andernorts fest zugewiesenen Fahrzeuge auswähle, wird es offensichlich am ursprünglichen Loadpoint entfernt (die Soc Anzeige verändert sich).

Ich bin aber ein bisschen verwirrt: wie kann ein integrateddevice (das per Definition kein Fahrzeug hat) ein zugewiesenes Fahrzeug haben? Was wäre das in der Realität? Ich wäre eher versucht, diesen Konfigurationsfehler abzustellen?

/cc @naltatis

naltatis commented 9 months ago

Ja, ich hätte auch erwartet, dass wir bei integrateddevice gar kein Fahrzeug akzeptieren. Weder in Konfiguration noch via API.

VolkerK62 commented 9 months ago

OK, dann habe eine Regelungslücke genutzt Ich wollte halt auch den Soc haben.

Charger:

- name: E-Bikes
  type: template
  template: shelly
  ##Shelly Plug-S in Garage
  host: 192.168.178.83
  standbypower: 10
  integrateddevice: true
  icon: bike

Vehicle:

- name: bike
  type: custom
  title: E-Bikes
  icon: bike
  capacity: 0.625
  phases: 1
  soc:
    source: mqtt
    topic: haus/mqtt/bike_soc
    timeout: 25h

Loadpoint:

- title: E-Bikes
  charger: E-Bikes
  vehicle: bike
  mode: pv
  phases: 1
  mincurrent: 0.75
  maxcurrent: 0.75
  priority: 5
  soc:
    estimate: true
  enable:
    delay: 30s
  disable:
    delay: 5m
  guardduration: 5m
naltatis commented 9 months ago

Welchen Vorteil hat denn integrateddevice: true dann in diesem Szenario für dich? Eine alternative/kompakte Darstellung haben wir ja bislang noch nicht bzw. nur minimal umgesetzt.

VolkerK62 commented 9 months ago

Vorteil? Eigentlich keinen. Ich könnte integrateddevice auch rausnehmen, dann wäre das oben beschriebene Problem ohne Neustart lösbar. Gedanke bei der Umsetzung war/ist, das es eine zusammengehörige Einheit ist und eine Vehicle-Auswahl somit unnötig. Die gleiche Kombi habe ich auch mit meiner Wärmepumpe konfiguriert.

andig commented 9 months ago

Das Kernrequirement hier ist doch eigentlich, beliebige Funktionen zu einem bestehenden Device zu "dekorieren". Das Fahrzeug "dekoriert" hier den SoC. Schön wäre ja sowas in der Art- damit verschwindet der Bedarf des zusätzlichen Vehicles:

- name: E-Bikes
  type: template
  template: shelly # Shelly Plug-S in Garage
  host: 192.168.178.83
  standbypower: 10
  integrateddevice: true
  icon: bike
  decorate:
    soc:
      source: mqtt
      topic: haus/mqtt/bike_soc
      timeout: 25h

Leider ist das nicht ganz so trivial generisch in Go zu machen.

VolkerK62 commented 9 months ago

Ja, das wäre der Mercedes 😄 Aber, ich kann mit der aktuellen Umsetzung gut leben. Das Eingangsproblem war konstruiert, da ich normalerweise kein Fahrzeug auswählen muss. Wollte aber trotzdem auf dieses Verhalten hinweisen. Mein erster Gedanke war, wenn "integrateddevice=true" und "Vehicle dem Loadpoint zugewiesen" dann Fahrzeug "unsichtbar".

VolkerK62 commented 9 months ago

Mein erster Gedanke war, wenn "integrateddevice=true" und "Vehicle dem Loadpoint zugewiesen" dann Fahrzeug "unsichtbar".

oder evtl noch einfacher. features: ["unvisible"] beim vehicle. Dann wird es im UI nicht angezeigt. @MarkusGH wäre das auch für dich eine Lösung?

MarkusGH commented 9 months ago

Das Kernrequirement hier ist doch eigentlich, beliebige Funktionen zu einem bestehenden Device zu "dekorieren". Das Fahrzeug "dekoriert" hier den SoC. Schön wäre ja sowas in der Art- damit verschwindet der Bedarf des zusätzlichen Vehicles:

Ich bin mir nicht sicher, ob das meinen use case abdecken würde. Denn ich hätte schon gerne den Namen des "vehicle" im UI und in der Liste der Ladevorgänge.

naltatis commented 9 months ago

Die aktuelle Planung ist, dass wir für Integrated Device Ladepunkte keine Ladevorgänge im klassischen Sinne speichern, da diese Ladepunkt auch so etwas wie ein Einstecken/Ausstecken nicht haben. Klassische Beispiele wäre hier Heizstab, Wärmepumpe, Steckdose mit festem Verbraucher. Diese Ladepunkte wären eher ein Kandidat für zeitabhängige Statistiken (Energie pro Tag, ...).

Das was hier ja gewünscht ist, geht eher in die Richtung eines klassichen Ladepunkts mit mehr Customizing Möglichkeiten, oder?

Siehe Konzept: https://github.com/evcc-io/evcc/discussions/7235 Der Plan ist bislang, dass die "Mini" Spalte im Konzept dem "Integrated Device" entspricht.

MarkusGH commented 9 months ago

Mein erster Gedanke war, wenn "integrateddevice=true" und "Vehicle dem Loadpoint zugewiesen" dann Fahrzeug "unsichtbar".

Das würde mir nicht helfen.

oder evtl noch einfacher. features: ["unvisible"] beim vehicle. Dann wird es im UI nicht angezeigt. @MarkusGH wäre das auch für dich eine Lösung?

Wenn das Vehicle damit nur aus den Auswahllisten für Fahrzeuge verschwindet wäre mir damit geholfen. Super wäre noch wenn man dann noch die Fahrzeugauswahlliste ohne weiteren Verlust an Funktionalität pro loadpoint deaktivieren könnte.

MarkusGH commented 9 months ago

Die aktuelle Planung ist, dass wir für Integrated Device Ladepunkte keine Ladevorgänge im klassischen Sinne speichern, da diese Ladepunkt auch so etwas wie ein Einstecken/Ausstecken nicht haben. Klassische Beispiele wäre hier Heizstab, Wärmepumpe, Steckdose mit festem Verbraucher. Diese Ladepunkte wären eher ein Kandidat für zeitabhängige Statistiken (Energie pro Tag, ...).

Mindestens bei der Wärmepumpe ist es nicht unbedingt schlecht, die einzelnen Vorgänge zu sehen.

Das was hier ja gewünscht ist, geht eher in die Richtung eines klassichen Ladepunkts mit mehr Customizing Möglichkeiten, oder?

Das ist dem Grunde nach das, was ich in https://github.com/evcc-io/evcc/discussions/11019 angefragt habe. Was VolkerK62 hier anfragt ist nach meinem Verständnis etwas spezifischer (wäre für meinen use case auch vom Ansatz her nicht ganz passend).

andig commented 9 months ago

Ich fasse nochmal zusammen. Zwei unterschiedliche Cases:

Verwendung von "Fahrzeugen" um...

Ist das so richtig?

VolkerK62 commented 9 months ago

Ist für mich richtig.

MarkusGH commented 9 months ago

Für mich (wahrscheinlich) auch richtig. Ich weiß nicht genau was Dir vorschwebt.

Ich teile unten mal meine Konfiguration und das Ergebnis. Zum Verständnis:

Momentan muss ich "Pseudovehicles" mit entsprechenden identifiern anlegen und kann features: [integrateddevice] nicht nutzen, da dann identify nicht aufgerufen wird. Wenn man den charger z. B. mit einer Funktion zum Abrufen des vehicleTitle dekorieren könnte, die auch bei einem charger mit features: [integrateddevice] gerufen wird wäre das tatsächlich einfacher.

javascript:
  - vm: shared
    script: |
      state = {
        heatpump: {
          enabled: false,
          maxpower: 0,
          mode: 0,
          power: 0,
          vehicle: ""
        }
      };
      function setMaxCurrent(maxcurrent) {
        state.heatpump.maxpower = ~~(maxcurrent * 230);
        return state.heatpump.enabled ? state.heatpump.maxpower : 0;
      }
      function getStatus() {
        if (state.heatpump.enabled && state.heatpump.power > 0) {
          return "C";
        } else if (state.heatpump.mode != 0 || state.heatpump.power > 0) {
          return "B";
        } else {
          return "A";
        }
      }
      function getSoc(modulation) {
        return Math.min(Math.max(0.1, modulation),99.9);
      }

meters:
- name: heatpump
  type: custom
  power:
    source: js
    vm: shared
    script: |
      state.heatpump.power;

chargers:
- name: heatpump
  type: custom
  # features: [integrateddevice]
  icon: waterheater
  enable:
    source: js
    vm: shared
    script: |
      state.heatpump.enabled = enable;
      if (state.heatpump.enabled) state.heatpump.maxpower; else 0;
    out:
      - name: maxpower
        type: int
        config:
          source: mqtt
          topic: canathome/pvmanager/heatingMaxPower
          payload: ${maxpower:%d}
  enabled:
    source: js
    vm: shared
    script: |
      state.heatpump.enabled;
  status:
    source: js
    vm: shared
    script: |
      state.heatpump.mode = mode;
      state.heatpump.power = power;
      if (state.heatpump.vehicle == vehicle) {
        getStatus();
      } else {
        state.heatpump.vehicle = vehicle;
        "A";
      }
    in:
      - name: mode
        type: int
        config:
          source: mqtt
          topic: canathome/pvmanager/mode
          timeout: 0s
      - name: power
        type: int
        config:
          source: mqtt
          topic: canathome/pvmanager/heatPumpPower
          timeout: 60s
      - name: vehicle
        type: string
        config:
          source: mqtt
          topic: canathome/pvmanager/heatPumpMode
          timeout: 0s
  maxcurrent:
    source: js
    vm: shared
    script: |
      setMaxCurrent(maxcurrent);
    out:
      - name: maxpower
        type: int
        config:
          source: mqtt
          topic: canathome/pvmanager/heatingMaxPower
          payload: ${maxpower:%d}
  maxcurrentmillis:
    source: js
    vm: shared
    script: |
      setMaxCurrent(maxcurrentmillis);
    out:
      - name: maxpower
        type: int
        config:
          source: mqtt
          topic: canathome/pvmanager/heatingMaxPower
          payload: ${maxpower:%d}
  soc:
    source: js
    vm: shared
    script: |
      getSoc(modulation);
    in:
      - name: modulation
        type: float
        config:
          source: mqtt
          topic: canathome/pvmanager/heatPumpCompressorUtil
          timeout: 60s  # Akzeptiere keine Daten die älter als dieser Wert ist
  identify:
    source: js
    vm: shared
    script: |
      mode;
    in:
      - name: mode
        type: string
        config:
          source: mqtt
          topic: canathome/pvmanager/heatPumpMode
          timeout: 0s  # Akzeptiere keine Daten die älter als dieser Wert ist

vehicles:
- name: wp2
  type: template
  template: offline
  title: Heizen
  identifiers: [Heating]
  icon: heater
- name: wp3
  type: template
  template: offline
  title: Kühlen
  identifiers: [Cooling]
  icon: cooler
- name: wp4
  type: template
  template: offline
  title: Warmwasser
  identifiers: [Warmwater]
  icon: waterheater

loadpoints:
- title: Wärmepumpe
  charger: heatpump
  mode: pv
  soc:
    poll:
      mode: always
      interval: 3s
    estimate: false
  phases: 1
  mincurrent: 5
  maxcurrent: 32 # actual 15, but PI regulator works better with a higher limit
  enable:
    threshold: 100000
    delay: 0s
  disable:
    threshold: 100000
    delay: 0s
  meter: heatpump
  guardduration: 0s

image

image

andig commented 9 months ago

@MarkusGH abgefahrenes Setup. Du verwendest die Fahrzeuge aber "nur" fürs Logging, nicht um etwas zu steuern, richtig?

MarkusGH commented 9 months ago

@andig: Genau

andig commented 8 months ago

Für @VolkerK62's case könnte man die Fahrzeuge vmtl. unsichtbar machen. einfach ein invisible Feature und sie damit aus dem API komplett entfernen. Für @MarkusGH fällt mir keine gute Lösung ein, damit müssen wir erstmal leben...

MarkusGH commented 8 months ago

Wenn "invisible" das Fahrzeug nur in den Auswahllisten versteckt wäre mir zumindest teilweise geholfen. Aber warum nicht flexibler: Definition einer Fahrzeugklasse (einfach ein String) und am Loadpoint eine Liste von akzeptierten Fahrzeugklassen. Damit wäre auch gleich der Fall unterschiedlicher Steckertypen abgehandelt.

MarkusGH commented 8 months ago

Das Gastfahrzeug oder Fahrzeuge ohne Klasse kriegen dabei die Fahrzeugklasse "default" oder "", Loadpoint ohne Filter für die Klassen akzeptiert alle Klassen.

andig commented 8 months ago

Aber warum nicht flexibler:

Weil wir einfach kein klares Bild von dem Usecase haben und keine Einzellösung bauen wollen.

MarkusGH commented 8 months ago

Aber warum nicht flexibler:

Weil wir einfach kein klares Bild von dem Usecase haben und keine Einzellösung bauen wollen.

Das hat für mich keine hohe Priorität, ist also völlig OK, aber dennoch:

Das wäre doch gerade eine generalisierte Lösung und keine Einzellösung. Der Fall unterschiedlicher Steckertypen kommt in der Praxis sicher vor: Beispiel: Jemand hat eine Ladestation für E-Scooter an einem Shelly und eine normale Wallbox für Elektroautos. Die E-Scooter können niemals an die Wallbox und die EVs können niemals an die Ladestation für die Scooter. Macht keinen Sinn, die wechselweise auswählen zu können.

andig commented 8 months ago

Wenn Du es so verkaufst, finde ich die Idee Klasse! Jetzt müssen wir nur rausfinden, wie sich das elegant lösen liesse so dass die Konfiguration nach Möglichkeit orthogonal bleibt.

Was wäre eine Kompatibilitätsregel für einen "Steckertyp": es darf alles verbunden werden, was entweder keinen oder den passenden Typ hat? Also wenn nur einer der Player typisiert ist dann passt es immer?

Die Regel erscheint sinnvoll, macht es aber schwierig weil aktuell kaum einer der Charger die Zusatzfunktionen für icon/feature enthält (...und die heute auch nicht vermisst werden). Da müssten wir uns was Schlaues überlegen.

Die Alternative wäre auf einem Match zu bestehen. Dann könnten wir aber per Default keine Steckertypen mit ausliefern da sich sonst die ganzen custom Fahrzeuge nicht mehr mit den Switch Sockets verbinden liessen (...für die so ein Default sinnig wäre). Oder man akzeptiert den nächsten breaking change :/

/cc @naltatis

MarkusGH commented 8 months ago

Wenn Du es so verkaufst, finde ich die Idee Klasse! Jetzt müssen wir nur rausfinden, wie sich das elegant lösen liesse so dass die Konfiguration nach Möglichkeit orthogonal bleibt.

Freut mich dass ich durchdringe. Es müsste aus meiner Sicht gar nicht orthogonal sein.

Was wäre eine Kompatibilitätsregel für einen "Steckertyp": es darf alles verbunden werden, was entweder keinen oder den passenden Typ hat? Also wenn nur einer der Player typisiert ist dann passt es immer?

Die Regel erscheint sinnvoll, macht es aber schwierig weil aktuell kaum einer der Charger die Zusatzfunktionen für icon/feature enthält (...und die heute auch nicht vermisst werden). Da müssten wir uns was Schlaues überlegen.

Ich würde es einfach halten.

Nennen wir das Feature doch group.

1) das vehicle bekommt eine property group, Gastfahrzeug hat group "" 2) der Loadpoint bekommt eine Liste allowedVehicleGroups, wenn allowedVehicleGroupsnicht gesetzt ist sind alle "groups" erlaubt.

Wenn ein vehicle nicht in den allowedVehicleGroupsauftaucht kann es im UI nicht ausgewählt werden.

Damit kann ich dann auch verhindern, dass bei einem Loadpoint das Gastfahrzeug manuell wählbar ist (für meine WP anbindung sinnvoll, evtl. auch in anderen Fällen erwünscht).

andig commented 8 months ago

Wieso der Loadpoint? Wenn hängt die group doch am charger?

MarkusGH commented 8 months ago

Wieso der Loadpoint? Wenn hängt die group doch am charger?

Ist am Ende egal - loadpoint und charger haben doch sowieso eine 1:1 Zuordnung - oder? Loadpoint kommt mir plausibler vor - es kann ja auch "nicht technische" Gründe für eine Gruppierung geben...

andig commented 8 months ago

@naltatis as discussed- please review

andig commented 8 months ago

Bisher haben wir kein Konzept gefunden, dass sich auch elegant mit einem künftigen Config UI verbinden lassen würde.

MarkusGH commented 8 months ago

Bisher haben wir kein Konzept gefunden, dass sich auch elegant mit einem künftigen Config UI verbinden lassen würde.

Verstehe ich nicht - wenn der von mir vorgeschlagene "group" Ansatz implementiert würde, dann bekäme doch nur der Loadpoint optional eine zusätzliche Liste von Strings und das Verhicle optional einen String. Wenn am Loadpoint kein Filter gesetzt ist sind alle Fahrzeuggruppen erlaubt, gibt es einen Filter dann sind nur die Fahrzeuge erlaubt die einer der genannten Gruppen angehören. Das Gastfahrzeug hat eine vordefinierte Gruppe. Einfache Regel, völlig generisch, vielseitig verwendbar.

andig commented 8 months ago

dann bekäme doch nur der Loadpoint optional eine zusätzliche Liste von Strings und das Verhicle optional einen String.

Es geht ums Config UI. Das wäre nicht sehr intuitiv.

MarkusGH commented 8 months ago

Ich bin nicht der Meinung, dass intuitive Bedienung in einem künftigen Config UI ein starkes Kriterium gegen ein solches "Expertenfeature" ist.

andig commented 8 months ago

Meinungen helfen uns hier nicht. Vorschläge, wie sich das elegant lösen liesse würden das Thema schneller voran bringen.

MarkusGH commented 8 months ago

Meinungen helfen uns hier nicht.

OK - verstanden. Damit macht es für mich aber auch keinen Sinn mehr, mich einzubringen.

andig commented 8 months ago

Es gibt keinen Grund beleidigt zu sein. Wir sehen da ein Thema und das verschwindet auch dadurch nicht, dass Du es anders einschätzt.

andig commented 7 months ago

Scheint, als hätten wir keine gute Idee, wie sich das elegant mit dem Config UI verbinden ließe- closing.

andig commented 2 months ago

Siehe auch https://github.com/evcc-io/evcc/issues/14508. Damit könnten (ausser switchsockets) für custom Charger auf das zusätzliche vehicle (soc ist bereits erledigt) oder meter verzichtet werden.