Ladezustand des Nissan Leaf nutzbar machen: Unterschied zwischen den Versionen
C2j2 (Diskussion | Beiträge) (Daten der "LeafSpy"-App in FHEM nutzbar zu machen, um die Nissan Leaf-Informationen in FHEM nutzen zu können) |
C2j2 (Diskussion | Beiträge) K (Reihenfolge logischer ;)) |
||
(13 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
'''Leaf Spy''' ist eine App für das Elektroauto '''Nissan Leaf''', die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter: | == Idee: Ladezustand des Leaf in FHEM nutzbar zu machen == | ||
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos '''Nissan Leaf''' (ZE0 und ZE1) in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird - wie empfohlen - das Auto beispielsweise bis maximal 80% geladen, um den Akku nicht durch Volladung stärker als nötig zu belasten: | |||
<syntaxhighlight lang=perl> | |||
my $leafBatSOC = ReadingsNum("Leaf", "BatterySOC", 0); | |||
my $leafBatSOCMax = ReadingsNum("MaxSOC", "state", 100); | |||
if ($leafBatSOC < $leafBatSOCMax) | |||
{ | |||
// charge | |||
} | |||
else | |||
{ | |||
// do not charge | |||
} | |||
</syntaxhighlight> | |||
Das Ganze sieht dann so aus: | |||
[[Datei:Ladesteuerung an der PV-Anlage.png|noframe|Ladesteuerung an der PV-Anlage]] | |||
wobei die Abschaltlogik hier im Bild noch nicht implementiert ist, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird - und da fehlt dann nur noch das Abschalten. | |||
== Vorgehensweise == | |||
Es gibt zwei Möglichkeiten, an die internen Werte des '''Leaf''' heranzukommen: | |||
# über die Smartphone-App '''Leaf Spy''' | |||
# über eine Abfrage über eine Web-URL ('''CARWINGS-API''') | |||
=== Alternative '''Leaf Spy''' === | |||
'''Leaf Spy''' ist eine Smartphone-App für das Elektroauto '''Nissan Leaf''', die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter: | |||
[http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und | [http://www.electricvehiclewiki.com/Leaf_Spy_Pro Leaf_Spy_Pro Wiki] und | ||
[http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App] | [http://www.leafspypro.com/wp-content/uploads/2017/09/LeafSpy-Help-1_2_1-iOS.pdf Dokumentation der App] | ||
'''Leaf Spy''' kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben. | '''Leaf Spy''' kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben. Und das in kurzen Intervallen, wenn man möchte. | ||
Um nun beispielsweise des SOC ("State of Charge")-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware für das Laden haben | Um nun beispielsweise des SOC ("State of Charge")-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben. | ||
Also braucht man einen kleinen Server, der die HTTP-Daten vom '''Leaf Spy''' empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen. | Also braucht man einen kleinen Server, der die HTTP-Daten vom '''Leaf Spy''' empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen. | ||
Was liegt näher, als diesen Server auf dem ''Raspberry Pi'' einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. | Was liegt näher, als diesen Server auf dem ''Raspberry Pi'' einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist "Flask", der die REST-URL im Handumdrehen auseinandernimmt. | ||
==== Voraussetzungen: ==== | ==== Voraussetzungen: ==== | ||
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte). | |||
* eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte). | |||
* LeafSpy installiert und funktionsfähig | * LeafSpy installiert und funktionsfähig | ||
==== | ==== Die Arbeit ==== | ||
* "Flask" installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung "venv" einrichten - findet man aber alles irgendwie: Stichwörter sind also "Flask" und "venv"). Das ist der Hauptschritt. | * "Flask" installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung "venv" einrichten - findet man aber alles irgendwie: Stichwörter sind also "Flask" und "venv"). Das ist der Hauptschritt. | ||
* ein kleines Python-Skript als "Proxy" einrichten (siehe unten), | * ein kleines Python-Skript als "Proxy" einrichten (siehe unten), kann man z.B. in "/home/pi/leaf-fhem-bridge/" unterbringen | ||
* und | * und eine Dummy-Variable "Leaf" FHEM einrichten mit diversen Readings ("BatterySOC" etc), die durch das Python-Script gesetzt werden. Siehe auch unten. | ||
* in FHEM die <code>WEBapi</code> einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff | * in FHEM die <code>WEBapi</code> einrichten ([[CsrfToken-HowTo]]) für den problemlosen internen Zugriff | ||
* | * Testen mit "http://raspberrypi:5000/app?SOC=80", dann müßte im FHEM im korrespondierende Dummy "Leaf" das Reading "BatterySOC" auf 80 gesetzt werden. | ||
* wenn alles klappt, diesen Flask-Server bei jedem Boot des ''Raspiberry Pi'' starten lassen (Google...) | |||
* von außen testen über "https://meine-IP/leaf?SOC=80" - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen... | * von außen testen über "https://meine-IP/leaf?SOC=80" - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen... | ||
Bei mir ist das alles derzeit noch "Trockenübung", da mein Auto noch nicht hier in der Garage steht. Ich hoffe dass das <code>return ""</code> in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren. | Bei mir ist das alles derzeit noch "Trockenübung", da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das <code>return ""</code> in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren. | ||
=== Alternative '''CARWINGS''' API === | |||
Diese API (Zugriff über einen Internet-Request auf eine feste Seite des Betreibers mit zum Auto passenden Zugangsdaten) ist die "offizielle" Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte. | |||
Vorteile: | |||
* nicht abhängig vom Akku eines Smartphones (dessen Verbrauch kann aber optimiert werden mit Tasker, AutomateIt und ähnlichen Apps) | |||
* man kann auch die Klimatisierung ein- und ausstellen | |||
* und den Ort des Autos abfragen. | |||
Nachteile: | |||
* langsames Update: eine SOC-Abfrage braucht knapp 2 Minuten (was aber egal ist, da das eh periodisch durchgeführt wird) | |||
Dazu habe ich mittlerweile ein Modul für FHEM gebaut, dass das alles in FHEM einbindbar ist: [https://forum.fhem.de/index.php/topic,92163.0.html]. | |||
Mittlerweile setze ich voll auf dieses Modul. | |||
== | == Anhänge == | ||
<syntaxhighlight> | ==== Das Server-Skript für Leaf Spy ==== | ||
Das Skript, das (auf dem ''Raspberry Pi'' mit dem Aufruf "phython <skriptname>.py" gestartet wird: | |||
<syntaxhighlight lang=py> | |||
import urllib | import urllib | ||
import urllib2 | import urllib2 | ||
Zeile 45: | Zeile 98: | ||
def post_fhem(key, value): | def post_fhem(key, value): | ||
url = "http://127.0.0.1:8088/fhem?cmd= | # Annahme: läuft auf dem gleichen RASPI wie FHEM | ||
# Annahme: WEBapi benutzt Port 8088 | |||
url = "http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20" + key + "%20" + value + "&XHR=1" | |||
req = urllib2.Request(url) | req = urllib2.Request(url) | ||
response = urllib2.urlopen(req) | response = urllib2.urlopen(req) | ||
Zeile 54: | Zeile 109: | ||
def api_echo(): | def api_echo(): | ||
if 'SOC' in request.args: | if 'SOC' in request.args: | ||
post_fhem(' | post_fhem('BatterySOC', request.args['SOC']) | ||
if 'Ahr' in request.args: | if 'Ahr' in request.args: | ||
post_fhem(' | post_fhem('BatteryCapacity', request.args['Ahr']) | ||
if 'BatTemp' in request.args: | if 'BatTemp' in request.args: | ||
post_fhem(' | post_fhem('BatteryTemp', request.args['BatTemp']) | ||
if 'Gids' in request.args: | if 'Gids' in request.args: | ||
post_fhem(' | post_fhem('BatteryGids', request.args['Gids']) | ||
if 'Amb' in request.args: | if 'Amb' in request.args: | ||
post_fhem(' | post_fhem('AmbientTemp', request.args['Amb']) | ||
if 'DevBat' in request.args: | if 'DevBat' in request.args: | ||
post_fhem(' | post_fhem('SmartphoneSOC', request.args['DevBat']) | ||
return "" | return "" | ||
Zeile 70: | Zeile 125: | ||
app.run(debug=True, host='0.0.0.0', port=5000) | app.run(debug=True, host='0.0.0.0', port=5000) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== und der dazu passende '''Leaf'''-Dummy ==== | |||
Internals: | |||
CFGFN | |||
NAME Leaf | |||
NR 3481 | |||
STATE SOC=79% Gids=88, Temp=50°C | |||
TYPE dummy | |||
Attributes: | |||
readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC | |||
room Auto | |||
stateFormat { sprintf("SOC=%d%% Gids=%d, Temp=%d°C", ReadingsNum("Leaf", "BatterySOC", 0), ReadingsNum("Leaf", "BatteryGids", 0), ReadingsNum("Leaf", "AmbientTemp", 0)); } | |||
[[Kategorie:Examples]] | |||
[[Kategorie:Code Snippets]] |
Aktuelle Version vom 30. Dezember 2018, 16:52 Uhr
Idee: Ladezustand des Leaf in FHEM nutzbar zu machen
Hier wird beschrieben, wie man auf den Ladezustand des Antriebsakkus eines Elektroautos Nissan Leaf (ZE0 und ZE1) in FHEM zugreifen kann. Dadurch kann man - beispielsweise über eine mehr oder weniger intelligente Perl-Routine - den Ladevorgang abbrechen, wenn das Auto den entsprechenden Maximal-SOC erreicht hat. Somit wird - wie empfohlen - das Auto beispielsweise bis maximal 80% geladen, um den Akku nicht durch Volladung stärker als nötig zu belasten:
my $leafBatSOC = ReadingsNum("Leaf", "BatterySOC", 0);
my $leafBatSOCMax = ReadingsNum("MaxSOC", "state", 100);
if ($leafBatSOC < $leafBatSOCMax)
{
// charge
}
else
{
// do not charge
}
Das Ganze sieht dann so aus:
wobei die Abschaltlogik hier im Bild noch nicht implementiert ist, aber man sieht, wie die Lade-Leistung mit der Photovoltaikleistung geregelt wird - und da fehlt dann nur noch das Abschalten.
Vorgehensweise
Es gibt zwei Möglichkeiten, an die internen Werte des Leaf heranzukommen:
- über die Smartphone-App Leaf Spy
- über eine Abfrage über eine Web-URL (CARWINGS-API)
Alternative Leaf Spy
Leaf Spy ist eine Smartphone-App für das Elektroauto Nissan Leaf, die interne Daten aus dem Leaf per Bluetooth ODB II-Adapter auslesen und darstellen kann wie Akkuzustand, Ladezustand, ... Innenraumtemperatur und so weiter:
Leaf_Spy_Pro Wiki und Dokumentation der App
Leaf Spy kann diese Daten glücklicherweise an einen Server per REST-API (HTTP-Request mit den Werten als Parameter) übergeben. Und das in kurzen Intervallen, wenn man möchte.
Um nun beispielsweise des SOC ("State of Charge")-Wert des Fahrakkus nutzen zu können, um die Ladung der Akkuschonung wegen nur bis 80% SOC durchzuführen, würde man die Daten gern in der Automationssoftware FHEM für das Laden haben.
Also braucht man einen kleinen Server, der die HTTP-Daten vom Leaf Spy empfängt und an FHEM weiterreicht, um dort Dummy-Variablen zur Weiterverarbeitung zu setzen.
Was liegt näher, als diesen Server auf dem Raspberry Pi einzurichten, auf dem auch FHEM läuft? Der langweilt sich doch eh zu Tode. Eine Möglichkeit dazu ist "Flask", der die REST-URL im Handumdrehen auseinandernimmt.
Voraussetzungen:
- eine konstante IP oder per DynDNS ansprechbare Adresse haben, über die der Raspi von außen ansprechbar ist (hat man vermutlich ohnehin, wenn man FHEM von außen erreichen möchte).
- LeafSpy installiert und funktionsfähig
Die Arbeit
- "Flask" installieren (bitte im Netz schauen, welches - hängt von der auf dem Raspi installierten Python-Version ab, gegebenenfalls muß man eine virtuelle Umgebung "venv" einrichten - findet man aber alles irgendwie: Stichwörter sind also "Flask" und "venv"). Das ist der Hauptschritt.
- ein kleines Python-Skript als "Proxy" einrichten (siehe unten), kann man z.B. in "/home/pi/leaf-fhem-bridge/" unterbringen
- und eine Dummy-Variable "Leaf" FHEM einrichten mit diversen Readings ("BatterySOC" etc), die durch das Python-Script gesetzt werden. Siehe auch unten.
- in FHEM die
WEBapi
einrichten (CsrfToken-HowTo) für den problemlosen internen Zugriff
- Testen mit "http://raspberrypi:5000/app?SOC=80", dann müßte im FHEM im korrespondierende Dummy "Leaf" das Reading "BatterySOC" auf 80 gesetzt werden.
- wenn alles klappt, diesen Flask-Server bei jedem Boot des Raspiberry Pi starten lassen (Google...)
- von außen testen über "https://meine-IP/leaf?SOC=80" - natürlich sind der Name und der Redirect entsprechend anzupassen, gegebenenfalls über Port-Angabe. Da kocht jeder sein eigenes Süppchen...
Bei mir ist das alles derzeit noch "Trockenübung", da mein Auto noch nicht hier in der Garage steht. Ich hoffe, dass das return ""
in Ordnung ist, mangels Auto kann ich das noch nicht testen. Ich werde das notfalls hier korrigieren.
Alternative CARWINGS API
Diese API (Zugriff über einen Internet-Request auf eine feste Seite des Betreibers mit zum Auto passenden Zugangsdaten) ist die "offizielle" Methode, an die Daten heranzukommen - und man kann damit beispielsweise auch die Klimaanlage steuern. Also geeignet für ehrgeizigere Projekte.
Vorteile:
- nicht abhängig vom Akku eines Smartphones (dessen Verbrauch kann aber optimiert werden mit Tasker, AutomateIt und ähnlichen Apps)
- man kann auch die Klimatisierung ein- und ausstellen
- und den Ort des Autos abfragen.
Nachteile:
- langsames Update: eine SOC-Abfrage braucht knapp 2 Minuten (was aber egal ist, da das eh periodisch durchgeführt wird)
Dazu habe ich mittlerweile ein Modul für FHEM gebaut, dass das alles in FHEM einbindbar ist: [1]. Mittlerweile setze ich voll auf dieses Modul.
Anhänge
Das Server-Skript für Leaf Spy
Das Skript, das (auf dem Raspberry Pi mit dem Aufruf "phython <skriptname>.py" gestartet wird:
import urllib
import urllib2
from flask import Flask
from flask import request
app = Flask(__name__)
def post_fhem(key, value):
# Annahme: läuft auf dem gleichen RASPI wie FHEM
# Annahme: WEBapi benutzt Port 8088
url = "http://127.0.0.1:8088/fhem?cmd=setreading%20Leaf%20" + key + "%20" + value + "&XHR=1"
req = urllib2.Request(url)
response = urllib2.urlopen(req)
page = response.read()
return page
@app.route('/app', methods = ['GET', 'POST'])
def api_echo():
if 'SOC' in request.args:
post_fhem('BatterySOC', request.args['SOC'])
if 'Ahr' in request.args:
post_fhem('BatteryCapacity', request.args['Ahr'])
if 'BatTemp' in request.args:
post_fhem('BatteryTemp', request.args['BatTemp'])
if 'Gids' in request.args:
post_fhem('BatteryGids', request.args['Gids'])
if 'Amb' in request.args:
post_fhem('AmbientTemp', request.args['Amb'])
if 'DevBat' in request.args:
post_fhem('SmartphoneSOC', request.args['DevBat'])
return ""
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
und der dazu passende Leaf-Dummy
Internals: CFGFN NAME Leaf NR 3481 STATE SOC=79% Gids=88, Temp=50°C TYPE dummy Attributes: readingList BatterySOC,BatteryGids,BatteryTemp,BatteryCapacity,AmbientTemp,SmartphoneSOC room Auto stateFormat { sprintf("SOC=%d%% Gids=%d, Temp=%d°C", ReadingsNum("Leaf", "BatterySOC", 0), ReadingsNum("Leaf", "BatteryGids", 0), ReadingsNum("Leaf", "AmbientTemp", 0)); }