Ora Funky Cat

Aus FHEMWiki

Auf dieser Seite wird die Einbindung des E-Autos Ora Funky Cat von GWM (Great Wall Motor aus China) in FHEM über die OBD2-Serviceschnittestelle erläutert.

Benötigte Hardware: MeatPi WiCAN-OBD-C3 Adapter

Der WiCAN wird in die OBD2-Serviceschnittestelle (rechts neben Sicherungsfach unterhalb Lenkrad) gesteckt. Am besten über ein Verlängerungskabel oder indem man den OBD2-Stecker aus der Halterung drückt und mit dem WiCAN ins Sicherungsfach legt.

Der WiCAN kommuniziert über den CAN-Bus des Fahrzeuges mit den Steuergeräten (ECU, Eletronic Control Unit) im Ora und kann sich über WLAN mit eine MQTT-Server verbinden. Näheres im obigen Link. Bei der WiCAN-Konfiguration mus das CAN-Protokoll "slcan" ausgewählt werden. Die Kommunikation erfolgt über den Eintrag can/tx und can/rx des WiCAN auf dem MQTT-Server. Bitte nicht vergessen, den automatischen Standby-Modus anzuschalten, ansonsten leert sich mit der Zeit die Fahrzeugbatterie.

Die Integration eines MQTT-Servers in FHEM wird hier erklärt.

Ist das Auto eingeschaltet und der Adapter gesteckt, dann können über FHEM einige Fahrzeugdaten abgefragt werden. Weiter unten eine beispielhafte EInrichtung eines MQTT2-Devices.

Readings

Die folgenden Werte werden mit unterer Beispielkonfiguration aus den Steuergeräten VCU (Vehicle Control Unit, ECU CAN-ID: 1930, Response CAN-ID: 1994) und BMSv2 (Batterie Management System, ECU CAN-ID: 1931, Response CAN-ID: 1995) ausgelesen:

  • Mileage: km-Stand - Abfrage über "set wican read_Mileage"
  • SoC: Ladezustand Hochvolt-Antriebsbatterie in % - Abfrage über "set wican read_SoC"
  • TrueSoC: ein zweiter Wert. Hintergrund ist unbekannt - Abfrage über "set wican read_TrueSoC"
  • SoE: Ladezustand Hochvolt-Antriebsbatterie in kW - Abfrage über "set wican read_SoE"
  • SoH: Gesundheitszustand der Hochvolt-Antriebsbatterie in % - Abfrage über "set wican read_SoH"
  • OperatingVoltage: Spannung Niedervolt-Fahrzeugbatterie in V - Abfrage über "set wican read_OperatingVoltage"
  • BatteryVoltage: Spannung Hochvolt-Antriebsbatterie in V - Abfrage über "set wican read_BatteryVoltage"
  • TotalCharge: Durch die Batterie aufgenommene Stromleistung in Ah (inklusive Rekuperation während des Fahrens) - Abfrage über "set wican read_Total Charge" Die Multiplikation mit 5 kV scheint die hinzugefügte elektrische Leistung zu ergeben.
  • TotalDischarge: Von der Hochvolt-Batterie abgezogene Stromleistung in Ah - Abfrage über "set wican read_TotalDischarge" Die Multiplikation mit 5 kV scheint die abgerufene elektrische Leistung zu ergeben.

Das erste Auslesen kann über ein notify angestossen werden, sobald der WiCAN den Status "online" hat.

define wican_online notify wican:status:.online set wican read_SoC;; sleep 1;; set wican read_TrueSoC;; sleep 1;; set wican read_Mileage;; sleep 1;; set wican read_OpVoltage;; sleep 1;; set wican read_SoH;; sleep 1;; set wican read_TotalCharge;; sleep 1;; set wican read_TotalDischarge;; sleep 1;; set wican read_BatteryVoltage;; sleep 1;; set wican read_SoE

Die weiteren Abfrage können über einen Timer erfolgen Der Timer kann mit einem notify ein- und wieder ausgeschaltet werden.

