diff --git a/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/ph2_commands.cpp b/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/ph2_commands.cpp index 765a1f6..0ce511d 100644 --- a/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/ph2_commands.cpp +++ b/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/ph2_commands.cpp @@ -38,80 +38,18 @@ #include "ovms_netmanager.h" #include "vehicle_renaultzoe_ph2_can.h" +#include "ph2_poller.h" void OvmsVehicleRenaultZoePh2CAN::CanInit() { OvmsCommand* cmd; OvmsCommand* obd; - obd = cmd_xrt->RegisterCommand("can", "CAN tools"); + obd = cmd_zoe_ph2->RegisterCommand("can", "CAN tools"); cmd = obd->RegisterCommand("request", "Send ISO-TP request, output response"); cmd->RegisterCommand("device", "Send ISO-TP request to a ECU", shell_can_request, " ", 3, 3); cmd->RegisterCommand("broadcast", "Send ISO-TP request as broadcast", shell_can_request, "", 1, 1); } -void OvmsVehicleRenaultZoePh2CAN::shell_obd_request(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv) -{ - uint16_t txid = 0, rxid = 0; - string request; - string response; - - // parse args: - string device = cmd->GetName(); - if (device == "device") { - if (argc < 3) { - writer->puts("ERROR: too few args, need: txid rxid request"); - return; - } - txid = strtol(argv[0], NULL, 16); - rxid = strtol(argv[1], NULL, 16); - request = hexdecode(argv[2]); - } else { - if (argc < 1) { - writer->puts("ERROR: too few args, need: request"); - return; - } - request = hexdecode(argv[0]); - // "broadcast" - txid = 0x7df; - rxid = 0; - } - - // validate request: - if (request.size() == 0) { - writer->puts("ERROR: no request"); - return; - } else { - uint8_t type = request.at(0); - if ((POLL_TYPE_HAS_16BIT_PID(type) && request.size() < 3) || - (POLL_TYPE_HAS_8BIT_PID(type) && request.size() < 2)) { - writer->printf("ERROR: request too short for type %02X\n", type); - return; - } - } - - // execute request: - int err = OvmsVehicleRenaultZoePh2CAN->CanRequest(txid, rxid, request, response); - if (err == -1) { - writer->puts("ERROR: timeout waiting for response"); - return; - } else if (err) { - writer->printf("ERROR: request failed with response error code %02X\n", err); - return; - } - - // output response as hex dump: - writer->puts("Response:"); - char *buf = NULL; - size_t rlen = response.size(), offset = 0; - do { - rlen = FormatHexDump(&buf, response.data() + offset, rlen, 16); - offset += 16; - writer->puts(buf ? buf : "-"); - } while (rlen); - if (buf) - free(buf); -} - int OvmsVehicleRenaultZoePh2CAN::CanRequest(uint16_t txid, uint16_t rxid, string request, string& response, int timeout_ms /*=3000*/) { OvmsMutexLock lock(&zoe_can1_request); @@ -163,6 +101,70 @@ int OvmsVehicleRenaultZoePh2CAN::CanRequest(uint16_t txid, uint16_t rxid, string return (rxok == pdFALSE) ? -1 : (int)zoe_can1_rxerr; } +void OvmsVehicleRenaultZoePh2CAN::shell_can_request(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv) +{ + OvmsVehicleRenaultZoePh2CAN* zoe_ph2_can = GetInstance(writer); + uint16_t txid = 0, rxid = 0; + string request; + string response; + + // parse args: + string device = cmd->GetName(); + if (device == "device") { + if (argc < 3) { + writer->puts("ERROR: too few args, need: txid rxid request"); + return; + } + txid = strtol(argv[0], NULL, 16); + rxid = strtol(argv[1], NULL, 16); + request = hexdecode(argv[2]); + } else { + if (argc < 1) { + writer->puts("ERROR: too few args, need: request"); + return; + } + request = hexdecode(argv[0]); + // "broadcast" + txid = 0x7df; + rxid = 0; + } + + // validate request: + if (request.size() == 0) { + writer->puts("ERROR: no request"); + return; + } else { + uint8_t type = request.at(0); + if ((POLL_TYPE_HAS_16BIT_PID(type) && request.size() < 3) || + (POLL_TYPE_HAS_8BIT_PID(type) && request.size() < 2)) { + writer->printf("ERROR: request too short for type %02X\n", type); + return; + } + } + + // execute request: + int err = zoe_ph2_can->CanRequest(txid, rxid, request, response, 3000); + if (err == -1) { + writer->puts("ERROR: timeout waiting for response"); + return; + } else if (err) { + writer->printf("ERROR: request failed with response error code %02X\n", err); + return; + } + + // output response as hex dump: + writer->puts("Response:"); + char *buf = NULL; + size_t rlen = response.size(), offset = 0; + do { + rlen = FormatHexDump(&buf, response.data() + offset, rlen, 16); + offset += 16; + writer->puts(buf ? buf : "-"); + } while (rlen); + if (buf) + free(buf); +} + OvmsVehicle::vehicle_command_t OvmsVehicleRenaultZoePh2CAN::CommandPreHeat(bool climatecontrolon) { //ToDo: Sniff TCU packets for preheat/cool, OVMS is connected on TCU port return NotImplemented; diff --git a/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/vehicle_renaultzoe_ph2_can.cpp b/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/vehicle_renaultzoe_ph2_can.cpp index f51f7a8..2c3a058 100644 --- a/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/vehicle_renaultzoe_ph2_can.cpp +++ b/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/vehicle_renaultzoe_ph2_can.cpp @@ -167,7 +167,7 @@ void OvmsVehicleRenaultZoePh2CAN::IncomingFrameCan2(CAN_frame_t* p_frame) { * Handles incoming poll results */ void OvmsVehicleRenaultZoePh2CAN::IncomingPollReply(canbus* bus, uint16_t type, uint16_t pid, uint8_t* data, uint8_t length, uint16_t remain) { - string& rxbuf = zoe_obd_rxbuf; + string& rxbuf = zoe_can1_rxbuf; //ESP_LOGV(TAG, "pid: %04x length: %d m_poll_ml_remain: %d m_poll_ml_frame: %d", pid, length, m_poll_ml_remain, m_poll_ml_frame); @@ -326,7 +326,8 @@ void OvmsVehicleRenaultZoePh2CAN::Ticker1(uint32_t ticker) { if (!StandardMetrics.ms_v_env_locked->AsBool()) { MyNotify.NotifyString("alert", "vehicle.lock", "Vehicle is not locked"); } - + } + } if (StandardMetrics.ms_v_env_on->AsBool() && !CarIsDriving) { CarIsDriving = true; @@ -384,7 +385,7 @@ class OvmsVehicleRenaultZoePh2CANInit { } MyOvmsVehicleRenaultZoePh2CANInit __attribute__ ((init_priority (9000))); -OvmsVehicleRenaultZoePh2CANInit::OvmsVehicleRenaultZoePh2CANInit() +OvmsVehicleRenaultZoePh2CANInit::OvmsVehicleRenaultZoePh2CANInit() { ESP_LOGI(TAG, "Registering Vehicle: Renault Zoe Ph2 (CAN) (9000)"); MyVehicleFactory.RegisterVehicle("RZ2","Renault Zoe Ph2 (CAN)"); diff --git a/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/vehicle_renaultzoe_ph2_can.h b/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/vehicle_renaultzoe_ph2_can.h index 58c3f70..7cf5cd1 100644 --- a/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/vehicle_renaultzoe_ph2_can.h +++ b/OVMS.V3/components/vehicle_renaultzoe_ph2_can/src/vehicle_renaultzoe_ph2_can.h @@ -67,8 +67,9 @@ class OvmsVehicleRenaultZoePh2CAN : public OvmsVehicle { static void WebCfgCommon(PageEntry_t& p, PageContext_t& c); void ConfigChanged(OvmsConfigParam* param); void ZoeWakeUp(); - void IncomingFrameCan1(CAN_frame_t* p_frame); - void IncomingPollReply(canbus* bus, uint16_t type, uint16_t pid, uint8_t* data, uint8_t length, uint16_t remain); + void IncomingFrameCan1(CAN_frame_t* p_frame); + void IncomingFrameCan2(CAN_frame_t* p_frame); + void IncomingPollReply(canbus* bus, uint16_t type, uint16_t pid, uint8_t* data, uint8_t length, uint16_t remain); void WebInit(); void WebDeInit(); bool CarIsCharging = false; @@ -79,16 +80,16 @@ class OvmsVehicleRenaultZoePh2CAN : public OvmsVehicle { float ACInputPowerFactor = 0.0; float Bat_cell_capacity = 0.0; - protected: + protected: int m_range_ideal; int m_battery_capacity; bool m_UseCarTrip = false; bool m_UseBMScalculation = false; char zoe_vin[18] = ""; - void IncomingINV(uint16_t type, uint16_t pid, const char* data, uint16_t len); - void IncomingEVC(uint16_t type, uint16_t pid, const char* data, uint16_t len); - void IncomingBCM(uint16_t type, uint16_t pid, const char* data, uint16_t len); - void IncomingLBC(uint16_t type, uint16_t pid, const char* data, uint16_t len); + void IncomingINV(uint16_t type, uint16_t pid, const char* data, uint16_t len); + void IncomingEVC(uint16_t type, uint16_t pid, const char* data, uint16_t len); + void IncomingBCM(uint16_t type, uint16_t pid, const char* data, uint16_t len); + void IncomingLBC(uint16_t type, uint16_t pid, const char* data, uint16_t len); void IncomingHVAC(uint16_t type, uint16_t pid, const char* data, uint16_t len); void IncomingUCM(uint16_t type, uint16_t pid, const char* data, uint16_t len); //void IncomingCLUSTER(uint16_t type, uint16_t pid, const char* data, uint16_t len); @@ -99,16 +100,8 @@ class OvmsVehicleRenaultZoePh2CAN : public OvmsVehicle { virtual void Ticker10(uint32_t ticker);//Handle charge, energy statistics virtual void Ticker1(uint32_t ticker); //Handle trip counter - protected: - OvmsSemaphore zoe_can1_rxwait; - uint16_t zoe_can1_rxerr; - string zoe_can1_rxbuf; - OvmsMutex zoe_can1_request; - private: unsigned int m_can1_activity_timer; - - OvmsCommand *cmd_zoe_ph2; // Renault ZOE specific metrics OvmsMetricBool *mt_bus_awake; //CAN bus awake status @@ -135,14 +128,24 @@ class OvmsVehicleRenaultZoePh2CAN : public OvmsVehicle { OvmsMetricString *mt_hvac_compressor_mode; //Compressor mode OvmsMetricFloat *mt_v_env_pressure; //Ambient air pressure + //CAN Commands section + public: + static OvmsVehicleRenaultZoePh2CAN* GetInstance(OvmsWriter* writer=NULL); + void CanInit(); + int CanRequest(uint16_t txid, uint16_t rxid, string request, string& response, int timeout_ms); + static void shell_can_request(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, const char* const* argv); + virtual vehicle_command_t CommandPreHeat(bool climatecontrolon); virtual vehicle_command_t CommandWakeup(); - virtual vehicle_command_t CommandPreHeat(bool enable); virtual vehicle_command_t CommandLock(const char* pin); virtual vehicle_command_t CommandUnlock(const char* pin); protected: - string zoe_obd_rxbuf; + OvmsCommand *cmd_zoe_ph2; + string zoe_can1_rxbuf; + OvmsSemaphore zoe_can1_rxwait; + uint16_t zoe_can1_rxerr; + OvmsMutex zoe_can1_request; }; #endif //#ifndef __VEHICLE_RENAULTZOE_PH2_OBD_H__