Integration von CarConnectivity

Begonnen von Prof. Dr. Peter Henning, 06 April 2026, 06:01:25

Vorheriges Thema - Nächstes Thema

Prof. Dr. Peter Henning

Da CarConnectivity inzwischen auf mehr Fahrzeugtypen ausgeweitet wird, mache ich dafür einen neuen Thread auf.

Zitat von: Prof. Dr. Peter Henning am 29 November 2025, 16:48:05Nach kurzer Diskussion mit Till Steinbach hat dieser die Version 0.9.3 des Carconnectivity-connector-volkswagen freigegeben. Darin sind jetzt auch die Daten für Türen und Fenster drin, prima. Man muss nur in der Konfiguration setzen

Zitat"force_enable_access": true // To allow for door/window state

Jetzt fehlt von den kritischen Readings nur noch die Überwachung des 12V-Batterielevel.


Till Steinbach, der Maintainer von carconnectivity, sucht einen Renault/Dacia-Nutzer, um seine Software auf diese Fahrzeugfamilie auszudehnen. Siehe hier https://github.com/tillsteinbach/CarConnectivity-plugin-mqtt/issues/147#issuecomment-4106736672

Hier der erste Code dafür: https://github.com/tillsteinbach/CarConnectivity-connector-renaultdacia/

LG

pah

P.S.: Vorschlag zwar von mir, aber der Dacia meiner Tochter kommt erst in ein paar Monaten


trupf

#1
Ich poste hier mal meine FHEM-Device-Definition dazu. So bekommt man eine gute Anzeige mit ähnlichen Informationen wie bei weconnect. Die DbLogInclude-Werte nutze ich dann für eine Trendanzeige in Grafana. Die von carconnectivity geposteten Werte zu den verfügbaren MQTT-Readings und zu den Plugins habe ich bewußt weggelassen, da sie das Device nur unnötig aufblasen. Vergesst nicht die "<vin>" im Code für das devicetopic mit Eurer zu ersetzen!