define wican_check at +*00:01:00 set wican read_SoC;; sleep 1;; set wican read_TrueSoC;; sleep 1;; set wican read_Mileage;; sleep 1;; set wican read_OpVoltage;; sleep 1;; set wican read_SoH;; sleep 1;; set wican read_TotalCharge;; sleep 1;; set wican read_TotalDischarge;; sleep 1;; set wican read_BatteryVoltage;; sleep 1;; set wican read_SoE

define wican_check_active notify wican:status:.online set wican_check active

define wican_check_inactive notify wican:status:.offline set wican_check inactive

Beispielhafte Einrichtung des WiCAN im Ora Funky Cat als MQTT2-Device

Ab der WiCAN Firmware v2.98 (13. April 2024) kann die Benennung des Eintrages im MQTT-Server frei gewählt werden. Die untere Konfiguration geht von folgender Benennung aus:

  • TX Topic: wican/ora/can/tx
  • RX Topic: wican/ora/can/tx
  • Status Topic: wican/ora/can/status
define wican MQTT2_DEVICE
attr wican alias Ora
attr wican stateFormat B: SoC% M: Mileage km (status)
attr wican event-on-change-reading status
attr wican event-on-update-reading frame_1_data_6,SoC
attr wican DbLogExclude .*
attr wican DbLogInclude SoC:3600
attr wican readingList wican/ora/can/status:.* {json2nameValue($EVENT)}\
 wican/ora/can/rx:.* {json2nameValue($EVENT)}
