-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vicare: Initial commit for new Viessmann plugin, communicating via Vi…
…essmann API with backend.
- Loading branch information
Showing
8 changed files
with
1,290 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# translations for the web interface | ||
plugin_translations: | ||
# Translations for the plugin specially for the web interface | ||
'Informationen': {'de': '=', 'en': 'Informations'} | ||
'Einstellungen': {'de': '=', 'en': 'Settings'} | ||
|
||
# Alternative format for translations of longer texts: | ||
'Viessmann Explanation': | ||
de: 'Schritt für Schritt Anleitung zur Verbindung des Plugins mit dem Vissmann Backend.' | ||
en: 'Step by step manual for connecting the plugin with the Viessmann backend.' | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# Metadata for the plugin | ||
plugin: | ||
# Global plugin attributes | ||
type: gateway # plugin type (gateway, interface, protocol, system, web) | ||
description: | ||
de: 'Plugin zur Anbindung an das Viessmann Backend an SmartHomeNG' | ||
en: 'Plugin to connect the Viessmann backend with SmartHomeNG' | ||
maintainer: aschwith | ||
tester: 'n/a' | ||
state: develop | ||
keywords: Viessmann, ViCare, Vitocontrol | ||
#documentation: | ||
support: https://knx-user-forum.de/forum/supportforen/smarthome-py/1916122-support-thread-f%C3%BCr-das-viessmann-plugin | ||
|
||
version: 1.9.0 # Plugin version | ||
sh_minversion: 1.9.0 # minimum shNG version to use this plugin | ||
# sh_maxversion: # maximum shNG version to use this plugin (leave empty if latest) | ||
multi_instance: False # plugin supports multi instance | ||
restartable: True | ||
classname: Vicare # class containing the plugin | ||
|
||
parameters: | ||
|
||
clientID: | ||
type: str | ||
mandatory: True | ||
description: | ||
de: "Client ID (via Viessmann Developper API Portal generiert)" | ||
en: "Client id (generated via Viessmann developper api portal)" | ||
|
||
redirectUrl: | ||
type: str | ||
mandatory: True | ||
description: | ||
de: "Redirect Url (via Viessmann Developper API Portal angelegt)" | ||
en: "Redirect uri (defined via Viessmann Developper API Portal)" | ||
|
||
accessToken: | ||
type: str | ||
gui_type: readonly | ||
description: | ||
de: "Token (beim Oauth2 Verfahren generiert)" | ||
en: "Token (generated during the Oauth2 procedure)" | ||
|
||
refreshToken: | ||
type: str | ||
gui_type: readonly | ||
description: | ||
de: "Refresh token (beim Oauth2 Verfahren generiert)" | ||
en: "Refresh token (generated during the Oauth2 procedure)" | ||
|
||
|
||
|
||
item_attributes: | ||
# Definition of item attributes defined by this plugin (enter 'item_attributes: NONE', if section should be empty) | ||
vicare_tx_key: | ||
type: str | ||
description: | ||
de: 'Key für das Senden von Kommandos an das Viessmann Backend' | ||
en: 'Key for sending commands to the Viessmann backend' | ||
valid_list: | ||
- 'heating.circuits.1.operating.programs.normal' | ||
- 'heating.circuits.1.operating.programs.reduced' | ||
- 'heating.dhw.temperature.main' | ||
- 'heating.dhw.operating.modes.active' | ||
- 'heating.circuits.1.operating.modes.active' | ||
|
||
vicare_tx_path: | ||
type: list | ||
description: | ||
de: 'Array mit Einträgen zum Pfad des Sendekommandos im Feature command' | ||
en: 'Array of entries to find command in json response' | ||
|
||
vicare_rx_key: | ||
type: str | ||
description: | ||
de: 'Key für den Empfang von Statusinformationen aus dem Viessmann Backend' | ||
en: 'Key for receiving status informations from the Viessmann backend' | ||
valid_list: | ||
- 'boilerSerial' | ||
- 'heating.circuits.1.sensors.temperature.supply' | ||
- 'heating.circuits.1.operating.programs.active' | ||
- 'heating.circuits.1.operating.modes.heating' | ||
- 'heating.circuits.1.operating.modes.active' | ||
- 'heating.gas.consumption.total' | ||
- 'heating.circuits.1.operating.programs.comfort' | ||
- 'heating.circuits.1.operating.programs.normal' | ||
- 'heating.circuits.1.operating.programs.reduced' | ||
- 'heating.circuits.1.circulation.pump' | ||
- 'heating.operating.programs.holiday' | ||
- 'heating.dhw' | ||
- 'heating.dhw.temperature.main' | ||
- 'heating.dhw.oneTimeCharge' | ||
- 'heating.dhw.operating.modes.active' | ||
- 'heating.dhw.sensors.temperature.dhwCylinder' | ||
- 'heating.dhw.sensors.temperature.hotWaterStorage' | ||
- 'heating.boiler.sensors.temperature.commonSupply' | ||
- 'heating.boiler.temperature' | ||
- 'heating.sensors.temperature.outside' | ||
- 'heating.power.consumption.summary.heating' | ||
- 'heating.power.consumption.total' | ||
- 'device.messages.errors.raw' | ||
|
||
vicare_path: | ||
type: list | ||
description: | ||
de: 'Array mit Pfad zur Eigenschaft in Feature property' | ||
en: 'Array of entries to find property in json response' | ||
|
||
|
||
plugin_functions: NONE | ||
|
||
logic_parameters: NONE | ||
|
||
item_structs: NONE | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
authlib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
.. index:: Plugins; vicare | ||
.. index:: vicare | ||
|
||
========== | ||
vicare | ||
========== | ||
|
||
.. image:: webif/static/img/plugin_logo.png | ||
:alt: plugin logo | ||
:width: 300px | ||
:height: 300px | ||
:scale: 50 % | ||
:align: left | ||
|
||
Allgemein | ||
========= | ||
|
||
SmarthomeNG plugin mit Unterstützung für Viessmann Heizungen via vicare backend mit OAuth2 Identifizierung. | ||
|
||
Konfiguration | ||
============= | ||
|
||
Die Informationen zur Konfiguration des Plugins sind unter :doc:`/plugins_doc/config/vicare` beschrieben. | ||
Die Kopplung zwischen Plugin und Viessmann Backend erfolgt über das OAuth2 Verfahren. Das Webinterface führt Schritt für Schritt durch den Anmeldeprozess. Die Authentifizierung muss einmal via | ||
Webinterface durchgeführt werden. Nach Abschluss erhält man einen access Token und einen refresh Token. Beide werden persistent in der plugin.yaml gespeichert. Mit Hilfe des refresh Tokens generiert | ||
das Plugin bei jedem Neustart einen neuen accessToken. Der refresh Token ist 180 Tage gültig, d.g. die manuelle Authentifizierung muss alle 180 Tage einmal durchgeführt werden. Dies ist eine Vorgabe der Viessmann API. | ||
|
||
Requirements | ||
============= | ||
- authlib | ||
|
||
Supported Hardware | ||
================== | ||
z.B. Vitodens 200-W | ||
|
||
|
||
Web Interface | ||
============= | ||
|
||
|
||
Aufruf des Webinterfaces | ||
------------------------ | ||
|
||
Das Plugin kann aus dem Admin Interface aufgerufen werden. Dazu auf der Seite Plugins in der entsprechenden | ||
Zeile das Icon in der Spalte **Web Interface** anklicken. | ||
|
||
Außerdem kann das Webinterface direkt über ``http://smarthome.local:8383/vicare`` aufgerufen werden. | ||
|
||
|
||
Beispiele | ||
--------- | ||
|
||
Folgende Informationen können im Webinterface angezeigt werden: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
#!/usr/bin/env python3 | ||
# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab | ||
######################################################################### | ||
# Copyright 2020- <AUTHOR> <EMAIL> | ||
######################################################################### | ||
# This file is part of SmartHomeNG. | ||
# https://www.smarthomeNG.de | ||
# https://knx-user-forum.de/forum/supportforen/smarthome-py | ||
# | ||
# Sample plugin for new plugins to run with SmartHomeNG version 1.5 and | ||
# upwards. | ||
# | ||
# SmartHomeNG is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# SmartHomeNG is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with SmartHomeNG. If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
######################################################################### | ||
|
||
import datetime | ||
import time | ||
import os | ||
import json | ||
|
||
from lib.item import Items | ||
from lib.model.smartplugin import SmartPluginWebIf | ||
|
||
|
||
# ------------------------------------------ | ||
# Webinterface of the plugin | ||
# ------------------------------------------ | ||
|
||
import cherrypy | ||
import csv | ||
from jinja2 import Environment, FileSystemLoader | ||
|
||
|
||
class WebInterface(SmartPluginWebIf): | ||
|
||
def __init__(self, webif_dir, plugin): | ||
""" | ||
Initialization of instance of class WebInterface | ||
:param webif_dir: directory where the webinterface of the plugin resides | ||
:param plugin: instance of the plugin | ||
:type webif_dir: str | ||
:type plugin: object | ||
""" | ||
self.logger = plugin.logger | ||
self.webif_dir = webif_dir | ||
self.plugin = plugin | ||
self.items = Items.get_instance() | ||
|
||
self.tplenv = self.init_template_environment() | ||
|
||
|
||
@cherrypy.expose | ||
def index(self, reload=None, action=None, email=None, hashInput=None, code=None, tokenInput=None): | ||
""" | ||
Build index.html for cherrypy | ||
Render the template and return the html file to be delivered to the browser | ||
:return: contents of the template after beeing rendered | ||
""" | ||
|
||
generateURLSuccessfull = None | ||
tokenRequestCompleted = None | ||
|
||
if action is not None: | ||
if action == "generateURL": | ||
self.logger.info("generate URL triggered via webinterface") | ||
self.plugin.generate_code_verifier() | ||
self.plugin.calculate_code_challenge(self.plugin.codeVerifier) | ||
generateURLSuccessfull = self.plugin.generate_request_url() | ||
elif action == "requestToken": | ||
self.logger.info("Request token triggered via webinterface") | ||
if (code is not None) and (not code == ''): | ||
tokenRequestCompleted = self.plugin.retrieve_accessToken(code) | ||
elif (code is None) or (code == ''): | ||
self.logger.error("Token request not possible: Code missing in field above.") | ||
tokenRequestCompleted = False | ||
else: | ||
self.logger.error("Token request not possible: Missing argument.") | ||
tokenRequestCompleted = False | ||
else: | ||
self.logger.error("Unknown command received via webinterface") | ||
|
||
tmpl = self.tplenv.get_template('index.html') | ||
# add values to be passed to the Jinja2 template eg: tmpl.render(p=self.plugin, interface=interface, ...) | ||
return tmpl.render(p=self.plugin, | ||
generateURLSuccessfull=generateURLSuccessfull, | ||
tokenRequestCompleted=tokenRequestCompleted ) | ||
|
||
|
||
@cherrypy.expose | ||
def get_data_html(self, dataSet=None): | ||
""" | ||
Return data to update the webpage | ||
For the standard update mechanism of the web interface, the dataSet to return the data for is None | ||
:param dataSet: Dataset for which the data should be returned (standard: None) | ||
:return: dict with the data needed to update the web page. | ||
""" | ||
# if dataSets are used, define them here | ||
if dataSet == 'overview': | ||
# get the new data from the plugin variable called _webdata | ||
data = self.plugin._webdata | ||
try: | ||
data = json.dumps(data) | ||
return data | ||
except Exception as e: | ||
self.logger.error(f"get_data_html exception: {e}") | ||
if dataSet is None: | ||
# get the new data | ||
data = {} | ||
|
||
# data['item'] = {} | ||
# for i in self.plugin.items: | ||
# data['item'][i]['value'] = self.plugin.getitemvalue(i) | ||
# | ||
# return it as json the the web page | ||
# try: | ||
# return json.dumps(data) | ||
# except Exception as e: | ||
# self.logger.error("get_data_html exception: {}".format(e)) | ||
return {} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.