Hello,
I’m having problems communicating with a REST API.
I’ve defined a POST, a PATCH, and a GET command, which I then use in the corresponding automations.
The idea is to log in to the API with credentials and then receive a beacon token including a refresh token.
The beacon thus obtained should be used to retrieve values via GET.
All values, including tokens, are written to or read from helpers.
Through debugging, I’ve seen that my automation for retrieving a token works, and the API also returns the corresponding tokens.
However, I can’t get the returned values into the helpers.
Apparently, there are problems in HomeAssistant precisely here, as values can’t be written to helpers due to a timing issue in HA.
Is there any truth to this?
rest_command.yaml:
fronius_get_jwt:
url: "https://api.solarweb.com/swqapi/iam/jwt?scope={{ scope }}"
method: POST
headers:
accesskeyid: "{{ accesskeyid }}"
accesskeyvalue: "{{ accesskeyvalue }}"
content-type: "application/json; charset=UTF-8"
accept-encoding: "gzip"
user-agent: "okhttp/4.12.0"
payload: '{"userId": "{{ userid }}", "password": "{{ password }}"}'
content_type: "application/json; charset=UTF-8"
verify_ssl: true
fronius_refresh_jwt:
url: "https://api.solarweb.com/swqapi/iam/jwt/{{ refresh_token }}?scope={{ scope }}"
method: PATCH
headers:
accesskeyid: "{{ accesskeyid }}"
accesskeyvalue: "{{ accesskeyvalue }}"
content-type: "application/json; charset=UTF-8"
authorization: "Bearer {{ jwt_token }}"
accept-encoding: "gzip"
user-agent: "okhttp/4.12.0"
payload: "{}"
content_type: "application/json; charset=UTF-8"
verify_ssl: true
fronius_get_energy_forecast:
url: "https://api.solarweb.com/swqapi/pvsystems/{{ pvsystemid }}/weather/energyforecast?fromTime={{ fromtime }}&toTime={{ totime }}"
method: GET
headers:
accesskeyid: "{{ accesskeyid }}"
accesskeyvalue: "{{ accesskeyvalue }}"
authorization: "Bearer {{ jwt_token }}"
accept-encoding: "gzip"
user-agent: "okhttp/4.12.0"
content_type: "application/json; charset=UTF-8"
verify_ssl: true
Automations:
- id: 'fronius_init'
alias: "Fronius: Initialwerte setzen"
trigger:
- platform: homeassistant
event: start
- platform: time
at: '04:55:00'
- platform: event
event_type: fronius_start_flow
action:
- service: input_text.set_value
target:
entity_id: input_text.fronius_userid
data:
value: !secret fronius_userid
- service: input_text.set_value
target:
entity_id: input_text.fronius_password
data:
value: !secret fronius_password
- service: input_text.set_value
target:
entity_id: input_text.fronius_scope
data:
value: !secret fronius_scope
- service: input_text.set_value
target:
entity_id: input_text.fronius_accesskeyid
data:
value: !secret fronius_accesskeyid
- service: input_text.set_value
target:
entity_id: input_text.fronius_accesskeyvalue
data:
value: !secret fronius_accesskeyvalue
- service: input_text.set_value
target:
entity_id: input_text.fronius_pvsystemid
data:
value: !secret fronius_pvsystemid
- service: input_text.set_value
target:
entity_id: input_text.fronius_fromtime
data:
value: "050000"
- service: input_text.set_value
target:
entity_id: input_text.fronius_totime
data:
value: "220000"
- service: input_text.set_value
target:
entity_id: input_text.fronius_jwt_token
data:
value: "jwt-init"
- service: input_text.set_value
target:
entity_id: input_text.fronius_refresh_token
data:
value: "refreshtoken-init"
- service: input_text.set_value
target:
entity_id: input_text.fronius_jwt_token_expiration
data:
value: "expiration-init"
- event: fronius_jwt_request
- id: 'fronius_jwt_request'
alias: "Fronius: JWT anfordern"
description: Authentifizierung bei Fronius Solarweb API
trigger:
- platform: event
event_type: fronius_jwt_request
condition:
- condition: template
value_template: >-
{{
states('input_text.fronius_userid') not in ['', 'unknown'] and
states('input_text.fronius_password') not in ['', 'unknown'] and
states('input_text.fronius_scope') not in ['', 'unknown'] and
states('input_text.fronius_accesskeyid') not in ['', 'unknown'] and
states('input_text.fronius_accesskeyvalue') not in ['', 'unknown']
}}
action:
- service: rest_command.fronius_get_jwt
data:
userid: "{{ states('input_text.fronius_userid') }}"
password: "{{ states('input_text.fronius_password') }}"
scope: "{{ states('input_text.fronius_scope') }}"
accesskeyid: "{{ states('input_text.fronius_accesskeyid') }}"
accesskeyvalue: "{{ states('input_text.fronius_accesskeyvalue') }}"
response_variable: jwt_response
- service: system_log.write
data:
message: "JWT Response Raw: {{ jwt_response }}"
level: info
- choose:
# Erfolgsfall (200 OK)
- conditions: "{{ jwt_response.status == 200 }}"
sequence:
- service: input_text.set_value
target:
entity_id: input_text.fronius_jwt_token
data:
value: >-
{% if jwt_response.content is string %}
{{ (jwt_response.content | from_json).get('jwtToken', '') }}
{% else %}
{{ jwt_response.content.get('jwtToken', '') }}
{% endif %}
- service: input_text.set_value
target:
entity_id: input_text.fronius_refresh_token
data:
value: >-
{% if jwt_response.content is string %}
{{ (jwt_response.content | from_json).get('refreshToken', '') }}
{% else %}
{{ jwt_response.content.get('refreshToken', '') }}
{% endif %}
- service: input_number.set_value
target:
entity_id: input_number.fronius_retry_count
data:
value: 0
- service: system_log.write
data:
message: "Token erfolgreich gespeichert: {{ now() }}"
level: info
- delay: "00:00:10"
- condition: template
value_template: "{{ states('input_text.fronius_jwt_token') not in [None, '', 'unavailable'] }}"
- event: fronius_energy_forecast_request
# Fehlerfall (401 Unauthorized)
- conditions: "{{ jwt_response.status == 401 }}"
sequence:
- service: input_number.increment
target:
entity_id: input_number.fronius_retry_count
- delay: "00:01:00"
- choose:
- conditions: "{{ states('input_number.fronius_retry_count') | int <= 3 }}"
sequence:
- delay: "00:01:00"
- event: fronius_jwt_request
- service: system_log.write
data:
message: "Erneuter Authentifizierungsversuch: {{ now() }}"
level: warning
- conditions: "{{ states('input_number.fronius_retry_count') | int > 3 }}"
sequence:
- service: input_number.set_value
target:
entity_id: input_number.fronius_retry_count
data:
value: 0
- service: system_log.write
data:
message: "Authentifizierung fehlgeschlagen, Initialisierung erforderlich: {{ now() }}"
level: error
- event: fronius_init
- id: 'fronius_energy_forecast'
alias: "Fronius: Energieprognose abrufen"
trigger:
- platform: event
event_type: fronius_energy_forecast_request
action:
- service: rest_command.fronius_get_energy_forecast
data:
jwt_token: "{{ states('input_text.fronius_jwt_token') }}"
accesskeyid: "{{ states('input_text.fronius_accesskeyid') }}"
accesskeyvalue: "{{ states('input_text.fronius_accesskeyvalue') }}"
pvsystemid: "{{ states('input_text.fronius_pvsystemid') }}"
fromtime: "{{ states('input_text.fronius_fromtime') }}"
totime: "{{ states('input_text.fronius_totime') }}"
response_variable: forecast_response
- choose:
- conditions: "{{ forecast_response.status == 200 }}"
sequence:
- service: input_number.set_value
target:
entity_id: input_number.fronius_energy_forecast
data:
value: "{{ ((forecast_response.content | from_json | default({}) | get('data', []) | map(attribute='channels') | map('first') | map(attribute='value') | map('float') | list) | sum / 1000 | round(2) if (forecast_response.content | from_json | default({}) | get('data', []) | count > 0) else '0.0') | string }}"
- service: system_log.write
data:
message: "getting forecast and writing in Entitäten ok: {{ now() }}"
level: info
- conditions: "{{ forecast_response.status == 401 or 'JWT expired.' in forecast_response.content }}"
sequence:
- service: system_log.write
data:
message: "forecast request failed, 401 or 'JWT expired: {{ now() }} "
level: warning
- delay: "00:01:00"
- event: fronius_jwt_request
- id: 'fronius_token_refresh'
alias: "Fronius: JWT Refresh"
trigger:
- platform: time_pattern
minutes: "/55"
action:
- choose:
# Prüfe, ob beide Tokens vorhanden sind
- conditions: >
{{
states('input_text.fronius_jwt_token') not in ['', 'unknown', 'unavailable'] and
states('input_text.fronius_refresh_token') not in ['', 'unknown', 'unavailable']
}}
sequence:
- service: rest_command.fronius_refresh_jwt
data:
refresh_token: "{{ states('input_text.fronius_refresh_token') }}"
accesskeyid: "{{ states('input_text.fronius_accesskeyid') }}"
accesskeyvalue: "{{ states('input_text.fronius_accesskeyvalue') }}"
scope: "{{ states('input_text.fronius_scope') }}"
jwt_token: "{{ states('input_text.fronius_jwt_token') }}"
response_variable: refresh_response
- choose:
# Erfolgsfall: Tokens speichern und Prognose abrufen
- conditions: "{{ (refresh_response.status | default(0)) == 200 }}"
sequence:
- service: input_text.set_value
target:
entity_id: input_text.fronius_jwt_token
data:
value: "{{ (refresh_response.content | from_json).get('jwtToken', '') | string }}"
- service: input_text.set_value
target:
entity_id: input_text.fronius_refresh_token
data:
value: "{{ (refresh_response.content | from_json).get('refreshToken', '') | string }}"
- delay: "00:01:00"
- condition: template
value_template: "{{ states('input_text.fronius_jwt_token') not in [None, '', 'unavailable'] }}"
- service: system_log.write
data:
message: "Token Refresh ok: {{ now() }}, starting forecast request"
level: info
- event: fronius_energy_forecast_request
# Fehlerfall: Token abgelaufen oder ungültig, neuen JWT anfordern
- conditions: "{{ (refresh_response.status | default(0)) == 401 or (refresh_response.content is defined and 'JWT expired.' in refresh_response.content) }}"
sequence:
- delay: "00:00:10"
- event: fronius_jwt_request
- service: system_log.write
data:
message: "Token abgelaufen oder ungültig, neuen JWT anfordern: {{ now() }}"
level: info
# Fehlerfall: refresh_response ist undefined (z.B. REST-Fehler)
- conditions: "{{ refresh_response is undefined }}"
sequence:
- service: system_log.write
data:
message: "Keine Antwort vom Refresh-Endpoint. Starte Neuauthentifizierung: {{ now() }}"
level: error
- event: fronius_jwt_request
# Falls ein Token fehlt: direkt neuen JWT anfordern
- conditions: >
{{
states('input_text.fronius_jwt_token') in ['', 'unknown', 'unavailable'] or
states('input_text.fronius_refresh_token') in ['', 'unknown', 'unavailable']
}}
sequence:
- service: system_log.write
data:
message: "Token Refresh übersprungen, da Token fehlt: {{ now() }}"
level: warning
- event: fronius_jwt_request
input_text.yaml:
fronius_userid:
name: User ID
fronius_password:
name: Passwort
mode: password
fronius_scope:
name: Scope
fronius_accesskeyid:
name: Access Key ID
fronius_accesskeyvalue:
name: Access Key Value
fronius_pvsystemid:
name: PV System ID
fronius_jwt_token:
name: JWT Token
fronius_refresh_token:
name: Refresh Token
fronius_jwt_token_expiration:
name: JWT Token Expiration
fronius_fromtime:
name: Fronius From Time
fronius_totime:
name: Fronius To Time