Skip to content
Open
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
82 changes: 77 additions & 5 deletions templates/definition/charger/viessmann.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,16 @@ requirements:
description:
de: |
Einmalige Warmwasserbereitung. Das Gerät entscheidet eigenständig, ob die Wärmepumpe oder die elektrische Zusatzheizung (falls vorhanden) genutzt wird.

Hinweis: Im Auslieferungszustand kann zur Warmwasserbereitung auch der Heizwasser-Durchlauferhitzer (elektrische Zusatzheizung, „Heizstab") automatisch zuschalten. Um das zu vermeiden, die Freigabe der elektrischen Zusatzheizung für die Warmwasserbereitung vom Fachbetrieb sperren lassen (Parameter „Freigabe Heizwasser-Durchlauferhitzer") oder — sofern verfügbar — in der ViCare-App den Warmwasser-Modus „Effizient" wählen.

Optional können Leistungs- und Temperaturwerte ausgelesen werden. Das setzt Datenpunkte der One-Base-/E3-Gerätegeneration voraus (z. B. Vitocal 25x, getestet mit Vitocal 250-A). Welche Datenpunkte ein Gerät liefert, ist geräteabhängig und lässt sich über die [Viessmann API](https://developer.viessmann-climatesolutions.com/) am Feature-Endpunkt der Anlage ablesen. Für unterstützte Geräte die Option „Leistungs- und Temperaturwerte auslesen" aktivieren.
en: |
One-time hot water preparation. The device automatically decides whether to use the heat pump or the auxiliary electric heater (if available).

Note: in the factory configuration, hot water preparation may also automatically activate the built-in electric booster heater ("Heizwasser-Durchlauferhitzer"). To avoid this, have your heating contractor lock the approval of the electric booster heater for hot water preparation (parameter "Freigabe Heizwasser-Durchlauferhitzer"), or — where available — select the "Efficient" hot water mode in the ViCare app.

Optionally, power and temperature readings can be enabled. This requires data points of the One Base/E3 device generation (e.g. Vitocal 25x, tested with a Vitocal 250-A). Which data points a device provides is device-specific and can be inspected via the [Viessmann API](https://developer.viessmann-climatesolutions.com/) feature endpoint of the installation. For supported devices, enable the "Read power and temperature values" option.
params:
- name: user
deprecated: true
Expand Down Expand Up @@ -133,6 +141,25 @@ params:
de: normalerweise `0`
en: typically `0`
default: 0
- name: measurements
required: true
type: bool
default: false
description:
de: Leistungs- und Temperaturwerte auslesen
en: Read power and temperature values
help:
de: Liest die aktuelle elektrische Leistungsaufnahme und die Warmwassertemperatur aus. Aktivieren, wenn das Gerät diese Datenpunkte liefert (One-Base-/E3-Generation, z. B. Vitocal 25x); die Verfügbarkeit lässt sich am Feature-Endpunkt der API ablesen. Standardmäßig deaktiviert, damit sich bestehende Installationen beim Update nicht ändern.
en: Reads the current electrical power consumption and the domestic hot water temperature. Enable if the device provides these data points (One Base/E3 generation, e.g. Vitocal 25x); availability can be checked via the API feature endpoint. Disabled by default so existing installations are unchanged on upgrade.
Comment on lines +144 to +153

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Boolean parameter measurements is treated as a string in the template condition, which is likely to misbehave.

The parameter is declared as type: bool but evaluated with {{- if eq .measurements "true" }}, which assumes a string. This will fail if evcc passes a real boolean (true/false without quotes). Use a boolean check such as {{- if .measurements }} or {{- if eq .measurements true }} so the condition matches the declared type and avoids misconfiguration.

- name: uri
advanced: true
default: https://api.viessmann-climatesolutions.com/iot/v2
description:
de: API-Basis-URL
en: API base URL
help:
de: Nur ändern, falls Viessmann die API-Domain erneut umzieht oder ein Proxy verwendet wird
en: Only change if Viessmann moves the API domain again or a proxy is used
- name: target_temperature
deprecated: true
description:
Expand All @@ -148,17 +175,22 @@ auth:
type: viessmann
params: [clientid, redirecturi, gateway_serial]
render: |
{{- $device := printf "%s/features/installations/%s/gateways/%s/devices/%s" .uri .installation_id .gateway_serial .device_id }}
type: sgready
getmode:
source: http
uri: https://api.viessmann-climatesolutions.com/iot/v2/features/installations/{{.installation_id}}/gateways/{{.gateway_serial}}/devices/{{.device_id}}/features/heating.dhw.oneTimeCharge
cache: 2s # to prevent making two identical requests straight after each other for "getmode"
# Read the whole device feature list in ONE request. All GET readers below use
# this exact same URL, so evcc's shared HTTP cache serves them from a single API
# call per cache window. The Viessmann API has a strict daily request quota
# (shared with the ViCare app); per-feature polling exhausts it (HTTP 429).
uri: {{ $device }}/features
cache: 120s # ~720 requests/day; raise further if you still hit 429
auth:
source: viessmann
clientid: {{ .clientid }}
redirecturi: {{ .redirecturi }}
gateway_serial: {{ .gateway_serial }}
jq: '.data.properties.active.value | if . == false then 2 elif . == true then 3 else . end'
jq: '.data[] | select(.feature == "heating.dhw.oneTimeCharge") | .properties.active.value | if . == false then 2 elif . == true then 3 else . end'
# false -> oneTimeCharge is disabled -> normal mode -> 2
# true -> oneTimeCharge is enabled -> boost mode -> 3
setmode:
Expand All @@ -171,7 +203,7 @@ render: |
- case: 2 # normal
set:
source: http
uri: https://api.viessmann-climatesolutions.com/iot/v2/features/installations/{{.installation_id}}/gateways/{{.gateway_serial}}/devices/{{.device_id}}/features/heating.dhw.oneTimeCharge/commands/deactivate
uri: {{ $device }}/features/heating.dhw.oneTimeCharge/commands/deactivate
method: POST
headers:
- content-type: application/json
Expand All @@ -185,7 +217,7 @@ render: |
- case: 3 # boost
set:
source: http
uri: https://api.viessmann-climatesolutions.com/iot/v2/features/installations/{{.installation_id}}/gateways/{{.gateway_serial}}/devices/{{.device_id}}/features/heating.dhw.oneTimeCharge/commands/activate
uri: {{ $device }}/features/heating.dhw.oneTimeCharge/commands/activate
method: POST
headers:
- content-type: application/json
Expand All @@ -200,4 +232,44 @@ render: |
set:
source: error
error: ErrNotAvailable
{{- if eq .measurements "true" }}
power:
# heating.power.consumption.current reports the real electrical input power in kW.
# Reading it replaces evcc's fallback estimate (current * phases * voltage), which
# wrongly assumed a full electric-heater draw when no meter was configured.
# Same URL + cache as getmode -> served from the shared cached feature list.
source: http
uri: {{ $device }}/features
cache: 120s
auth:
source: viessmann
clientid: {{ .clientid }}
redirecturi: {{ .redirecturi }}
gateway_serial: {{ .gateway_serial }}
jq: '.data[] | select(.feature == "heating.power.consumption.current") | .properties.value.value * 1000' # kW -> W
temp:
# heating.dhw.sensors.temperature.dhwCylinder: domestic hot water temperature (°C).
# The device controls one-time DHW charging, so the hot water tank is the natural
# temperature to display on the loadpoint gauge.
source: http
uri: {{ $device }}/features
cache: 120s
auth:
source: viessmann
clientid: {{ .clientid }}
redirecturi: {{ .redirecturi }}
gateway_serial: {{ .gateway_serial }}
jq: '.data[] | select(.feature == "heating.dhw.sensors.temperature.dhwCylinder") | .properties.value.value'
limittemp:
# heating.dhw.temperature.main: configured DHW target temperature (°C).
source: http
uri: {{ $device }}/features
cache: 120s
auth:
source: viessmann
clientid: {{ .clientid }}
redirecturi: {{ .redirecturi }}
gateway_serial: {{ .gateway_serial }}
jq: '.data[] | select(.feature == "heating.dhw.temperature.main") | .properties.value.value'
{{- end }}
{{ include "heatpumpswitch" . }}
95 changes: 95 additions & 0 deletions templates/definition/meter/viessmann.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
template: viessmann
products:
- brand: Viessmann
description:
generic: Heatpump consumption (API)
requirements:
# evcc: ["sponsorship"]
evcc: ["skiptest"]
description:
de: |
Liest die aktuelle elektrische Leistungsaufnahme der Wärmepumpe (heating.power.consumption.current)
als zusätzlichen Verbraucher (aux). Dadurch erscheint die Wärmepumpe im Energiefluss unter "Verbrauch"
und ihr Verbrauch fließt in die evcc-Statistik ein - unabhängig davon, ob evcc die Wärmepumpe steuert.
en: |
Reads the heat pump's current electrical power consumption (heating.power.consumption.current) as an
additional consumer (aux). The heat pump then appears under "Consumption" in the energy flow and its
usage feeds the evcc statistics - independent of whether evcc controls the heat pump.
params:
- name: usage
choice: ["aux"]
- name: clientid
required: true
help:
de: Konfigurieren in [app.developer.viessmann-climatesolutions.com](https://app.developer.viessmann-climatesolutions.com)
en: Configure at [app.developer.viessmann-climatesolutions.com](https://app.developer.viessmann-climatesolutions.com)
- name: redirecturi
help:
en: "Redirect URI of the evcc instance. Must match the redirect URI set in the Viessmann developer portal."
de: "Redirect-URI der evcc-Instanz. Muss mit der Redirect URI übereinstimmen, die im Viessmann Developer Portal konfiguriert ist."
service: auth/redirecturi
- name: gateway_serial
required: true
description:
de: Gateway Serial
en: Gateway Serial
help:
de: Seriennummer des VitoConnect modul (VitoCare App -> Einstellungen -> Kommunikationsmodul -> Seriennummer)
en: VitoConnect serial number (VitoCare App -> Settings -> Communication module -> Serial number)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (review_instructions): The wording here uses "VitoCare App", which is inconsistent with other templates that reference the "ViCare" app.

Other templates in the templates directory refer to the Viessmann app as "ViCare" (without the extra "to"). Please update both the German and English help texts to use the same app name spelling for consistency with existing templates.

Review instructions:

Path patterns: templates/**/*.yaml

Instructions:
Verify that the changes comply to the rules defined in templates/README.md. Also check consistence (wording) with other files inside templates directory.

- name: installation_id
required: true
description:
de: Installation ID
en: Installation ID
help:
de: Ermittlung wie beim Viessmann Wärmepumpen-Charger-Template beschrieben (equipment/installations).
en: Determine as described in the Viessmann heat pump charger template (equipment/installations).
- name: device_id
required: true
description:
de: Device ID
en: Device ID
help:
de: normalerweise `0`
en: typically `0`
default: 0
- name: uri
advanced: true
default: https://api.viessmann-climatesolutions.com/iot/v2
description:
de: API-Basis-URL
en: API base URL
help:
de: Nur ändern, falls Viessmann die API-Domain erneut umzieht oder ein Proxy verwendet wird
en: Only change if Viessmann moves the API domain again or a proxy is used
auth:
type: viessmann
params: [clientid, redirecturi, gateway_serial]
render: |
{{- $device := printf "%s/features/installations/%s/gateways/%s/devices/%s" .uri .installation_id .gateway_serial .device_id }}
type: custom
power:
# heating.power.consumption.current: real electrical input power in kW -> W.
# Uses the same device feature-list URL + cache as the Viessmann charger, so when
# both are configured this shares one cached request instead of doubling API calls
# (the Viessmann API has a strict daily quota shared with the ViCare app).
source: http
uri: {{ $device }}/features
cache: 120s
auth:
source: viessmann
clientid: {{ .clientid }}
redirecturi: {{ .redirecturi }}
gateway_serial: {{ .gateway_serial }}
jq: '.data[] | select(.feature == "heating.power.consumption.current") | .properties.value.value * 1000' # kW -> W
soc:
# heating.dhw.sensors.temperature.dhwCylinder: domestic hot water temperature (°C).
source: http
uri: {{ $device }}/features
cache: 120s
auth:
source: viessmann
clientid: {{ .clientid }}
redirecturi: {{ .redirecturi }}
gateway_serial: {{ .gateway_serial }}
jq: '.data[] | select(.feature == "heating.dhw.sensors.temperature.dhwCylinder") | .properties.value.value'
Loading