Merge pull request #1314 from dalathegreat/bugfix/tesla-CAN-improvements

Tesla: Simulate entire vehicle towards battery
This commit is contained in:
Daniel Öster 2025-07-22 15:38:14 +03:00 committed by GitHub
commit a23200971d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 1991 additions and 699 deletions

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,11 @@
#define SELECTED_BATTERY_CLASS TeslaModelSXBattery #define SELECTED_BATTERY_CLASS TeslaModelSXBattery
#endif #endif
/*NOTE! IMPORTANT INFORMATION!
Be sure to scroll down in this file and configure all "GTW_" parameters to suit your battery.
Failure to configure these will result in VCFRONT and GTW MIA errors
*/
//#define EXP_TESLA_BMS_DIGITAL_HVIL // Experimental parameter. Forces the transmission of additional CAN frames for experimental purposes, to test potential HVIL issues in 3/Y packs with newer firmware. //#define EXP_TESLA_BMS_DIGITAL_HVIL // Experimental parameter. Forces the transmission of additional CAN frames for experimental purposes, to test potential HVIL issues in 3/Y packs with newer firmware.
class TeslaBattery : public CanBattery { class TeslaBattery : public CanBattery {
@ -43,7 +48,25 @@ class TeslaBattery : public CanBattery {
static const int MAXDISCHARGEPOWERALLOWED = static const int MAXDISCHARGEPOWERALLOWED =
60000; // 60000W we use a define since the value supplied by Tesla is always 0 60000; // 60000W we use a define since the value supplied by Tesla is always 0
/* Do not change the defines below */ // Set this to true to try to close contactors/full startup even with no inverter defined/connected
bool batteryTestOverride = false;
// 0x7FF gateway config, "Gen3" vehicles only, not applicable to Gen2 "classic" Model S and Model X
//
// ** MANUALLY SET FOR NOW **, TODO: change based on USER_SETTINGS.h or preset
//
static const uint16_t GTW_country =
18242; // "US" (USA): 21843, "CA" (Canada): 17217, "GB" (UK & N Ireland): 18242, "DK" (Denmark): 17483, "DE" (Germany): 17477, "AU" (Australia): 16725 [HVP shows errors if EU/US region mismatch for example]
// GTW_country is ISO 3166-1 Alpha-2 code, each letter converted to binary (8-bit chunks), those 8-bit chunks concatenated and then converted to decimal
static const uint8_t GTW_rightHandDrive =
1; // Left: 0, Right: 1 (not sure this matters but there for consistency in emulating the car - make sure correct for GTW_country, e.g. 0 for USA)
static const uint8_t GTW_mapRegion =
1; // "ME": 8, "NONE": 2, "CN": 3, "TW": 6, "JP": 5, "US": 0, "KR": 7, "AU": 4, "EU": 1 (not sure this matters but there for consistency)
static const uint8_t GTW_chassisType =
2; // "MODEL_3_CHASSIS": 2, "MODEL_Y_CHASSIS": 3 ("MODEL_S_CHASSIS": 0, "MODEL_X_CHASSIS": 1)
static const uint8_t GTW_packEnergy = 1; // "PACK_50_KWH": 0, "PACK_74_KWH": 1, "PACK_62_KWH": 2, "PACK_100_KWH": 3
/* Do not change anything below this line! */
static const int RAMPDOWN_SOC = 900; // 90.0 SOC% to start ramping down from max charge power towards 0 at 100.00% static const int RAMPDOWN_SOC = 900; // 90.0 SOC% to start ramping down from max charge power towards 0 at 100.00%
static const int RAMPDOWNPOWERALLOWED = 10000; // What power we ramp down from towards top balancing static const int RAMPDOWNPOWERALLOWED = 10000; // What power we ramp down from towards top balancing
static const int FLOAT_MAX_POWER_W = 200; // W, what power to allow for top balancing battery static const int FLOAT_MAX_POWER_W = 200; // W, what power to allow for top balancing battery
@ -75,53 +98,391 @@ class TeslaBattery : public CanBattery {
unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was sent unsigned long previousMillis100 = 0; // will store last time a 100ms CAN Message was sent
unsigned long previousMillis500 = 0; // will store last time a 500ms CAN Message was sent unsigned long previousMillis500 = 0; // will store last time a 500ms CAN Message was sent
unsigned long previousMillis1000 = 0; // will store last time a 1000ms CAN Message was sent unsigned long previousMillis1000 = 0; // will store last time a 1000ms CAN Message was sent
bool alternate243 = false;
//0x221 545 VCFRONT_LVPowerState: "GenMsgCycleTime" 50ms //UDS session tracker
CAN_frame TESLA_221_1 = { //static bool uds_SessionInProgress = false; // Future use
.FD = false, //0x221 VCFRONT_LVPowerState
uint8_t muxNumber_TESLA_221 = 0;
uint8_t frameCounter_TESLA_221 = 15; // Start at 15 for Mux 0
uint8_t vehicleState = 1; // "OFF": 0, "DRIVE": 1, "ACCESSORY": 2, "GOING_DOWN": 3
uint16_t powerDownTimer = 180; // Car power down (i.e. contactor open) tracking timer, 3 seconds per sendingState
//0x2E1 VCFRONT_status, 6 mux tracker
uint8_t muxNumber_TESLA_2E1 = 0;
//0x334 UI
bool TESLA_334_INITIAL_SENT = false;
//0x3A1 VCFRONT_vehicleStatus, 15 frame counter (temporary)
uint8_t frameCounter_TESLA_3A1 = 0;
//0x3C2 VCLEFT_switchStatus
uint8_t muxNumber_TESLA_3C2 = 0;
//0x504 TWC_status
bool TESLA_504_INITIAL_SENT = false;
//0x7FF GTW_carConfig, 5 mux tracker
uint8_t muxNumber_TESLA_7FF = 0;
//Max percentage charge tracker
uint16_t previous_max_percentage = datalayer.battery.settings.max_percentage;
//0x082 UI_tripPlanning: "cycle_time" 1000ms
CAN_frame TESLA_082 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x082,
.data = {0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80}};
//0x102 VCLEFT_doorStatus: "cycle_time" 100ms
CAN_frame TESLA_102 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x102,
.data = {0x22, 0x33, 0x00, 0x00, 0xC0, 0x38, 0x21, 0x08}};
//0x103 VCRIGHT_doorStatus: "cycle_time" 100ms
CAN_frame TESLA_103 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x103,
.data = {0x22, 0x33, 0x00, 0x00, 0x30, 0xF2, 0x20, 0x02}};
//0x118 DI_systemStatus: "cycle_time" 50ms, DI_systemStatusChecksum/DI_systemStatusCounter generated via generateFrameCounterChecksum
CAN_frame TESLA_118 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x118,
.data = {0xAB, 0x60, 0x2A, 0x00, 0x00, 0x08, 0x00, 0x00}};
//0x2A8 CMPD_state: "cycle_time" 100ms, different depending on firmware, semi-manual increment for now
CAN_frame TESLA_2A8 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x2A8,
.data = {0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x2C}};
//0x213 UI_cruiseControl: "cycle_time" 500ms, UI_speedLimitTick/UI_cruiseControlCounter - different depending on firmware, semi-manual increment for now
CAN_frame TESLA_213 = {.FD = false, .ext_ID = false, .DLC = 2, .ID = 0x213, .data = {0x00, 0x15}};
//0x221 These frames will/should eventually be migrated to 2 base frames (1 per mux), and then just the relevant bits changed
//0x221 VCFRONT_LVPowerState "Drive"
//VCFRONT_vehiclePowerState VEHICLE_POWER_STATE_DRIVE (Mux0, Counter 15): "cycle_time" 50ms each mux/LVPowerStateIndex, VCFRONT_LVPowerStateChecksum/VCFRONT_LVPowerStateCounter generated via generateMuxFrameCounterChecksum
CAN_frame TESLA_221_DRIVE_Mux0 = {.FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 8, .DLC = 8,
.ID = 0x221, .ID = 0x221,
.data = {0x41, 0x11, 0x01, 0x00, 0x00, 0x00, 0x20, 0x96}}; //Contactor frame 221 - close contactors .data = {0x60, 0x55, 0x55, 0x15, 0x54, 0x51, 0xF1, 0xD8}};
CAN_frame TESLA_221_2 = {
.FD = false, //0x221 VCFRONT_LVPowerState "Drive"
//VCFRONT_vehiclePowerState VEHICLE_POWER_STATE_DRIVE (Mux1, Counter 0): "cycle_time" 50ms each mux/LVPowerStateIndex, VCFRONT_LVPowerStateChecksum/VCFRONT_LVPowerStateCounter generated via generateMuxFrameCounterChecksum
CAN_frame TESLA_221_DRIVE_Mux1 = {.FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 8, .DLC = 8,
.ID = 0x221, .ID = 0x221,
.data = {0x61, 0x15, 0x01, 0x00, 0x00, 0x00, 0x20, 0xBA}}; //Contactor Frame 221 - hv_up_for_drive .data = {0x61, 0x05, 0x55, 0x05, 0x00, 0x00, 0x00, 0xE3}};
//0x241 VCFRONT_coolant 100ms
//0x221 VCFRONT_LVPowerState "Accessory"
//VCFRONT_vehiclePowerState VEHICLE_POWER_STATE_ACCESSORY (Mux0, Counter 15): "cycle_time" 50ms each mux/LVPowerStateIndex, VCFRONT_LVPowerStateChecksum/VCFRONT_LVPowerStateCounter generated via generateMuxFrameCounterChecksum
CAN_frame TESLA_221_ACCESSORY_Mux0 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x221,
.data = {0x40, 0x55, 0x55, 0x05, 0x54, 0x51, 0xF5, 0xAC}};
//0x221 VCFRONT_LVPowerState "Accessory"
//VCFRONT_vehiclePowerState VEHICLE_POWER_STATE_ACCESSORY (Mux1, Counter 0): "cycle_time" 50ms each mux/LVPowerStateIndex, VCFRONT_LVPowerStateChecksum/VCFRONT_LVPowerStateCounter generated via generateMuxFrameCounterChecksum
CAN_frame TESLA_221_ACCESSORY_Mux1 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x221,
.data = {0x41, 0x05, 0x55, 0x55, 0x01, 0x00, 0x04, 0x18}};
//0x221 VCFRONT_LVPowerState "Going Down"
//VCFRONT_vehiclePowerState VEHICLE_POWER_STATE_OFF, key parts GOING_DOWN (Mux0, Counter 15): "cycle_time" 50ms each mux/LVPowerStateIndex, VCFRONT_LVPowerStateChecksum/VCFRONT_LVPowerStateCounter generated via generateMuxFrameCounterChecksum
CAN_frame TESLA_221_GOING_DOWN_Mux0 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x221,
.data = {0x00, 0x89, 0x55, 0x06, 0xA4, 0x51, 0xF1, 0xED}};
//0x221 VCFRONT_LVPowerState "Going Down"
//VCFRONT_vehiclePowerState VEHICLE_POWER_STATE_OFF, key parts GOING_DOWN (Mux1, Counter 0): "cycle_time" 50ms each mux/LVPowerStateIndex, VCFRONT_LVPowerStateChecksum/VCFRONT_LVPowerStateCounter generated via generateMuxFrameCounterChecksum
CAN_frame TESLA_221_GOING_DOWN_Mux1 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x221,
.data = {0x01, 0x09, 0x55, 0x59, 0x00, 0x00, 0x00, 0xDB}};
//0x221 VCFRONT_LVPowerState "Off"
//VCFRONT_vehiclePowerState VEHICLE_POWER_STATE_OFF, key parts OFF (Mux0, Counter 15): "cycle_time" 50ms each mux/LVPowerStateIndex, VCFRONT_LVPowerStateChecksum/VCFRONT_LVPowerStateCounter generated via generateMuxFrameCounterChecksum
CAN_frame TESLA_221_OFF_Mux0 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x221,
.data = {0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0xF1, 0x65}};
//0x221 VCFRONT_LVPowerState "Off"
//VCFRONT_vehiclePowerState VEHICLE_POWER_STATE_OFF, key parts OFF (Mux1, Counter 0): "cycle_time" 50ms each mux/LVPowerStateIndex, VCFRONT_LVPowerStateChecksum/VCFRONT_LVPowerStateCounter generated via generateMuxFrameCounterChecksum
CAN_frame TESLA_221_OFF_Mux1 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x221,
.data = {0x01, 0x01, 0x01, 0x50, 0x00, 0x00, 0x00, 0x76}};
//0x229 SCCM_rightStalk: "cycle_time" 100ms, SCCM_rightStalkChecksum/SCCM_rightStalkCounter generated via dedicated generateTESLA_229 function for now
//CRC seemingly related to AUTOSAR ID array... "autosarDataIds": [124,182,240,47,105,163,221,28,86,144,202,9,67,125,183,241] found in Model 3 firmware
CAN_frame TESLA_229 = {.FD = false, .ext_ID = false, .DLC = 3, .ID = 0x229, .data = {0x46, 0x00, 0x00}};
//0x241 VCFRONT_coolant: "cycle_time" 100ms
CAN_frame TESLA_241 = {.FD = false, CAN_frame TESLA_241 = {.FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 7, .DLC = 7,
.ID = 0x241, .ID = 0x241,
.data = {0x3C, 0x78, 0x2C, 0x0F, 0x1E, 0x5B, 0x00}}; .data = {0x35, 0x34, 0x0C, 0x0F, 0x8F, 0x55, 0x00}};
//0x242 VCLEFT_LVPowerState 100ms
CAN_frame TESLA_242 = {.FD = false, .ext_ID = false, .DLC = 2, .ID = 0x242, .data = {0x10, 0x95}}; //0x2D1 VCFRONT_okToUseHighPower: "cycle_time" 100ms
//0x243 VCRIGHT_hvacStatus 50ms CAN_frame TESLA_2D1 = {.FD = false, .ext_ID = false, .DLC = 2, .ID = 0x2D1, .data = {0xFF, 0x01}};
CAN_frame TESLA_243_1 = {.FD = false,
//0x2E1, 6 muxes
//0x2E1 VCFRONT_status: "cycle_time" 10ms each mux/statusIndex
CAN_frame TESLA_2E1_VEHICLE_AND_RAILS = {.FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 8, .DLC = 8,
.ID = 0x243, .ID = 0x2E1,
.data = {0xC9, 0x00, 0xEB, 0xD4, 0x31, 0x32, 0x02, 0x00}}; .data = {0x29, 0x0A, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00}};
CAN_frame TESLA_243_2 = {.FD = false,
//{0x29, 0x0A, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x00} INIT
//{0x29, 0x0A, 0x0D, 0xFF, 0x0F, 0x00, 0x00, 0x00} DRIVE
//{0x29, 0x0A, 0x09, 0xFF, 0x0F, 0x00, 0x00, 0x00} HV_UP_STANDBY
//{0x29, 0x0A, 0x0A, 0xFF, 0x0F, 0x00, 0x00, 0x00} ACCESSORY
//{0x29, 0x0A, 0x06, 0xFF, 0x0F, 0x00, 0x00, 0x00} SLEEP_STANDBY
//0x2E1 VCFRONT_status: "cycle_time" 10ms each mux/statusIndex
CAN_frame TESLA_2E1_HOMELINK = {.FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 8, .DLC = 8,
.ID = 0x243, .ID = 0x2E1,
.data = {0x08, 0x81, 0x42, 0x60, 0x92, 0x2C, 0x0E, 0x09}}; .data = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00}};
//0x129 SteeringAngle 10ms
CAN_frame TESLA_129 = {.FD = false, //0x2E1 VCFRONT_status: "cycle_time" 10ms each mux/statusIndex
CAN_frame TESLA_2E1_REFRIGERANT_SYSTEM = {.FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 8, .DLC = 8,
.ID = 0x129, .ID = 0x2E1,
.data = {0x21, 0x24, 0x36, 0x5F, 0x00, 0x20, 0xFF, 0x3F}}; .data = {0x03, 0x6D, 0x99, 0x02, 0x1B, 0x57, 0x00, 0x00}};
//0x612 UDS diagnostic requests - on demand
//0x2E1 VCFRONT_status: "cycle_time" 10ms each mux/statusIndex
CAN_frame TESLA_2E1_LV_BATTERY_DEBUG = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x2E1,
.data = {0xFC, 0x1B, 0xD1, 0x99, 0x9A, 0xD8, 0x09, 0x00}};
//0x2E1 VCFRONT_status: "cycle_time" 10ms each mux/statusIndex
CAN_frame TESLA_2E1_MUX_5 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x2E1,
.data = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
//0x2E1 VCFRONT_status: "cycle_time" 10ms each mux/statusIndex
CAN_frame TESLA_2E1_BODY_CONTROLS = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x2E1,
.data = {0x08, 0x21, 0x04, 0x6E, 0xA0, 0x88, 0x06, 0x04}};
//0x2E8 EPBR_status: "cycle_time" 100ms
CAN_frame TESLA_2E8 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x2E8,
.data = {0x02, 0x00, 0x10, 0x00, 0x00, 0x80, 0x00, 0x6C}};
//0x284 UI_vehicleModes: "cycle_time" 500ms
CAN_frame TESLA_284 = {.FD = false, .ext_ID = false, .DLC = 5, .ID = 0x284, .data = {0x10, 0x00, 0x00, 0x00, 0x00}};
//0x293 UI_chassisControl: "cycle_time" 500ms, UI_chassisControlChecksum/UI_chassisControlCounter generated via generateFrameCounterChecksum
CAN_frame TESLA_293 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x293,
.data = {0x01, 0x0C, 0x55, 0x91, 0x55, 0x15, 0x01, 0xF3}};
//0x3A1 VCFRONT_vehicleStatus: "cycle_time" 50ms, VCFRONT_vehicleStatusChecksum/VCFRONT_vehicleStatusCounter eventually need to be generated via generateMuxFrameCounterChecksum
//Looks like 2 muxes, counter at bit 52 width 4 and checksum at bit 56 width 8? Need later software Model3_ETH.compact.json signal file or DBC.
//Migrated to an array until figured out
CAN_frame TESLA_3A1[16] = {
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0xC3, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0xD0, 0x01}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0x08, 0x62, 0x0B, 0x18, 0x00, 0x28, 0xE2, 0xCB}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0xC3, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0xF0, 0x21}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0x08, 0x62, 0x0B, 0x18, 0x00, 0x28, 0x02, 0xEB}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0xC3, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0x10, 0x41}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0x08, 0x62, 0x0B, 0x18, 0x00, 0x28, 0x22, 0x0B}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0xC3, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0x30, 0x61}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0x08, 0x62, 0x0B, 0x18, 0x00, 0x28, 0x42, 0x2B}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0xC3, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0x50, 0x81}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0x08, 0x62, 0x0B, 0x18, 0x00, 0x28, 0x62, 0x4B}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0xC3, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0x70, 0xA1}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0x08, 0x62, 0x0B, 0x18, 0x00, 0x28, 0x82, 0x6B}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0xC3, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0x90, 0xC1}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0x08, 0x62, 0x0B, 0x18, 0x00, 0x28, 0xA2, 0x8B}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0xC3, 0xFF, 0xFF, 0xFF, 0x3D, 0x00, 0xB0, 0xE1}},
{.FD = false, .ext_ID = false, .DLC = 8, .ID = 0x3A1, .data = {0x08, 0x62, 0x0B, 0x18, 0x00, 0x28, 0xC2, 0xAB}}};
//0x313 UI_powertrainControl: "cycle_time" 500ms, UI_powertrainControlChecksum/UI_powertrainControlCounter generated via generateFrameCounterChecksum
CAN_frame TESLA_313 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x313,
.data = {0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1B}};
//0x321 VCFRONT_sensors: "cycle_time" 1000ms
CAN_frame TESLA_321 = {
.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x321,
.data = {0xEC, 0x71, 0xA7, 0x6E, 0x02, 0x6C, 0x00, 0x04}}; // Last 2 bytes are counter and checksum
//0x333 UI_chargeRequest: "cycle_time" 500ms, UI_chargeTerminationPct value = 900 [bit 16, width 10, scale 0.1, min 25, max 100]
CAN_frame TESLA_333 = {.FD = false, .ext_ID = false, .DLC = 5, .ID = 0x333, .data = {0x84, 0x30, 0x84, 0x07, 0x02}};
//0x334 UI request: "cycle_time" 500ms, initial frame car sends
CAN_frame TESLA_334_INITIAL = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x334,
.data = {0x3F, 0x3F, 0xC8, 0x00, 0xE2, 0x3F, 0x80, 0x1E}};
//0x334 UI request: "cycle_time" 500ms, generated via generateFrameCounterChecksum
CAN_frame TESLA_334 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x334,
.data = {0x3F, 0x3F, 0x00, 0x0F, 0xE2, 0x3F, 0x90, 0x75}};
//0x3B3 UI_vehicleControl2: "cycle_time" 500ms
CAN_frame TESLA_3B3 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x3B3,
.data = {0x90, 0x80, 0x05, 0x08, 0x00, 0x00, 0x00, 0x01}};
//0x39D IBST_status: "cycle_time" 50ms, IBST_statusChecksum/IBST_statusCounter generated via generateFrameCounterChecksum
CAN_frame TESLA_39D = {.FD = false, .ext_ID = false, .DLC = 5, .ID = 0x39D, .data = {0xE1, 0x59, 0xC1, 0x27, 0x00}};
//0x3C2 VCLEFT_switchStatus (Mux0, initial frame car sends): "cycle_time" 50ms, sent once
CAN_frame TESLA_3C2_INITIAL = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x3C2,
.data = {0x00, 0x55, 0x55, 0x55, 0x00, 0x00, 0x5A, 0x05}};
//0x3C2 VCLEFT_switchStatus (Mux0): "cycle_time" 50ms each mux/SwitchStatusIndex
CAN_frame TESLA_3C2_Mux0 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x3C2,
.data = {0x00, 0x55, 0x55, 0x55, 0x00, 0x00, 0x5A, 0x45}};
//0x3C2 VCLEFT_switchStatus (Mux1): "cycle_time" 50ms each mux/SwitchStatusIndex
CAN_frame TESLA_3C2_Mux1 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x3C2,
.data = {0x29, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
//0x504 Initially sent
CAN_frame TESLA_504_INITIAL = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x504,
.data = {0x00, 0x1B, 0x06, 0x03, 0x00, 0x01, 0x00, 0x01}};
//0x55A Unknown but always sent: "cycle_time" 500ms
CAN_frame TESLA_55A = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x55A,
.data = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
//0x7FF GTW_carConfig: "cycle_time" 100ms each mux/carConfigMultiplexer (UK/RHD)
CAN_frame TESLA_7FF_Mux1 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7FF,
.data = {0x01, 0x49, 0x42, 0x47, 0x00, 0x03, 0x15, 0x01}};
//0x7FF GTW_carConfig: "cycle_time" 100ms each mux/carConfigMultiplexer
CAN_frame TESLA_7FF_Mux2 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7FF,
.data = {0x02, 0x66, 0x32, 0x24, 0x04, 0x49, 0x95, 0x82}};
//0x7FF GTW_carConfig: "cycle_time" 100ms each mux/carConfigMultiplexer (EU/Long Range)
CAN_frame TESLA_7FF_Mux3 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7FF,
.data = {0x03, 0x01, 0x08, 0x48, 0x01, 0x00, 0x00, 0x12}};
//0x7FF GTW_carConfig: "cycle_time" 100ms each mux/carConfigMultiplexer
CAN_frame TESLA_7FF_Mux4 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7FF,
.data = {0x04, 0x73, 0x03, 0x67, 0x5C, 0x00, 0x00, 0x00}};
//0x7FF GTW_carConfig: "cycle_time" 100ms each mux/carConfigMultiplexer
CAN_frame TESLA_7FF_Mux5 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7FF,
.data = {0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00}};
//0x7FF GTW_carConfig: "cycle_time" 100ms each mux/carConfigMultiplexer - later firmware has muxes 6 & 7, needed?
CAN_frame TESLA_7FF_Mux6 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7FF,
.data = {0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xD0}};
//0x7FF GTW_carConfig: "cycle_time" 100ms each mux/carConfigMultiplexer - later firmware has muxes 6 & 7, needed?
CAN_frame TESLA_7FF_Mux7 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x7FF,
.data = {0x07, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00}};
//0x722 BMS_bmbKeepAlive: "cycle_time" 100ms, should only be sent when testing packs or diagnosing problems
CAN_frame TESLA_722 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x722,
.data = {0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}};
//0x25D CP_status: "cycle_time" 100ms, stops some cpMia errors, but not necessary for standalone pack operation so not used/necessary. Note CP_type for different regions, the below has "IEC_CCS"
CAN_frame TESLA_25D = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x25D,
.data = {0x37, 0x41, 0x01, 0x16, 0x08, 0x00, 0x00, 0x00}};
//0x602 BMS UDS diagnostic request: on demand
CAN_frame TESLA_602 = {.FD = false, CAN_frame TESLA_602 = {.FD = false,
.ext_ID = false, .ext_ID = false,
.DLC = 8, .DLC = 8,
.ID = 0x602, .ID = 0x602,
.data = {0x02, 0x27, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}}; .data = {0x02, 0x27, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}}; // Define initial UDS request
//0x610 BMS Query UDS request: on demand
CAN_frame TESLA_610 = {.FD = false,
.ext_ID = false,
.DLC = 8,
.ID = 0x610,
.data = {0x02, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}}; // Define initial UDS request
uint8_t stateMachineClearIsolationFault = 0xFF; uint8_t stateMachineClearIsolationFault = 0xFF;
uint8_t stateMachineBMSReset = 0xFF; uint8_t stateMachineBMSReset = 0xFF;
uint8_t stateMachineBMSQuery = 0xFF;
uint16_t sendContactorClosingMessagesStill = 300; uint16_t sendContactorClosingMessagesStill = 300;
uint16_t battery_cell_max_v = 3300; uint16_t battery_cell_max_v = 3300;
uint16_t battery_cell_min_v = 3300; uint16_t battery_cell_min_v = 3300;
@ -162,8 +523,8 @@ class TeslaBattery : public CanBattery {
//0x2d2: 722 BMSVAlimits //0x2d2: 722 BMSVAlimits
uint16_t battery_max_discharge_current = 0; uint16_t battery_max_discharge_current = 0;
uint16_t battery_max_charge_current = 0; uint16_t battery_max_charge_current = 0;
uint16_t battery_bms_max_voltage = 0; uint16_t BMS_max_voltage = 0;
uint16_t battery_bms_min_voltage = 0; uint16_t BMS_min_voltage = 0;
//0x2b4: 692 PCS_dcdcRailStatus //0x2b4: 692 PCS_dcdcRailStatus
uint16_t battery_dcdcHvBusVolt = 0; // Change name from battery_high_voltage to battery_dcdcHvBusVolt uint16_t battery_dcdcHvBusVolt = 0; // Change name from battery_high_voltage to battery_dcdcHvBusVolt
uint16_t battery_dcdcLvBusVolt = 0; // Change name from battery_low_voltage to battery_dcdcLvBusVolt uint16_t battery_dcdcLvBusVolt = 0; // Change name from battery_low_voltage to battery_dcdcLvBusVolt
@ -198,7 +559,7 @@ class TeslaBattery : public CanBattery {
uint8_t battery_packContNegativeState = 0; uint8_t battery_packContNegativeState = 0;
uint8_t battery_packContPositiveState = 0; uint8_t battery_packContPositiveState = 0;
uint8_t battery_packContactorSetState = 0; uint8_t battery_packContactorSetState = 0;
bool battery_packCtrsClosingAllowed = false; // Change to bool bool battery_packCtrsClosingBlocked = false; // Change to bool
bool battery_pyroTestInProgress = false; // Change to bool bool battery_pyroTestInProgress = false; // Change to bool
bool battery_packCtrsOpenNowRequested = false; // Change to bool bool battery_packCtrsOpenNowRequested = false; // Change to bool
bool battery_packCtrsOpenRequested = false; // Change to bool bool battery_packCtrsOpenRequested = false; // Change to bool
@ -217,47 +578,68 @@ class TeslaBattery : public CanBattery {
bool battery_fcCtrsResetRequestRequired = false; // Change to bool bool battery_fcCtrsResetRequestRequired = false; // Change to bool
bool battery_fcLinkAllowedToEnergize = false; // Change to bool bool battery_fcLinkAllowedToEnergize = false; // Change to bool
//0x72A: BMS_serialNumber //0x72A: BMS_serialNumber
uint8_t BMS_SerialNumber[14] = {0}; // Stores raw HEX values for ASCII chars uint8_t battery_serialNumber[14] = {0}; // Stores raw HEX values for ASCII chars
bool parsed_battery_serialNumber = false;
char* battery_manufactureDate; // YYYY-MM-DD\0
//Via UDS
uint8_t battery_partNumber[12] = {0}; //stores raw HEX values for ASCII chars
bool parsed_battery_partNumber = false;
//Via UDS
//static uint8_t BMS_partNumber[12] = {0}; //stores raw HEX values for ASCII chars
//static bool parsed_BMS_partNumber = false;
//0x300: BMS_info
uint16_t BMS_info_buildConfigId = 0;
uint16_t BMS_info_hardwareId = 0;
uint16_t BMS_info_componentId = 0;
uint8_t BMS_info_pcbaId = 0;
uint8_t BMS_info_assemblyId = 0;
uint16_t BMS_info_usageId = 0;
uint16_t BMS_info_subUsageId = 0;
uint8_t BMS_info_platformType = 0;
uint32_t BMS_info_appCrc = 0;
uint64_t BMS_info_bootGitHash = 0;
uint8_t BMS_info_bootUdsProtoVersion = 0;
uint32_t BMS_info_bootCrc = 0;
//0x212: 530 BMS_status //0x212: 530 BMS_status
bool battery_BMS_hvacPowerRequest = false; //Change to bool bool BMS_hvacPowerRequest = false; //Change to bool
bool battery_BMS_notEnoughPowerForDrive = false; //Change to bool bool BMS_notEnoughPowerForDrive = false; //Change to bool
bool battery_BMS_notEnoughPowerForSupport = false; //Change to bool bool BMS_notEnoughPowerForSupport = false; //Change to bool
bool battery_BMS_preconditionAllowed = false; //Change to bool bool BMS_preconditionAllowed = false; //Change to bool
bool battery_BMS_updateAllowed = false; //Change to bool bool BMS_updateAllowed = false; //Change to bool
bool battery_BMS_activeHeatingWorthwhile = false; //Change to bool bool BMS_activeHeatingWorthwhile = false; //Change to bool
bool battery_BMS_cpMiaOnHvs = false; //Change to bool bool BMS_cpMiaOnHvs = false; //Change to bool
uint8_t battery_BMS_contactorState = 0; uint8_t BMS_contactorState = 0;
uint8_t battery_BMS_state = 0; uint8_t BMS_state = 0;
uint8_t battery_BMS_hvState = 0; uint8_t BMS_hvState = 0;
uint16_t battery_BMS_isolationResistance = 0; uint16_t BMS_isolationResistance = 0;
bool battery_BMS_chargeRequest = false; //Change to bool bool BMS_chargeRequest = false; //Change to bool
bool battery_BMS_keepWarmRequest = false; //Change to bool bool BMS_keepWarmRequest = false; //Change to bool
uint8_t battery_BMS_uiChargeStatus = 0; uint8_t BMS_uiChargeStatus = 0;
bool battery_BMS_diLimpRequest = false; //Change to bool bool BMS_diLimpRequest = false; //Change to bool
bool battery_BMS_okToShipByAir = false; //Change to bool bool BMS_okToShipByAir = false; //Change to bool
bool battery_BMS_okToShipByLand = false; //Change to bool bool BMS_okToShipByLand = false; //Change to bool
uint32_t battery_BMS_chgPowerAvailable = 0; uint32_t BMS_chgPowerAvailable = 0;
uint8_t battery_BMS_chargeRetryCount = 0; uint8_t BMS_chargeRetryCount = 0;
bool battery_BMS_pcsPwmEnabled = false; //Change to bool bool BMS_pcsPwmEnabled = false; //Change to bool
bool battery_BMS_ecuLogUploadRequest = false; //Change to bool bool BMS_ecuLogUploadRequest = false; //Change to bool
uint8_t battery_BMS_minPackTemperature = 0; uint8_t BMS_minPackTemperature = 0;
// 0x224:548 PCS_dcdcStatus // 0x224:548 PCS_dcdcStatus
uint8_t battery_PCS_dcdcPrechargeStatus = 0; uint8_t PCS_dcdcPrechargeStatus = 0;
uint8_t battery_PCS_dcdc12VSupportStatus = 0; uint8_t PCS_dcdc12VSupportStatus = 0;
uint8_t battery_PCS_dcdcHvBusDischargeStatus = 0; uint8_t PCS_dcdcHvBusDischargeStatus = 0;
uint16_t battery_PCS_dcdcMainState = 0; uint16_t PCS_dcdcMainState = 0;
uint8_t battery_PCS_dcdcSubState = 0; uint8_t PCS_dcdcSubState = 0;
bool battery_PCS_dcdcFaulted = false; //Change to bool bool PCS_dcdcFaulted = false; //Change to bool
bool battery_PCS_dcdcOutputIsLimited = false; //Change to bool bool PCS_dcdcOutputIsLimited = false; //Change to bool
uint32_t battery_PCS_dcdcMaxOutputCurrentAllowed = 0; uint32_t PCS_dcdcMaxOutputCurrentAllowed = 0;
uint8_t battery_PCS_dcdcPrechargeRtyCnt = 0; uint8_t PCS_dcdcPrechargeRtyCnt = 0;
uint8_t battery_PCS_dcdc12VSupportRtyCnt = 0; uint8_t PCS_dcdc12VSupportRtyCnt = 0;
uint8_t battery_PCS_dcdcDischargeRtyCnt = 0; uint8_t PCS_dcdcDischargeRtyCnt = 0;
uint8_t battery_PCS_dcdcPwmEnableLine = 0; uint8_t PCS_dcdcPwmEnableLine = 0;
uint8_t battery_PCS_dcdcSupportingFixedLvTarget = 0; uint8_t PCS_dcdcSupportingFixedLvTarget = 0;
uint8_t battery_PCS_ecuLogUploadRequest = 0; uint8_t PCS_ecuLogUploadRequest = 0;
uint8_t battery_PCS_dcdcPrechargeRestartCnt = 0; uint8_t PCS_dcdcPrechargeRestartCnt = 0;
uint8_t battery_PCS_dcdcInitialPrechargeSubState = 0; uint8_t PCS_dcdcInitialPrechargeSubState = 0;
//0x312: 786 BMS_thermalStatus //0x312: 786 BMS_thermalStatus
uint16_t BMS_powerDissipation = 0; uint16_t BMS_powerDissipation = 0;
uint16_t BMS_flowRequest = 0; uint16_t BMS_flowRequest = 0;
@ -268,6 +650,22 @@ class TeslaBattery : public CanBattery {
uint16_t BMS_packTMax = 0; uint16_t BMS_packTMax = 0;
bool BMS_pcsNoFlowRequest = false; bool BMS_pcsNoFlowRequest = false;
bool BMS_noFlowRequest = false; bool BMS_noFlowRequest = false;
//0x3C4: PCS_info
uint8_t PCS_partNumber[12] = {0}; //stores raw HEX values for ASCII chars
bool parsed_PCS_partNumber = false;
uint16_t PCS_info_buildConfigId = 0;
uint16_t PCS_info_hardwareId = 0;
uint16_t PCS_info_componentId = 0;
uint8_t PCS_info_pcbaId = 0;
uint8_t PCS_info_assemblyId = 0;
uint16_t PCS_info_usageId = 0;
uint16_t PCS_info_subUsageId = 0;
uint8_t PCS_info_platformType = 0;
uint32_t PCS_info_appCrc = 0;
uint32_t PCS_info_cpu2AppCrc = 0;
uint64_t PCS_info_bootGitHash = 0;
uint8_t PCS_info_bootUdsProtoVersion = 0;
uint32_t PCS_info_bootCrc = 0;
//0x2A4; 676 PCS_thermalStatus //0x2A4; 676 PCS_thermalStatus
int16_t PCS_chgPhATemp = 0; int16_t PCS_chgPhATemp = 0;
int16_t PCS_chgPhBTemp = 0; int16_t PCS_chgPhBTemp = 0;
@ -330,6 +728,18 @@ class TeslaBattery : public CanBattery {
bool HVP_shuntRefVoltageMismatch = false; //Change to bool bool HVP_shuntRefVoltageMismatch = false; //Change to bool
bool HVP_shuntThermistorMia = false; //Change to bool bool HVP_shuntThermistorMia = false; //Change to bool
bool HVP_shuntHwMia = false; //Change to bool bool HVP_shuntHwMia = false; //Change to bool
uint16_t HVP_info_buildConfigId = 0;
uint16_t HVP_info_hardwareId = 0;
uint16_t HVP_info_componentId = 0;
uint8_t HVP_info_pcbaId = 0;
uint8_t HVP_info_assemblyId = 0;
uint16_t HVP_info_usageId = 0;
uint16_t HVP_info_subUsageId = 0;
uint8_t HVP_info_platformType = 0;
uint32_t HVP_info_appCrc = 0;
uint64_t HVP_info_bootGitHash = 0;
uint8_t HVP_info_bootUdsProtoVersion = 0;
uint32_t HVP_info_bootCrc = 0;
int16_t HVP_dcLinkVoltage = 0; int16_t HVP_dcLinkVoltage = 0;
int16_t HVP_packVoltage = 0; int16_t HVP_packVoltage = 0;
int16_t HVP_fcLinkVoltage = 0; int16_t HVP_fcLinkVoltage = 0;
@ -411,99 +821,99 @@ class TeslaBattery : public CanBattery {
bool battery_fcCtrCloseFailed = false; bool battery_fcCtrCloseFailed = false;
bool battery_shuntThermistorMia = false; bool battery_shuntThermistorMia = false;
//0x320: 800 BMS_alertMatrix //0x320: 800 BMS_alertMatrix
uint8_t battery_BMS_matrixIndex = 0; // Changed to bool uint8_t BMS_matrixIndex = 0; // Changed to bool
bool battery_BMS_a061_robinBrickOverVoltage = false; bool BMS_a061_robinBrickOverVoltage = false;
bool battery_BMS_a062_SW_BrickV_Imbalance = false; bool BMS_a062_SW_BrickV_Imbalance = false;
bool battery_BMS_a063_SW_ChargePort_Fault = false; bool BMS_a063_SW_ChargePort_Fault = false;
bool battery_BMS_a064_SW_SOC_Imbalance = false; bool BMS_a064_SW_SOC_Imbalance = false;
bool battery_BMS_a127_SW_shunt_SNA = false; bool BMS_a127_SW_shunt_SNA = false;
bool battery_BMS_a128_SW_shunt_MIA = false; bool BMS_a128_SW_shunt_MIA = false;
bool battery_BMS_a069_SW_Low_Power = false; bool BMS_a069_SW_Low_Power = false;
bool battery_BMS_a130_IO_CAN_Error = false; bool BMS_a130_IO_CAN_Error = false;
bool battery_BMS_a071_SW_SM_TransCon_Not_Met = false; bool BMS_a071_SW_SM_TransCon_Not_Met = false;
bool battery_BMS_a132_HW_BMB_OTP_Uncorrctbl = false; bool BMS_a132_HW_BMB_OTP_Uncorrctbl = false;
bool battery_BMS_a134_SW_Delayed_Ctr_Off = false; bool BMS_a134_SW_Delayed_Ctr_Off = false;
bool battery_BMS_a075_SW_Chg_Disable_Failure = false; bool BMS_a075_SW_Chg_Disable_Failure = false;
bool battery_BMS_a076_SW_Dch_While_Charging = false; bool BMS_a076_SW_Dch_While_Charging = false;
bool battery_BMS_a017_SW_Brick_OV = false; bool BMS_a017_SW_Brick_OV = false;
bool battery_BMS_a018_SW_Brick_UV = false; bool BMS_a018_SW_Brick_UV = false;
bool battery_BMS_a019_SW_Module_OT = false; bool BMS_a019_SW_Module_OT = false;
bool battery_BMS_a021_SW_Dr_Limits_Regulation = false; bool BMS_a021_SW_Dr_Limits_Regulation = false;
bool battery_BMS_a022_SW_Over_Current = false; bool BMS_a022_SW_Over_Current = false;
bool battery_BMS_a023_SW_Stack_OV = false; bool BMS_a023_SW_Stack_OV = false;
bool battery_BMS_a024_SW_Islanded_Brick = false; bool BMS_a024_SW_Islanded_Brick = false;
bool battery_BMS_a025_SW_PwrBalance_Anomaly = false; bool BMS_a025_SW_PwrBalance_Anomaly = false;
bool battery_BMS_a026_SW_HFCurrent_Anomaly = false; bool BMS_a026_SW_HFCurrent_Anomaly = false;
bool battery_BMS_a087_SW_Feim_Test_Blocked = false; bool BMS_a087_SW_Feim_Test_Blocked = false;
bool battery_BMS_a088_SW_VcFront_MIA_InDrive = false; bool BMS_a088_SW_VcFront_MIA_InDrive = false;
bool battery_BMS_a089_SW_VcFront_MIA = false; bool BMS_a089_SW_VcFront_MIA = false;
bool battery_BMS_a090_SW_Gateway_MIA = false; bool BMS_a090_SW_Gateway_MIA = false;
bool battery_BMS_a091_SW_ChargePort_MIA = false; bool BMS_a091_SW_ChargePort_MIA = false;
bool battery_BMS_a092_SW_ChargePort_Mia_On_Hv = false; bool BMS_a092_SW_ChargePort_Mia_On_Hv = false;
bool battery_BMS_a034_SW_Passive_Isolation = false; bool BMS_a034_SW_Passive_Isolation = false;
bool battery_BMS_a035_SW_Isolation = false; bool BMS_a035_SW_Isolation = false;
bool battery_BMS_a036_SW_HvpHvilFault = false; bool BMS_a036_SW_HvpHvilFault = false;
bool battery_BMS_a037_SW_Flood_Port_Open = false; bool BMS_a037_SW_Flood_Port_Open = false;
bool battery_BMS_a158_SW_HVP_HVI_Comms = false; bool BMS_a158_SW_HVP_HVI_Comms = false;
bool battery_BMS_a039_SW_DC_Link_Over_Voltage = false; bool BMS_a039_SW_DC_Link_Over_Voltage = false;
bool battery_BMS_a041_SW_Power_On_Reset = false; bool BMS_a041_SW_Power_On_Reset = false;
bool battery_BMS_a042_SW_MPU_Error = false; bool BMS_a042_SW_MPU_Error = false;
bool battery_BMS_a043_SW_Watch_Dog_Reset = false; bool BMS_a043_SW_Watch_Dog_Reset = false;
bool battery_BMS_a044_SW_Assertion = false; bool BMS_a044_SW_Assertion = false;
bool battery_BMS_a045_SW_Exception = false; bool BMS_a045_SW_Exception = false;
bool battery_BMS_a046_SW_Task_Stack_Usage = false; bool BMS_a046_SW_Task_Stack_Usage = false;
bool battery_BMS_a047_SW_Task_Stack_Overflow = false; bool BMS_a047_SW_Task_Stack_Overflow = false;
bool battery_BMS_a048_SW_Log_Upload_Request = false; bool BMS_a048_SW_Log_Upload_Request = false;
bool battery_BMS_a169_SW_FC_Pack_Weld = false; bool BMS_a169_SW_FC_Pack_Weld = false;
bool battery_BMS_a050_SW_Brick_Voltage_MIA = false; bool BMS_a050_SW_Brick_Voltage_MIA = false;
bool battery_BMS_a051_SW_HVC_Vref_Bad = false; bool BMS_a051_SW_HVC_Vref_Bad = false;
bool battery_BMS_a052_SW_PCS_MIA = false; bool BMS_a052_SW_PCS_MIA = false;
bool battery_BMS_a053_SW_ThermalModel_Sanity = false; bool BMS_a053_SW_ThermalModel_Sanity = false;
bool battery_BMS_a054_SW_Ver_Supply_Fault = false; bool BMS_a054_SW_Ver_Supply_Fault = false;
bool battery_BMS_a176_SW_GracefulPowerOff = false; bool BMS_a176_SW_GracefulPowerOff = false;
bool battery_BMS_a059_SW_Pack_Voltage_Sensing = false; bool BMS_a059_SW_Pack_Voltage_Sensing = false;
bool battery_BMS_a060_SW_Leakage_Test_Failure = false; bool BMS_a060_SW_Leakage_Test_Failure = false;
bool battery_BMS_a077_SW_Charger_Regulation = false; bool BMS_a077_SW_Charger_Regulation = false;
bool battery_BMS_a081_SW_Ctr_Close_Blocked = false; bool BMS_a081_SW_Ctr_Close_Blocked = false;
bool battery_BMS_a082_SW_Ctr_Force_Open = false; bool BMS_a082_SW_Ctr_Force_Open = false;
bool battery_BMS_a083_SW_Ctr_Close_Failure = false; bool BMS_a083_SW_Ctr_Close_Failure = false;
bool battery_BMS_a084_SW_Sleep_Wake_Aborted = false; bool BMS_a084_SW_Sleep_Wake_Aborted = false;
bool battery_BMS_a094_SW_Drive_Inverter_MIA = false; bool BMS_a094_SW_Drive_Inverter_MIA = false;
bool battery_BMS_a099_SW_BMB_Communication = false; bool BMS_a099_SW_BMB_Communication = false;
bool battery_BMS_a105_SW_One_Module_Tsense = false; bool BMS_a105_SW_One_Module_Tsense = false;
bool battery_BMS_a106_SW_All_Module_Tsense = false; bool BMS_a106_SW_All_Module_Tsense = false;
bool battery_BMS_a107_SW_Stack_Voltage_MIA = false; bool BMS_a107_SW_Stack_Voltage_MIA = false;
bool battery_BMS_a121_SW_NVRAM_Config_Error = false; bool BMS_a121_SW_NVRAM_Config_Error = false;
bool battery_BMS_a122_SW_BMS_Therm_Irrational = false; bool BMS_a122_SW_BMS_Therm_Irrational = false;
bool battery_BMS_a123_SW_Internal_Isolation = false; bool BMS_a123_SW_Internal_Isolation = false;
bool battery_BMS_a129_SW_VSH_Failure = false; bool BMS_a129_SW_VSH_Failure = false;
bool battery_BMS_a131_Bleed_FET_Failure = false; bool BMS_a131_Bleed_FET_Failure = false;
bool battery_BMS_a136_SW_Module_OT_Warning = false; bool BMS_a136_SW_Module_OT_Warning = false;
bool battery_BMS_a137_SW_Brick_UV_Warning = false; bool BMS_a137_SW_Brick_UV_Warning = false;
bool battery_BMS_a138_SW_Brick_OV_Warning = false; bool BMS_a138_SW_Brick_OV_Warning = false;
bool battery_BMS_a139_SW_DC_Link_V_Irrational = false; bool BMS_a139_SW_DC_Link_V_Irrational = false;
bool battery_BMS_a141_SW_BMB_Status_Warning = false; bool BMS_a141_SW_BMB_Status_Warning = false;
bool battery_BMS_a144_Hvp_Config_Mismatch = false; bool BMS_a144_Hvp_Config_Mismatch = false;
bool battery_BMS_a145_SW_SOC_Change = false; bool BMS_a145_SW_SOC_Change = false;
bool battery_BMS_a146_SW_Brick_Overdischarged = false; bool BMS_a146_SW_Brick_Overdischarged = false;
bool battery_BMS_a149_SW_Missing_Config_Block = false; bool BMS_a149_SW_Missing_Config_Block = false;
bool battery_BMS_a151_SW_external_isolation = false; bool BMS_a151_SW_external_isolation = false;
bool battery_BMS_a156_SW_BMB_Vref_bad = false; bool BMS_a156_SW_BMB_Vref_bad = false;
bool battery_BMS_a157_SW_HVP_HVS_Comms = false; bool BMS_a157_SW_HVP_HVS_Comms = false;
bool battery_BMS_a159_SW_HVP_ECU_Error = false; bool BMS_a159_SW_HVP_ECU_Error = false;
bool battery_BMS_a161_SW_DI_Open_Request = false; bool BMS_a161_SW_DI_Open_Request = false;
bool battery_BMS_a162_SW_No_Power_For_Support = false; bool BMS_a162_SW_No_Power_For_Support = false;
bool battery_BMS_a163_SW_Contactor_Mismatch = false; bool BMS_a163_SW_Contactor_Mismatch = false;
bool battery_BMS_a164_SW_Uncontrolled_Regen = false; bool BMS_a164_SW_Uncontrolled_Regen = false;
bool battery_BMS_a165_SW_Pack_Partial_Weld = false; bool BMS_a165_SW_Pack_Partial_Weld = false;
bool battery_BMS_a166_SW_Pack_Full_Weld = false; bool BMS_a166_SW_Pack_Full_Weld = false;
bool battery_BMS_a167_SW_FC_Partial_Weld = false; bool BMS_a167_SW_FC_Partial_Weld = false;
bool battery_BMS_a168_SW_FC_Full_Weld = false; bool BMS_a168_SW_FC_Full_Weld = false;
bool battery_BMS_a170_SW_Limp_Mode = false; bool BMS_a170_SW_Limp_Mode = false;
bool battery_BMS_a171_SW_Stack_Voltage_Sense = false; bool BMS_a171_SW_Stack_Voltage_Sense = false;
bool battery_BMS_a174_SW_Charge_Failure = false; bool BMS_a174_SW_Charge_Failure = false;
bool battery_BMS_a179_SW_Hvp_12V_Fault = false; bool BMS_a179_SW_Hvp_12V_Fault = false;
bool battery_BMS_a180_SW_ECU_reset_blocked = false; bool BMS_a180_SW_ECU_reset_blocked = false;
}; };
class TeslaModel3YBattery : public TeslaBattery { class TeslaModel3YBattery : public TeslaBattery {

View file

@ -39,8 +39,8 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
float packMass = static_cast<float>(datalayer_extended.tesla.battery_packMass); float packMass = static_cast<float>(datalayer_extended.tesla.battery_packMass);
float platformMaxBusVoltage = float platformMaxBusVoltage =
static_cast<float>(datalayer_extended.tesla.battery_platformMaxBusVoltage) * 0.1 + 375; static_cast<float>(datalayer_extended.tesla.battery_platformMaxBusVoltage) * 0.1 + 375;
float bms_min_voltage = static_cast<float>(datalayer_extended.tesla.battery_bms_min_voltage) * 0.01 * 2; float bms_min_voltage = static_cast<float>(datalayer_extended.tesla.BMS_min_voltage) * 0.01 * 2;
float bms_max_voltage = static_cast<float>(datalayer_extended.tesla.battery_bms_max_voltage) * 0.01 * 2; float bms_max_voltage = static_cast<float>(datalayer_extended.tesla.BMS_max_voltage) * 0.01 * 2;
float max_charge_current = static_cast<float>(datalayer_extended.tesla.battery_max_charge_current); float max_charge_current = static_cast<float>(datalayer_extended.tesla.battery_max_charge_current);
float max_discharge_current = static_cast<float>(datalayer_extended.tesla.battery_max_discharge_current); float max_discharge_current = static_cast<float>(datalayer_extended.tesla.battery_max_discharge_current);
float soc_ave = static_cast<float>(datalayer_extended.tesla.battery_soc_ave) * 0.1; float soc_ave = static_cast<float>(datalayer_extended.tesla.battery_soc_ave) * 0.1;
@ -51,9 +51,9 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
float BrickVoltageMin = static_cast<float>(datalayer_extended.tesla.battery_BrickVoltageMin) * 0.002; float BrickVoltageMin = static_cast<float>(datalayer_extended.tesla.battery_BrickVoltageMin) * 0.002;
float BrickModelTMax = static_cast<float>(datalayer_extended.tesla.battery_BrickModelTMax) * 0.5 - 40; float BrickModelTMax = static_cast<float>(datalayer_extended.tesla.battery_BrickModelTMax) * 0.5 - 40;
float BrickModelTMin = static_cast<float>(datalayer_extended.tesla.battery_BrickModelTMin) * 0.5 - 40; float BrickModelTMin = static_cast<float>(datalayer_extended.tesla.battery_BrickModelTMin) * 0.5 - 40;
float isolationResistance = static_cast<float>(datalayer_extended.tesla.battery_BMS_isolationResistance) * 10; float isolationResistance = static_cast<float>(datalayer_extended.tesla.BMS_isolationResistance) * 10;
float PCS_dcdcMaxOutputCurrentAllowed = float PCS_dcdcMaxOutputCurrentAllowed =
static_cast<float>(datalayer_extended.tesla.battery_PCS_dcdcMaxOutputCurrentAllowed) * 0.1; static_cast<float>(datalayer_extended.tesla.PCS_dcdcMaxOutputCurrentAllowed) * 0.1;
float PCS_dcdcTemp = static_cast<float>(datalayer_extended.tesla.PCS_dcdcTemp) * 0.1 + 40; float PCS_dcdcTemp = static_cast<float>(datalayer_extended.tesla.PCS_dcdcTemp) * 0.1 + 40;
float PCS_ambientTemp = static_cast<float>(datalayer_extended.tesla.PCS_ambientTemp) * 0.1 + 40; float PCS_ambientTemp = static_cast<float>(datalayer_extended.tesla.PCS_ambientTemp) * 0.1 + 40;
float PCS_chgPhATemp = static_cast<float>(datalayer_extended.tesla.PCS_chgPhATemp) * 0.1 + 40; float PCS_chgPhATemp = static_cast<float>(datalayer_extended.tesla.PCS_chgPhATemp) * 0.1 + 40;
@ -128,7 +128,7 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
static const char* contactorText[] = {"UNKNOWN(0)", "OPEN", "CLOSING", "BLOCKED", "OPENING", static const char* contactorText[] = {"UNKNOWN(0)", "OPEN", "CLOSING", "BLOCKED", "OPENING",
"CLOSED", "UNKNOWN(6)", "WELDED", "POS_CL", "NEG_CL", "CLOSED", "UNKNOWN(6)", "WELDED", "POS_CL", "NEG_CL",
"UNKNOWN(10)", "UNKNOWN(11)", "UNKNOWN(12)"}; "UNKNOWN(10)", "UNKNOWN(11)", "UNKNOWN(12)"};
static const char* hvilStatusState[] = {"NOT Ok", static const char* hvilStatusState[] = {"UNKNOWN or CONTACTORS OPEN",
"STATUS_OK", "STATUS_OK",
"CURRENT_SOURCE_FAULT", "CURRENT_SOURCE_FAULT",
"INTERNAL_OPEN_FAULT", "INTERNAL_OPEN_FAULT",
@ -183,15 +183,46 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
static const char* noYes[] = {"No", "Yes"}; static const char* noYes[] = {"No", "Yes"};
static const char* Fault[] = {"NOT_ACTIVE", "ACTIVE"}; static const char* Fault[] = {"NOT_ACTIVE", "ACTIVE"};
//0x20A 522 HVP_contatorState //Main battery info
content += "<h4>Contactor Status: " + String(contactorText[datalayer_extended.tesla.status_contactor]) + "</h4>"; char readableBatterySerialNumber[15]; // One extra space for null terminator
content += "<h4>HVIL: " + String(hvilStatusState[datalayer_extended.tesla.hvil_status]) + "</h4>"; memcpy(readableBatterySerialNumber, datalayer_extended.tesla.battery_serialNumber,
sizeof(datalayer_extended.tesla.battery_serialNumber));
readableBatterySerialNumber[14] = '\0'; // Null terminate the string
content += "<h4>Battery Serial Number: " + String(readableBatterySerialNumber) + "</h4>";
char readableBatteryPartNumber[13]; // One extra space for null terminator
memcpy(readableBatteryPartNumber, datalayer_extended.tesla.battery_partNumber,
sizeof(datalayer_extended.tesla.battery_partNumber));
readableBatteryPartNumber[12] = '\0'; // Null terminate the string
content += "<h4>Battery Part Number: " + String(readableBatteryPartNumber) + "</h4>";
//0x3C4 PCS_info
char readablePCSPartNumber[13]; // One extra space for null terminator
memcpy(readablePCSPartNumber, datalayer_extended.tesla.PCS_partNumber,
sizeof(datalayer_extended.tesla.PCS_partNumber));
readablePCSPartNumber[13] = '\0'; // Null terminate the string
content += "<h4>PCS Part Number: " + String(readablePCSPartNumber) + "</h4>";
content += "<h4>Battery Manufacture Date: " + String(datalayer_extended.tesla.battery_manufactureDate) + "</h4>";
content += "<h4>Battery Pack Mass: " + String(packMass) + " KG</h4>";
//0x3D2 978 BMS_kwhCounter
content += "<h4>Battery Total Discharge: " + String(total_discharge) + " kWh</h4>";
content += "<h4>Battery Total Charge: " + String(total_charge) + " kWh</h4>";
//0x20A 522 HVP_contactorState + HVIL
//content += "<h4>HVIL Fault: " + String(noYes[datalayer_extended.tesla.BMS_hvilFault]) + "</h4>";
content += "<h4>HVIL Status: " + String(hvilStatusState[datalayer_extended.tesla.hvil_status]) + "</h4>";
content += content +=
"<h4>Negative contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "</h4>"; "<h4>HVP Contactor State: " + String(contactorText[datalayer_extended.tesla.packContactorSetState]) + "</h4>";
content += content +=
"<h4>Positive contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "</h4>"; "<h4>BMS Contactor State: " + String(BMS_contactorState[datalayer_extended.tesla.BMS_contactorState]) + "</h4>";
content += "<h4>Closing allowed?: " + String(noYes[datalayer_extended.tesla.packCtrsClosingAllowed]) + "</h4>"; content +=
content += "<h4>Pyrotest in Progress: " + String(noYes[datalayer_extended.tesla.pyroTestInProgress]) + "</h4>"; "<h4>Negative Contactor: " + String(contactorState[datalayer_extended.tesla.packContNegativeState]) + "</h4>";
content +=
"<h4>Positive Contactor: " + String(contactorState[datalayer_extended.tesla.packContPositiveState]) + "</h4>";
if (datalayer_extended.tesla.packContactorSetState == 5) { //Closed
content += "<h4>Closing blocked: " + String(noYes[datalayer_extended.tesla.packCtrsClosingBlocked]) +
" (already CLOSED)</h4>";
} else {
content += "<h4>Closing blocked: " + String(noYes[datalayer_extended.tesla.packCtrsClosingBlocked]) + "</h4>";
}
content += "<h4>Pyrotest in progress: " + String(noYes[datalayer_extended.tesla.pyroTestInProgress]) + "</h4>";
content += "<h4>Contactors Open Now Requested: " + content += "<h4>Contactors Open Now Requested: " +
String(noYes[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "</h4>"; String(noYes[datalayer_extended.tesla.battery_packCtrsOpenNowRequested]) + "</h4>";
content += content +=
@ -204,21 +235,16 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
content += content +=
"<h4>DC Link Allowed to Energize: " + String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) + "<h4>DC Link Allowed to Energize: " + String(noYes[datalayer_extended.tesla.battery_dcLinkAllowedToEnergize]) +
"</h4>"; "</h4>";
char readableSerialNumber[15]; // One extra space for null terminator
memcpy(readableSerialNumber, datalayer_extended.tesla.BMS_SerialNumber,
sizeof(datalayer_extended.tesla.BMS_SerialNumber));
readableSerialNumber[14] = '\0'; // Null terminate the string
content += "<h4>BMS Serial number: " + String(readableSerialNumber) + "</h4>";
// Comment what data you would like to display, order can be changed. // Comment what data you would like to display, order can be changed.
//0x352 850 BMS_energyStatus //0x352 850 BMS_energyStatus
if (datalayer_extended.tesla.BMS352_mux == false) { if (datalayer_extended.tesla.BMS352_mux == false) {
content += "<h3>BMS 0x352 w/o mux</h3>"; //if using older BMS <2021 and comment 0x352 without MUX content += "<h3>BMS 0x352 w/o mux</h3>"; //if using older BMS <2021 and comment 0x352 without MUX
content += "<h4>Calculated SOH: " + String(nominal_full_pack_energy * 100 / beginning_of_life) + "</h4>"; content += "<h4>Calculated SOH: " + String(nominal_full_pack_energy * 100 / beginning_of_life) + "</h4>";
content += "<h4>Nominal Full Pack Energy: " + String(nominal_full_pack_energy) + " KWh</h4>"; content += "<h4>Nominal Full Pack Energy: " + String(nominal_full_pack_energy) + " kWh</h4>";
content += "<h4>Nominal Energy Remaining: " + String(nominal_energy_remaining) + " KWh</h4>"; content += "<h4>Nominal Energy Remaining: " + String(nominal_energy_remaining) + " kWh</h4>";
content += "<h4>Ideal Energy Remaining: " + String(ideal_energy_remaining) + " KWh</h4>"; content += "<h4>Ideal Energy Remaining: " + String(ideal_energy_remaining) + " kWh</h4>";
content += "<h4>Energy to Charge Complete: " + String(energy_to_charge_complete) + " KWh</h4>"; content += "<h4>Energy to Charge Complete: " + String(energy_to_charge_complete) + " kWh</h4>";
content += "<h4>Energy Buffer: " + String(energy_buffer) + " KWh</h4>"; content += "<h4>Energy Buffer: " + String(energy_buffer) + " kWh</h4>";
content += "<h4>Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) + content += "<h4>Full Charge Complete: " + String(noYes[datalayer_extended.tesla.battery_full_charge_complete]) +
"</h4>"; //bool "</h4>"; //bool
} }
@ -226,19 +252,26 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
if (datalayer_extended.tesla.BMS352_mux == true) { if (datalayer_extended.tesla.BMS352_mux == true) {
content += "<h3>BMS 0x352 w/ mux</h3>"; //if using newer BMS >2021 and comment 0x352 with MUX content += "<h3>BMS 0x352 w/ mux</h3>"; //if using newer BMS >2021 and comment 0x352 with MUX
content += "<h4>Calculated SOH: " + String(nominal_full_pack_energy_m0 * 100 / beginning_of_life) + "</h4>"; content += "<h4>Calculated SOH: " + String(nominal_full_pack_energy_m0 * 100 / beginning_of_life) + "</h4>";
content += "<h4>Nominal Full Pack Energy: " + String(nominal_full_pack_energy_m0) + " KWh</h4>"; content += "<h4>Nominal Full Pack Energy: " + String(nominal_full_pack_energy_m0) + " kWh</h4>";
content += "<h4>Nominal Energy Remaining: " + String(nominal_energy_remaining_m0) + " KWh</h4>"; content += "<h4>Nominal Energy Remaining: " + String(nominal_energy_remaining_m0) + " kWh</h4>";
content += "<h4>Ideal Energy Remaining: " + String(ideal_energy_remaining_m0) + " KWh</h4>"; content += "<h4>Ideal Energy Remaining: " + String(ideal_energy_remaining_m0) + " kWh</h4>";
content += "<h4>Energy to Charge Complete: " + String(energy_to_charge_complete_m1) + " KWh</h4>"; content += "<h4>Energy to Charge Complete: " + String(energy_to_charge_complete_m1) + " kWh</h4>";
content += "<h4>Energy Buffer: " + String(energy_buffer_m1) + " KWh</h4>"; content += "<h4>Energy Buffer: " + String(energy_buffer_m1) + " kWh</h4>";
content += "<h4>Expected Energy Remaining: " + String(expected_energy_remaining_m1) + " KWh</h4>"; content += "<h4>Expected Energy Remaining: " + String(expected_energy_remaining_m1) + " kWh</h4>";
content += "<h4>Fully Charged: " + String(noYes[datalayer_extended.tesla.battery_fully_charged]) + "</h4>"; content += "<h4>Fully Charged: " + String(noYes[datalayer_extended.tesla.battery_fully_charged]) + "</h4>";
} }
//0x3D2 978 BMS_kwhCounter //0x212 530 BMS_status
content += "<h4>Total Discharge: " + String(total_discharge) + " KWh</h4>"; content += "<h4>Isolation Resistance: " + String(isolationResistance) + " kOhms</h4>";
content += "<h4>Total Charge: " + String(total_charge) + " KWh</h4>"; content += "<h4>BMS State: " + String(BMS_state[datalayer_extended.tesla.BMS_state]) + "</h4>";
content += "<h4>BMS HV State: " + String(BMS_hvState[datalayer_extended.tesla.BMS_hvState]) + "</h4>";
content += "<h4>BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.BMS_uiChargeStatus]) +
"</h4>";
content += "<h4>BMS_buildConfigId: " + String(datalayer_extended.tesla.BMS_info_buildConfigId) + "</h4>";
content += "<h4>BMS_hardwareId: " + String(datalayer_extended.tesla.BMS_info_hardwareId) + "</h4>";
content += "<h4>BMS_componentId: " + String(datalayer_extended.tesla.BMS_info_componentId) + "</h4>";
content += "<h4>BMS PCS PWM Enabled: " + String(Fault[datalayer_extended.tesla.BMS_pcsPwmEnabled]) + "</h4>";
//0x292 658 BMS_socStates //0x292 658 BMS_socStates
content += "<h4>Battery Beginning of Life: " + String(beginning_of_life) + " KWh</h4>"; content += "<h4>Battery Beginning of Life: " + String(beginning_of_life) + " kWh</h4>";
content += "<h4>Battery SOC UI: " + String(soc_ui) + " </h4>"; content += "<h4>Battery SOC UI: " + String(soc_ui) + " </h4>";
content += "<h4>Battery SOC Ave: " + String(soc_ave) + " </h4>"; content += "<h4>Battery SOC Ave: " + String(soc_ave) + " </h4>";
content += "<h4>Battery SOC Max: " + String(soc_max) + " </h4>"; content += "<h4>Battery SOC Max: " + String(soc_max) + " </h4>";
@ -252,7 +285,7 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
//content += "<h4>packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "</h4>"; // Not giving useable data //content += "<h4>packConfigMultiplexer: " + String(datalayer_extended.tesla.battery_packConfigMultiplexer) + "</h4>"; // Not giving useable data
//content += "<h4>moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "</h4>"; // Not giving useable data //content += "<h4>moduleType: " + String(datalayer_extended.tesla.battery_moduleType) + "</h4>"; // Not giving useable data
//content += "<h4>reserveConfig: " + String(datalayer_extended.tesla.battery_reservedConfig) + "</h4>"; // Not giving useable data //content += "<h4>reserveConfig: " + String(datalayer_extended.tesla.battery_reservedConfig) + "</h4>"; // Not giving useable data
content += "<h4>Battery Pack Mass: " + String(packMass) + " KG</h4>"; //content += "<h4>Battery Pack Mass: " + String(packMass) + " KG</h4>";
content += "<h4>Platform Max Bus Voltage: " + String(platformMaxBusVoltage) + " V</h4>"; content += "<h4>Platform Max Bus Voltage: " + String(platformMaxBusVoltage) + " V</h4>";
//0x2D2 722 BMSVAlimits //0x2D2 722 BMSVAlimits
content += "<h4>BMS Min Voltage: " + String(bms_min_voltage) + " V</h4>"; content += "<h4>BMS Min Voltage: " + String(bms_min_voltage) + " V</h4>";
@ -273,25 +306,14 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
content += "<h4>PCS Chg PhB Temp: " + String(PCS_chgPhBTemp) + " DegC</h4>"; content += "<h4>PCS Chg PhB Temp: " + String(PCS_chgPhBTemp) + " DegC</h4>";
content += "<h4>PCS Chg PhC Temp: " + String(PCS_chgPhCTemp) + " DegC</h4>"; content += "<h4>PCS Chg PhC Temp: " + String(PCS_chgPhCTemp) + " DegC</h4>";
//0x252 594 BMS_powerAvailable //0x252 594 BMS_powerAvailable
content += "<h4>Max Regen Power: " + String(BMS_maxRegenPower) + " KW</h4>"; content += "<h4>Max Regen Power: " + String(BMS_maxRegenPower) + " kW</h4>";
content += "<h4>Max Discharge Power: " + String(BMS_maxDischargePower) + " KW</h4>"; content += "<h4>Max Discharge Power: " + String(BMS_maxDischargePower) + " kW</h4>";
//content += "<h4>Max Stationary Heat Power: " + String(BMS_maxStationaryHeatPower) + " KWh</h4>"; // Not giving useable data //content += "<h4>Max Stationary Heat Power: " + String(BMS_maxStationaryHeatPower) + " kWh</h4>"; // Not giving useable data
//content += "<h4>HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " KW</h4>"; // Not giving useable data //content += "<h4>HVAC Power Budget: " + String(BMS_hvacPowerBudget) + " kW</h4>"; // Not giving useable data
//content += "<h4>Not Enough Power For Heat Pump: " + String(noYes[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + "</h4>"; // Not giving useable data //content += "<h4>Not Enough Power For Heat Pump: " + String(noYes[datalayer_extended.tesla.BMS_notEnoughPowerForHeatPump]) + "</h4>"; // Not giving useable data
content += content +=
"<h4>Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "</h4>"; "<h4>Power Limit State: " + String(BMS_powerLimitState[datalayer_extended.tesla.BMS_powerLimitState]) + "</h4>";
//content += "<h4>Inverter TQF: " + String(datalayer_extended.tesla.BMS_inverterTQF) + "</h4>"; // Not giving useable data //content += "<h4>Inverter TQF: " + String(datalayer_extended.tesla.BMS_inverterTQF) + "</h4>"; // Not giving useable data
//0x212 530 BMS_status
content += "<h4>Isolation Resistance: " + String(isolationResistance) + " kOhms</h4>";
content +=
"<h4>BMS Contactor State: " + String(BMS_contactorState[datalayer_extended.tesla.battery_BMS_contactorState]) +
"</h4>";
content += "<h4>BMS State: " + String(BMS_state[datalayer_extended.tesla.battery_BMS_state]) + "</h4>";
content += "<h4>BMS HV State: " + String(BMS_hvState[datalayer_extended.tesla.battery_BMS_hvState]) + "</h4>";
content += "<h4>BMS UI Charge Status: " + String(BMS_uiChargeStatus[datalayer_extended.tesla.battery_BMS_hvState]) +
"</h4>";
content +=
"<h4>BMS PCS PWM Enabled: " + String(Fault[datalayer_extended.tesla.battery_BMS_pcsPwmEnabled]) + "</h4>";
//0x312 786 BMS_thermalStatus //0x312 786 BMS_thermalStatus
content += "<h4>Power Dissipation: " + String(BMS_powerDissipation) + " kW</h4>"; content += "<h4>Power Dissipation: " + String(BMS_powerDissipation) + " kW</h4>";
content += "<h4>Flow Request: " + String(BMS_flowRequest) + " LPM</h4>"; content += "<h4>Flow Request: " + String(BMS_flowRequest) + " LPM</h4>";
@ -304,36 +326,34 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
content += "<h4>BMS No Flow Request: " + String(Fault[datalayer_extended.tesla.BMS_noFlowRequest]) + "</h4>"; content += "<h4>BMS No Flow Request: " + String(Fault[datalayer_extended.tesla.BMS_noFlowRequest]) + "</h4>";
//0x224 548 PCS_dcdcStatus //0x224 548 PCS_dcdcStatus
content += content +=
"<h4>Precharge Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdcPrechargeStatus]) + "<h4>Precharge Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.PCS_dcdcPrechargeStatus]) + "</h4>";
"</h4>"; content += "<h4>12V Support Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.PCS_dcdc12VSupportStatus]) +
content +=
"<h4>12V Support Status: " + String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdc12VSupportStatus]) +
"</h4>"; "</h4>";
content += "<h4>HV Bus Discharge Status: " + content += "<h4>HV Bus Discharge Status: " +
String(PCS_dcdcStatus[datalayer_extended.tesla.battery_PCS_dcdcHvBusDischargeStatus]) + "</h4>"; String(PCS_dcdcStatus[datalayer_extended.tesla.PCS_dcdcHvBusDischargeStatus]) + "</h4>";
content += content += "<h4>Main State: " + String(PCS_dcdcMainState[datalayer_extended.tesla.PCS_dcdcMainState]) + "</h4>";
"<h4>Main State: " + String(PCS_dcdcMainState[datalayer_extended.tesla.battery_PCS_dcdcMainState]) + "</h4>"; content += "<h4>Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.PCS_dcdcSubState]) + "</h4>";
content += content += "<h4>PCS Faulted: " + String(Fault[datalayer_extended.tesla.PCS_dcdcFaulted]) + "</h4>";
"<h4>Sub State: " + String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcSubState]) + "</h4>"; content += "<h4>Output Is Limited: " + String(Fault[datalayer_extended.tesla.PCS_dcdcOutputIsLimited]) + "</h4>";
content += "<h4>PCS Faulted: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcFaulted]) + "</h4>";
content +=
"<h4>Output Is Limited: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcOutputIsLimited]) + "</h4>";
content += "<h4>Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A</h4>"; content += "<h4>Max Output Current Allowed: " + String(PCS_dcdcMaxOutputCurrentAllowed) + " A</h4>";
content += "<h4>Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRtyCnt]) +
"</h4>";
content += content +=
"<h4>12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdc12VSupportRtyCnt]) + "<h4>Precharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.PCS_dcdcPrechargeRtyCnt]) + "</h4>";
"</h4>";
content += "<h4>Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcDischargeRtyCnt]) +
"</h4>";
content += content +=
"<h4>PWM Enable Line: " + String(Fault[datalayer_extended.tesla.battery_PCS_dcdcPwmEnableLine]) + "</h4>"; "<h4>12V Support Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.PCS_dcdc12VSupportRtyCnt]) + "</h4>";
content += "<h4>Supporting Fixed LV Target: " + content +=
String(Fault[datalayer_extended.tesla.battery_PCS_dcdcSupportingFixedLvTarget]) + "</h4>"; "<h4>Discharge Rty Cnt: " + String(falseTrue[datalayer_extended.tesla.PCS_dcdcDischargeRtyCnt]) + "</h4>";
content += "<h4>Precharge Restart Cnt: " + content += "<h4>PWM Enable Line: " + String(Fault[datalayer_extended.tesla.PCS_dcdcPwmEnableLine]) + "</h4>";
String(falseTrue[datalayer_extended.tesla.battery_PCS_dcdcPrechargeRestartCnt]) + "</h4>"; content +=
"<h4>Supporting Fixed LV Target: " + String(Fault[datalayer_extended.tesla.PCS_dcdcSupportingFixedLvTarget]) +
"</h4>";
content += "<h4>Precharge Restart Cnt: " + String(falseTrue[datalayer_extended.tesla.PCS_dcdcPrechargeRestartCnt]) +
"</h4>";
content += "<h4>Initial Precharge Substate: " + content += "<h4>Initial Precharge Substate: " +
String(PCS_dcdcSubState[datalayer_extended.tesla.battery_PCS_dcdcInitialPrechargeSubState]) + "</h4>"; String(PCS_dcdcSubState[datalayer_extended.tesla.PCS_dcdcInitialPrechargeSubState]) + "</h4>";
//0x3C4 PCS_info
content += "<h4>PCS_buildConfigId: " + String(datalayer_extended.tesla.PCS_info_buildConfigId) + "</h4>";
content += "<h4>PCS_hardwareId: " + String(datalayer_extended.tesla.PCS_info_hardwareId) + "</h4>";
content += "<h4>PCS_componentId: " + String(datalayer_extended.tesla.PCS_info_componentId) + "</h4>";
//0x2C4 708 PCS_logging //0x2C4 708 PCS_logging
content += "<h4>PCS_dcdcMaxLvOutputCurrent: " + String(PCS_dcdcMaxLvOutputCurrent) + " A</h4>"; content += "<h4>PCS_dcdcMaxLvOutputCurrent: " + String(PCS_dcdcMaxLvOutputCurrent) + " A</h4>";
content += "<h4>PCS_dcdcCurrentLimit: " + String(PCS_dcdcCurrentLimit) + " A</h4>"; content += "<h4>PCS_dcdcCurrentLimit: " + String(PCS_dcdcCurrentLimit) + " A</h4>";
@ -355,6 +375,10 @@ class TeslaHtmlRenderer : public BatteryHtmlRenderer {
content += "<h4>PCS_dcdcIntervalMinLvBusVolt: " + String(PCS_dcdcIntervalMinLvBusVolt) + " V</h4>"; content += "<h4>PCS_dcdcIntervalMinLvBusVolt: " + String(PCS_dcdcIntervalMinLvBusVolt) + " V</h4>";
content += "<h4>PCS_dcdcIntervalMinLvOutputCurr: " + String(PCS_dcdcIntervalMinLvOutputCurr) + " A</h4>"; content += "<h4>PCS_dcdcIntervalMinLvOutputCurr: " + String(PCS_dcdcIntervalMinLvOutputCurr) + " A</h4>";
content += "<h4>PCS_dcdc12vSupportLifetimekWh: " + String(PCS_dcdc12vSupportLifetimekWh) + " kWh</h4>"; content += "<h4>PCS_dcdc12vSupportLifetimekWh: " + String(PCS_dcdc12vSupportLifetimekWh) + " kWh</h4>";
//0x310 HVP_info
content += "<h4>HVP_buildConfigId: " + String(datalayer_extended.tesla.HVP_info_buildConfigId) + "</h4>";
content += "<h4>HVP_hardwareId: " + String(datalayer_extended.tesla.HVP_info_hardwareId) + "</h4>";
content += "<h4>HVP_componentId: " + String(datalayer_extended.tesla.HVP_info_componentId) + "</h4>";
//0x7AA 1962 HVP_debugMessage //0x7AA 1962 HVP_debugMessage
content += "<h4>HVP_battery12V: " + String(HVP_battery12V) + " V</h4>"; content += "<h4>HVP_battery12V: " + String(HVP_battery12V) + " V</h4>";
content += "<h4>HVP_dcLinkVoltage: " + String(HVP_dcLinkVoltage) + " V</h4>"; content += "<h4>HVP_dcLinkVoltage: " + String(HVP_dcLinkVoltage) + " V</h4>";

View file

@ -355,9 +355,9 @@ typedef struct {
typedef struct { typedef struct {
/** uint8_t */ /** uint8_t */
/** Contactor status */ /** Contactor status */
uint8_t status_contactor = 0; //uint8_t status_contactor = 0;
/** uint8_t */ /** uint8_t */
/** Contactor status */ /** HVIL status */
uint8_t hvil_status = 0; uint8_t hvil_status = 0;
/** uint8_t */ /** uint8_t */
/** Negative contactor state */ /** Negative contactor state */
@ -366,12 +366,12 @@ typedef struct {
/** Positive contactor state */ /** Positive contactor state */
uint8_t packContPositiveState = 0; uint8_t packContPositiveState = 0;
/** uint8_t */ /** uint8_t */
/** Set state of contactors */ /** HVP set state of contactors */
uint8_t packContactorSetState = 0; uint8_t packContactorSetState = 0;
/** uint8_t */ /** bool */
/** Battery pack allows closing of contacors */ /** Battery pack allows closing of contactors */
uint8_t packCtrsClosingAllowed = 0; bool packCtrsClosingBlocked = false;
/** uint8_t */ /** bool */
/** Pyro test in progress */ /** Pyro test in progress */
bool pyroTestInProgress = false; bool pyroTestInProgress = false;
bool battery_packCtrsOpenNowRequested = false; bool battery_packCtrsOpenNowRequested = false;
@ -379,7 +379,22 @@ typedef struct {
uint8_t battery_packCtrsRequestStatus = 0; uint8_t battery_packCtrsRequestStatus = 0;
bool battery_packCtrsResetRequestRequired = false; bool battery_packCtrsResetRequestRequired = false;
bool battery_dcLinkAllowedToEnergize = false; bool battery_dcLinkAllowedToEnergize = false;
uint8_t BMS_SerialNumber[15] = {0}; //stores raw HEX values for ASCII chars uint8_t BMS_partNumber[12] = {0}; //stores raw HEX values for ASCII chars
uint16_t BMS_info_buildConfigId = 0;
uint16_t BMS_info_hardwareId = 0;
uint16_t BMS_info_componentId = 0;
uint8_t BMS_info_pcbaId = 0;
uint8_t BMS_info_assemblyId = 0;
uint16_t BMS_info_usageId = 0;
uint16_t BMS_info_subUsageId = 0;
uint8_t BMS_info_platformType = 0;
uint32_t BMS_info_appCrc = 0;
uint64_t BMS_info_bootGitHash = 0;
uint8_t BMS_info_bootUdsProtoVersion = 0;
uint32_t BMS_info_bootCrc = 0;
uint8_t battery_serialNumber[15] = {0}; //stores raw HEX values for ASCII chars
uint8_t battery_partNumber[12] = {0}; //stores raw HEX values for ASCII chars
char* battery_manufactureDate;
uint8_t battery_beginning_of_life = 0; uint8_t battery_beginning_of_life = 0;
uint8_t battery_battTempPct = 0; uint8_t battery_battTempPct = 0;
uint16_t battery_dcdcLvBusVolt = 0; uint16_t battery_dcdcLvBusVolt = 0;
@ -413,37 +428,23 @@ typedef struct {
uint16_t battery_reservedConfig = 0; uint16_t battery_reservedConfig = 0;
uint32_t battery_packMass = 0; uint32_t battery_packMass = 0;
uint32_t battery_platformMaxBusVoltage = 0; uint32_t battery_platformMaxBusVoltage = 0;
uint32_t battery_bms_min_voltage = 0; uint32_t BMS_min_voltage = 0;
uint32_t battery_bms_max_voltage = 0; uint32_t BMS_max_voltage = 0;
uint32_t battery_max_charge_current = 0; uint32_t battery_max_charge_current = 0;
uint32_t battery_max_discharge_current = 0; uint32_t battery_max_discharge_current = 0;
uint32_t battery_soc_min = 0; uint32_t battery_soc_min = 0;
uint32_t battery_soc_max = 0; uint32_t battery_soc_max = 0;
uint32_t battery_soc_ave = 0; uint32_t battery_soc_ave = 0;
uint32_t battery_soc_ui = 0; uint32_t battery_soc_ui = 0;
uint8_t battery_BMS_contactorState = 0; bool BMS_hvilFault = false;
uint8_t battery_BMS_state = 0; uint8_t BMS_contactorState = 0;
uint8_t battery_BMS_hvState = 0; uint8_t BMS_state = 0;
uint16_t battery_BMS_isolationResistance = 0; uint8_t BMS_hvState = 0;
uint8_t battery_BMS_uiChargeStatus = 0; uint16_t BMS_isolationResistance = 0;
bool battery_BMS_diLimpRequest = false; uint8_t BMS_uiChargeStatus = 0;
uint16_t battery_BMS_chgPowerAvailable = 0; bool BMS_diLimpRequest = false;
bool battery_BMS_pcsPwmEnabled = false; uint16_t BMS_chgPowerAvailable = 0;
uint8_t battery_PCS_dcdcPrechargeStatus = 0; bool BMS_pcsPwmEnabled = false;
uint8_t battery_PCS_dcdc12VSupportStatus = 0;
uint8_t battery_PCS_dcdcHvBusDischargeStatus = 0;
uint8_t battery_PCS_dcdcMainState = 0;
uint8_t battery_PCS_dcdcSubState = 0;
bool battery_PCS_dcdcFaulted = false;
bool battery_PCS_dcdcOutputIsLimited = false;
uint16_t battery_PCS_dcdcMaxOutputCurrentAllowed = 0;
uint8_t battery_PCS_dcdcPrechargeRtyCnt = 0;
uint8_t battery_PCS_dcdc12VSupportRtyCnt = 0;
uint8_t battery_PCS_dcdcDischargeRtyCnt = 0;
uint8_t battery_PCS_dcdcPwmEnableLine = 0;
uint8_t battery_PCS_dcdcSupportingFixedLvTarget = 0;
uint8_t battery_PCS_dcdcPrechargeRestartCnt = 0;
uint8_t battery_PCS_dcdcInitialPrechargeSubState = 0;
uint16_t BMS_maxRegenPower = 0; uint16_t BMS_maxRegenPower = 0;
uint16_t BMS_maxDischargePower = 0; uint16_t BMS_maxDischargePower = 0;
uint16_t BMS_maxStationaryHeatPower = 0; uint16_t BMS_maxStationaryHeatPower = 0;
@ -460,6 +461,35 @@ typedef struct {
uint16_t BMS_packTMax = 0; uint16_t BMS_packTMax = 0;
bool BMS_pcsNoFlowRequest = false; bool BMS_pcsNoFlowRequest = false;
bool BMS_noFlowRequest = false; bool BMS_noFlowRequest = false;
uint8_t PCS_dcdcPrechargeStatus = 0;
uint8_t PCS_dcdc12VSupportStatus = 0;
uint8_t PCS_dcdcHvBusDischargeStatus = 0;
uint8_t PCS_dcdcMainState = 0;
uint8_t PCS_dcdcSubState = 0;
bool PCS_dcdcFaulted = false;
bool PCS_dcdcOutputIsLimited = false;
uint16_t PCS_dcdcMaxOutputCurrentAllowed = 0;
uint8_t PCS_dcdcPrechargeRtyCnt = 0;
uint8_t PCS_dcdc12VSupportRtyCnt = 0;
uint8_t PCS_dcdcDischargeRtyCnt = 0;
uint8_t PCS_dcdcPwmEnableLine = 0;
uint8_t PCS_dcdcSupportingFixedLvTarget = 0;
uint8_t PCS_dcdcPrechargeRestartCnt = 0;
uint8_t PCS_dcdcInitialPrechargeSubState = 0;
uint8_t PCS_partNumber[13] = {0}; //stores raw HEX values for ASCII chars
uint16_t PCS_info_buildConfigId = 0;
uint16_t PCS_info_hardwareId = 0;
uint16_t PCS_info_componentId = 0;
uint8_t PCS_info_pcbaId = 0;
uint8_t PCS_info_assemblyId = 0;
uint16_t PCS_info_usageId = 0;
uint16_t PCS_info_subUsageId = 0;
uint8_t PCS_info_platformType = 0;
uint32_t PCS_info_appCrc = 0;
uint32_t PCS_info_cpu2AppCrc = 0;
uint64_t PCS_info_bootGitHash = 0;
uint8_t PCS_info_bootUdsProtoVersion = 0;
uint32_t PCS_info_bootCrc = 0;
uint16_t PCS_dcdcTemp = 0; uint16_t PCS_dcdcTemp = 0;
uint16_t PCS_ambientTemp = 0; uint16_t PCS_ambientTemp = 0;
uint16_t PCS_chgPhATemp = 0; uint16_t PCS_chgPhATemp = 0;
@ -516,6 +546,19 @@ typedef struct {
bool HVP_currentSenseMia = false; bool HVP_currentSenseMia = false;
bool HVP_shuntRefVoltageMismatch = false; bool HVP_shuntRefVoltageMismatch = false;
bool HVP_shuntThermistorMia = false; bool HVP_shuntThermistorMia = false;
uint8_t HVP_partNumber[13] = {0}; //stores raw HEX values for ASCII chars
uint16_t HVP_info_buildConfigId = 0;
uint16_t HVP_info_hardwareId = 0;
uint16_t HVP_info_componentId = 0;
uint8_t HVP_info_pcbaId = 0;
uint8_t HVP_info_assemblyId = 0;
uint16_t HVP_info_usageId = 0;
uint16_t HVP_info_subUsageId = 0;
uint8_t HVP_info_platformType = 0;
uint32_t HVP_info_appCrc = 0;
uint64_t HVP_info_bootGitHash = 0;
uint8_t HVP_info_bootUdsProtoVersion = 0;
uint32_t HVP_info_bootCrc = 0;
uint8_t HVP_shuntHwMia = 0; uint8_t HVP_shuntHwMia = 0;
uint16_t HVP_dcLinkVoltage = 0; uint16_t HVP_dcLinkVoltage = 0;
uint16_t HVP_packVoltage = 0; uint16_t HVP_packVoltage = 0;