defmod ID3 MQTT2_DEVICE myBroker
attr ID3 DbLogExclude .*
attr ID3 DbLogInclude primary_level:300,odometer:300
attr ID3 autocreate 0
attr ID3 devStateIcon { my $soc      = ReadingsVal($name,"primary_level",0);;\
  my $con_state = ReadingsVal($name,"connection_state","disconnected");;\
\
  # Punkt (Verbindung)\
  my $dot = (time - ::time_str2num(ReadingsTimestamp("ID3","connection_state",0)) < 600 and \
    ($con_state eq "online" or $con_state eq "reachable")) ? "10px-kreis-gruen" : "10px-kreis-rot";;\
  # Schloss\
  my $lockIcon  = ReadingsVal($name,"doors_lock_state","unknown") eq "locked" ? "secur_locked" : "secur_open";;\
  # Batterie / Laden\
  my $chargeIcon;;\
  if ($soc >= 90) {$chargeIcon = 'battery_90';;}\
    elsif ($soc >= 80) {$chargeIcon = 'battery_80';;}\
    elsif ($soc >= 70) {$chargeIcon = 'battery_70';;}\
    elsif ($soc >= 60) {$chargeIcon = 'battery_60';;}\
    elsif ($soc >= 50) {$chargeIcon = 'battery_50';;}\
    elsif ($soc >= 40) {$chargeIcon = 'battery_40';;}\
    elsif ($soc >= 30) {$chargeIcon = 'battery_30';;}\
    elsif ($soc >= 20) {$chargeIcon = 'battery_20';;}\
    elsif ($soc >= 10) {$chargeIcon = 'battery_10';;}\
    else  {$chargeIcon = 'battery_0';;}\
  if ($soc >= 80) {\
    $chargeIcon =  $chargeIcon .'@green';;\
  } else {\
    if (ReadingsVal($name,"state","unknown") eq "charging") {$chargeIcon = $chargeIcon .'@cyan';;}\
      elsif (ReadingsVal($name,"connector_connection_state","disconnected") eq "connected") {$chargeIcon = $chargeIcon .'@blue';;}\
      else {$chargeIcon = $chargeIcon .'@orange';;}\
  }\
  return\
    '<div style="display:flex;;align-items:center;;gap:4px;;">'\
      # Linke Spalte (Punkt + Schloss untereinander)\
      .'<div style="display:flex;;flex-direction:column;;align-items:center;;gap:10px">'\
      .FW_makeImage($dot).FW_makeImage($lockIcon).FW_makeImage($chargeIcon)\
      .'<span>'.sprintf("%.0f%%", $soc).'</span>'.'</div>'\
      # Rechte Spalte\
      .'<div style="display:flex;;flex-direction:column;;align-items:center;;gap:0px;;">'\
      .'<a href="https://www.google.com/maps/place/'.ReadingsVal($name,"position_latitude",0).','\
      .ReadingsVal($name,"position_longitude",0).'" target="_blank">'\
      .'<img src="/fhem/images/'.$name.'-picture.png" style="max-width:200px;; max-height:200px;;"></a>'\
      .'<span>'.sprintf("Laden: %.1f kW", ReadingsVal($name,"power",0)).'</span></div>'\
    .'</div>';;\
}
attr ID3 devicetopic carconnectivity/0/garage/<vin>
attr ID3 group Auto
attr ID3 icon car
attr ID3 readingList $DEVICETOPIC/((?!images)\w+):.* { $TOPIC =~ m,$DEVICETOPIC/(\w+),;; { "${1}"=>$EVENT }}\
$DEVICETOPIC/images/car_picture:.* {WriteFile("www/images/$NAME-picture.png",$EVENT);;;;}\
$DEVICETOPIC/drives/(\w+):.* { $TOPIC =~ m,drives/(\w+),;; { "${1}"=>$EVENT }}\
$DEVICETOPIC/drives/(\w+)/(\w+):.* { $TOPIC =~ m,drives/(\w+)/(\w+),;; { "${1}_${2}"=>$EVENT }}\
$DEVICETOPIC/drives/(\w+)/(\w+)/(\w+):.* { $TOPIC =~ m,drives/(\w+)/(\w+)/(\w+),;; { "${1}_${2}_${3}"=>$EVENT }}\
$DEVICETOPIC/doors/(\w+):.* { $TOPIC =~ m,doors/(\w+),;; { "doors_${1}"=>$EVENT }}\
$DEVICETOPIC/doors/(\w+)/(\w+):.* { $TOPIC =~ m,doors/(\w+)/(\w+),;; { "doors_${1}_${2}"=>$EVENT }}\
$DEVICETOPIC/windows/(\w+):.* { $TOPIC =~ m,windows/(\w+),;; { "windows_${1}"=>$EVENT }}\
$DEVICETOPIC/windows/(\w+)/(\w+):.* { $TOPIC =~ m,windows/(\w+)/(\w+),;; { "windows_${1}_${2}"=>$EVENT }}\
$DEVICETOPIC/lights/(\w+):.* { $TOPIC =~ m,lights/(\w+),;; { "${1}"=>$EVENT }}\
$DEVICETOPIC/lights/(\w+)/(\w+):.* { $TOPIC =~ m,lights/(\w+)/(\w+),;; { "${1}_${2}"=>$EVENT }}\
$DEVICETOPIC/position/(\w+):.* { $TOPIC =~ m,position/(\w+),;; { "position_${1}"=>$EVENT }}\
$DEVICETOPIC/position/(\w+)/(\w+):.* { $TOPIC =~ m,position/(\w+)/(\w+),;; { "location_${2}"=>$EVENT }}\
$DEVICETOPIC/climatization/(\w+):.* { $TOPIC =~ m,climatization/(\w+),;; { "climatization_${1}"=>$EVENT }}\
$DEVICETOPIC/climatization/(\w+)/(\w+):.* { $TOPIC =~ m,climatization/(\w+)/(\w+),;; { "climatization_${2}"=>$EVENT }}\
$DEVICETOPIC/window_heating/(\w+):.* { $TOPIC =~ m,window_heating/(\w+),;; { "${1}"=>$EVENT }}\
$DEVICETOPIC/window_heating/(\w+)/(\w+):.* { $TOPIC =~ m,window_heating/(\w+)/(\w+),;; { "${1}_${2}"=>$EVENT }}\
$DEVICETOPIC/maintenance/(\w+):.* { $TOPIC =~ m,maintenance/(\w+),;; { "${1}"=>$EVENT }}\
$DEVICETOPIC/is_active:.* is_active\
$DEVICETOPIC/charging/(\w+):.* { $TOPIC =~ m,charging/(\w+),;; { "${1}"=>$EVENT }}\
$DEVICETOPIC/charging/(\w+)/(\w+):.* { $TOPIC =~ m,charging/(\w+)/(\w+),;; { "${1}_${2}"=>$EVENT }}\
carconnectivity/0/connectors/(\w+)/(\w+)/(\w+):.* { $TOPIC =~ m,connectors/(\w+)/(\w+)/(\w+),;; { "${1}_${2}_${3}"=>$EVENT }}\
carconnectivity/0/connectors/(\w+)/(\w+):.* { $TOPIC =~ m,connectors/(\w+)/(\w+),;; { "${1}_${2}"=>$EVENT }}\
carconnectivity/0/version:.* carconnectivity_version
attr ID3 room Auto,MQTT2_DEVICE,Strom->Photovoltaik
attr ID3 setList update:start,stop carconnectivity/0/commands/update_writetopic $EVTPART1\
volkswagen_interval carconnectivity/0/connectors/volkswagen/interval_writetopic $EVTPART1\
charging:start,stop $DEVICETOPIC/charging/commands/start-stop_writetopic $EVTPART1\
settings_maximum_current:maximum,reduced $DEVICETOPIC/charging/settings/maximum_current_writetopic $EVTPART1\
settings_target_level:slider,0,10,100 $DEVICETOPIC/charging/settings/target_level_writetopic $EVTPART1\
climatization:start,stop $DEVICETOPIC/climatization/commands/start-stop_writetopic $EVTPART1\
climatization_without_external_power:on,off $DEVICETOPIC/climatization/settings/climatization_without_external_power_writetopic $EVTPART1\
climatization_at_unlock:true,false $DEVICETOPIC/climatisation/settings/climatization_at_unlock_writetopic $EVTPART1\
climatization_target_temperature $DEVICETOPIC/climatization/settings/target_temperature_writetopic $EVTPART1\
wake-sleep:wake,sleep $DEVICETOPIC/commands/wake-sleep_writetopic $EVTPART1\
window_heating:start,stop $DEVICETOPIC/window_heating/commands/start-stop_writetopic $EVTPART1
attr ID3 stateFormat doors_lock_state, primary_level %, connector_connection_state
attr ID3 userReadings carImage { '<html><img src="fhem/images/' . $name . '-picture.png" style="max-width:256px;; max-height:256px;;"></html>' }
attr ID3 verbose 0

