diff --git a/plugin/auth/viessmann.go b/plugin/auth/viessmann.go index 5de4143df..89caad8b7 100644 --- a/plugin/auth/viessmann.go +++ b/plugin/auth/viessmann.go @@ -3,28 +3,21 @@ package auth import ( "context" + "dario.cat/mergo" "github.com/evcc-io/evcc/util" "github.com/evcc-io/evcc/util/request" "golang.org/x/oauth2" ) -const ( - OAuthURI = "https://iam.viessmann-climatesolutions.com/idp/v3" - RedirectURI = "http://localhost:4200/" - // ^ the value of RedirectURI doesn't matter, but it must be the same between requests -) +const OAuthURI = "https://iam.viessmann-climatesolutions.com/idp/v3" -func oauth2Config(clientID string) *oauth2.Config { - return &oauth2.Config{ - ClientID: clientID, - Endpoint: oauth2.Endpoint{ - AuthURL: OAuthURI + "/authorize", - TokenURL: OAuthURI + "/token", - AuthStyle: oauth2.AuthStyleInHeader, - }, - RedirectURL: RedirectURI, - Scopes: []string{"IoT User", "offline_access"}, - } +var oauthConfig = oauth2.Config{ + Endpoint: oauth2.Endpoint{ + AuthURL: OAuthURI + "/authorize", + TokenURL: OAuthURI + "/token", + AuthStyle: oauth2.AuthStyleInHeader, + }, + Scopes: []string{"IoT User", "offline_access"}, } func init() { @@ -33,8 +26,9 @@ func init() { func NewViessmannFromConfig(ctx context.Context, other map[string]any) (oauth2.TokenSource, error) { var cc struct { - ClientID string - Gateway string + ClientID string + RedirectURI string + Gateway string } if err := util.DecodeOther(other, &cc); err != nil { @@ -44,5 +38,13 @@ func NewViessmannFromConfig(ctx context.Context, other map[string]any) (oauth2.T log := util.NewLogger("viessmann").Redact(cc.ClientID) ctx = context.WithValue(ctx, oauth2.HTTPClient, request.NewClient(log)) - return NewOauth(ctx, "Viessmann", cc.Gateway, oauth2Config(cc.ClientID)) + oc := oauth2.Config{ + ClientID: cc.ClientID, + RedirectURL: cc.RedirectURI, + } + if err := mergo.Merge(&oc, oauthConfig); err != nil { + return nil, err + } + + return NewOauth(ctx, "Viessmann", cc.Gateway, &oc) } diff --git a/templates/definition/charger/viessmann.yaml b/templates/definition/charger/viessmann.yaml index 74aa960cd..21eb16fb2 100644 --- a/templates/definition/charger/viessmann.yaml +++ b/templates/definition/charger/viessmann.yaml @@ -22,6 +22,14 @@ params: 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 + required: true + description: + generic: Redirect URI + 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 Viessmann Developer Portal konfiguriert ist." + example: "https://evcc.example.org/providerauth/callback" - name: gateway_serial required: true description: @@ -50,7 +58,7 @@ params: Dann holen wir uns einen oauth token (n.b. am besten den gesamten Block in das Terminal kopieren, da die Zwischenvariable 'CODE' nur 20 Sekunden gültig ist): ``` - VIESSMANN_REDIRECT_URI="http://localhost:4200/" + VIESSMANN_REDIRECT_URI= VIESSMANN_CODE_CHALLENGE="5M5nhkBfkWZCGfLZYcTL-l7esjPUN7PpZ4rq8k4cmys" VIESSMANN_CODE_VERIFIER="6PygdmeK8JKPuuftlkc6q4ceyvjhMM_a_cJrPbcmcLc-SPjx2ZXTYr-SOofPUBydQ3McNYRy7Hibc2L2WtVLJFpOQ~Qbgic455ArKjUz9_UiTLnO6q8A3e.I_fIF8hAo" @@ -92,7 +100,7 @@ params: Then execute the following to get an oauth token (n.b. it's best to paste the entire block as-is, since the intermediate 'CODE' is only valid for 20 seconds): ``` - VIESSMANN_REDIRECT_URI="http://localhost:4200/" + VIESSMANN_REDIRECT_URI= VIESSMANN_CODE_CHALLENGE="5M5nhkBfkWZCGfLZYcTL-l7esjPUN7PpZ4rq8k4cmys" VIESSMANN_CODE_VERIFIER="6PygdmeK8JKPuuftlkc6q4ceyvjhMM_a_cJrPbcmcLc-SPjx2ZXTYr-SOofPUBydQ3McNYRy7Hibc2L2WtVLJFpOQ~Qbgic455ArKjUz9_UiTLnO6q8A3e.I_fIF8hAo" @@ -149,6 +157,7 @@ render: | auth: source: viessmann clientid: {{ .clientid }} + redirecturi: {{ .redirecturi }} gateway: {{ .gateway_serial }} jq: '.data.properties.active.value | if . == false then 2 elif . == true then 3 else . end' # false -> oneTimeCharge is disabled -> normal mode -> 2 @@ -170,6 +179,7 @@ render: | auth: source: viessmann clientid: {{ .clientid }} + redirecturi: {{ .redirecturi }} gateway: {{ .gateway_serial }} body: > { } @@ -183,6 +193,7 @@ render: | auth: source: viessmann clientid: {{ .clientid }} + redirecturi: {{ .redirecturi }} gateway: {{ .gateway_serial }} body: > { }