attr wican setList read_SoC:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":49539,"frame":[{"id":1931,"dlc":8,"rtr":false,"extd":false,"data":[3,34,32,80,170,170,170,170]}]}\
read_TrueSoC:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":27825,"frame":[{"id":1931,"dlc":8,"rtr":false,"extd":false,"data":[3,34,3,8,170,170,170,170]}]}\
read_SoH:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":12016,"frame":[{"id":1931,"dlc":8,"rtr":false,"extd":false,"data":[3,34,32,81,170,170,170,170]}]}\
read_SoE:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":17777,"frame":[{"id":1930,"dlc":8,"rtr":false,"extd":false,"data":[3,34,208,98,170,170,170,170]}]}\
read_OpVoltage:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":17645,"frame":[{"id":1931,"dlc":8,"rtr":false,"extd":false,"data":[3,34,208,3,170,170,170,170]}]}\
read_Mileage:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":35674,"frame":[{"id":1931,"dlc":8,"rtr":false,"extd":false,"data":[3,34,208,4,170,170,170,170]}]}\
read_TotalCharge:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":28695,"frame":[{"id":1931,"dlc":8,"rtr":false,"extd":false,"data":[3,34,33,113,170,170,170,170]}]}\
read_TotalDischarge:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":28695,"frame":[{"id":1931,"dlc":8,"rtr":false,"extd":false,"data":[3,34,33,114,170,170,170,170]}]}\
read_BatteryVoltage:noArg wican/ora/can/tx {"bus":"0","type":"tx","ts":58591,"frame":[{"id":1931,"dlc":8,"rtr":false,"extd":false,"data":[3,34,32,3,170,170,170,170]}]}
attr wican userReadings SoC:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1995 and ReadingsNum($NAME, 'frame_1_data_1', 0)  == 5 and ReadingsNum($NAME, 'frame_1_data_2', 0)  == 98\
      and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 32 and ReadingsNum($NAME, 'frame_1_data_4', 0)  == 80 ) {\
		return (ReadingsNum($NAME, 'frame_1_data_5', 0) * 256+ReadingsNum($NAME, 'frame_1_data_6', 0))/10.0\
	} else {\
		return ReadingsNum($NAME, 'SoC', 0)\
	}\
},\
SoH:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1995 and ReadingsNum($NAME, 'frame_1_data_1', 0)  == 5 and ReadingsNum($NAME, 'frame_1_data_2', 0)  == 98\
      and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 32 and ReadingsNum($NAME, 'frame_1_data_4', 0)  == 81 ) {\
		return (ReadingsNum($NAME, 'frame_1_data_5', 0) * 256 + ReadingsNum($NAME, 'frame_1_data_6', 0))/10.0\
	} else {\
		return ReadingsNum($NAME, 'SoH', 0)\
	}\
},\
TrueSoC:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1995 and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 3) {\
		return (ReadingsNum($NAME, 'frame_1_data_5', 0) * 256 + ReadingsNum($NAME, 'frame_1_data_6', 0))/10.0\
	} else {\
		return ReadingsNum($NAME, 'TrueSoC', 0)\
	}\
},\
Mileage:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1995 and ReadingsNum($NAME, 'frame_1_data_1', 0)  == 6 and ReadingsNum($NAME, 'frame_1_data_2', 0)  == 98\
      and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 208 ) {\
		return ReadingsNum($NAME, 'frame_1_data_6', 0) * 256 + ReadingsNum($NAME, 'frame_1_data_7', 0)\
	} else {\
		return ReadingsNum($NAME, 'Mileage', 0)\
	}\
},\
OperatingVoltage:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1995 and ReadingsNum($NAME, 'frame_1_data_1', 0)  == 4 and ReadingsNum($NAME, 'frame_1_data_2', 0)  == 98\
      and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 208 ) {\
		return ReadingsNum($NAME, 'frame_1_data_5', 0) /10.0\
	} else {\
		return ReadingsNum($NAME, 'OperatingVoltage', 0)\
	}\
},\
TotalCharge:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1995 and ReadingsNum($NAME, 'frame_1_data_1', 0)  == 7 and ReadingsNum($NAME, 'frame_1_data_2', 0)  == 98\
      and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 33 and ReadingsNum($NAME, 'frame_1_data_4', 0)  == 113 ) {\
		return round( 2 * ReadingsNum($NAME, 'frame_1_data_7', 0) + ReadingsNum($NAME, 'frame_1_data_8', 0) / 128 , 0)\
	} else {\
		return ReadingsNum($NAME, 'TotalCharge', 0)\
	}\
},\
TotalDischarge:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1995 and ReadingsNum($NAME, 'frame_1_data_1', 0)  == 7 and ReadingsNum($NAME, 'frame_1_data_2', 0)  == 98\
  and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 33 and ReadingsNum($NAME, 'frame_1_data_4', 0)  == 114 ) {\
		return round( 2 * ReadingsNum($NAME, 'frame_1_data_7', 0) + ReadingsNum($NAME, 'frame_1_data_8', 0) / 128 , 0)\
	} else {\
		return ReadingsNum($NAME, 'TotalDischarge', 0)\
	}\
},\
BatteryVoltage:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1995 and ReadingsNum($NAME, 'frame_1_data_1', 0)  == 16 and ReadingsNum($NAME, 'frame_1_data_2', 0)  == 9\
      and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 98 and ReadingsNum($NAME, 'frame_1_data_4', 0)  == 32 ) {\
		return ( 256 * ReadingsNum($NAME, 'frame_1_data_6', 0) + ReadingsNum($NAME, 'frame_1_data_7', 0)) / 10.0 \
	} else {\
		return ReadingsNum($NAME, 'BatteryVoltage', 0)\
	}\
},\
SoE:frame_1_data_6:.* {\
	if (ReadingsNum($NAME, 'frame_1_id', 0) == 1994 and ReadingsNum($NAME, 'frame_1_data_1', 0)  == 7 and ReadingsNum($NAME, 'frame_1_data_2', 0)  == 98\
      and ReadingsNum($NAME, 'frame_1_data_3', 0)  == 208 and ReadingsNum($NAME, 'frame_1_data_4', 0)  == 98 ) {\
		return (256*ReadingsNum($NAME, 'frame_1_data_7', 0)+ReadingsNum($NAME, 'frame_1_data_8', 0)) / 10.0 \
	} else {\
		return ReadingsNum($NAME, 'SoE', 0)\
	}\
}