Turtle

#2
Hallo Zusammen,

ich habe mir von Codex ein FHEM-Modul bauen lassen, das carconnectivity-cli nutzt:

Wer es testen will so wird es konfiguriert.

CarConnectivity
FHEM Modul fuer carconnectivity-cli. Das Modul installiert CLI und Connector in eine eigene Python-venv, liest Volkswagen, Skoda, Seat, Cupra, Audi Fahrzeuge ohne MQTT aus. Beim Loeschen des FHEM-Devices entfernt das Modul automatisch den kompletten eigenen Installationsordner und das gespeicherte Passwort.

Define:
define <name> CarConnectivity

Beispiel fuer einen VW ID.3:
define ID3 CarConnectivity
attr ID3 connector volkswagen
attr ID3 username deine@mail.de
set ID3 password deinPasswort
set ID3 install

22.05.2026
Ich habe das Poll-Verhalten etwas verändert. Vorher konnte es bei einem fehlgeschlagenen Poll bis zu 15 Minuten dauern, bis erneut ein Poll ausgeführt wurde. Außerdem habe ich das Klimatisieren angepasst.

neue Version 0.2.22

Prof. Dr. Peter Henning

Ich rede mir echt den Mund fusselig darüber, aber offenbar sind viele immer noch arg naiv.

1. Das ist ein ganzes Modul, das von einer generativen KI stammt. Mit hoher Wahrscheinlichkeit handelt es sich dabei um eine Urheberrechtsverletzung - weil Codebestandteile verwendet wurden, die ganz bestimmten Lizenzen unterliegen. Und sei es auch nur der GPL, die immerhin die Namensnennung der originalen Urheber fordert.

2. Wenn man KI-generierten Code publiziert, sollte dieser _in der Datei_ als solche gekennzeichnet werden.

LG

pah

Turtle

Danke fürs Mund-fusselig-Reden ;D  – ich habe den Hinweis aufgenommen und im Modul ergänzt:

###############################################################################
# 98_CarConnectivity.pm
# FHEM wrapper module for carconnectivity-cli
#
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2026 Turtle
#
# AI-assisted implementation: created and iterated with OpenAI Codex
# under user direction.
#
# This module does not include source code from carconnectivity-cli.
# It installs and uses carconnectivity-cli and connector packages as external
# Python dependencies. Those packages are MIT licensed by their respective
# authors.
###############################################################################

Damit ist im Modul selbst klar gekennzeichnet, dass es KI-unterstützt erstellt wurde, und die Lizenz ist ebenfalls direkt in der Datei angegeben.

Gruß
Turtle

Prof. Dr. Peter Henning

Gut, prompte Reaktion.

Im Header wären für die Aufnahme in die FHEM-Distribution noch ein paar Anforderungen zu erfüllen.
Und natürlich ist https://wiki.fhem.de/wiki/DevelopmentModuleIntro zu beachten.

LG

pah