<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Tom,<div class=""><br class=""></div><div class=""><blockquote type="cite" class="">When I play a can bus recording I see the metrics update!</blockquote><br class=""></div><div class="">Sounds great. It is pretty cool to see the metrics populated. Much easier to ensure everything is working than with v2.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">I see that quite a few of the metrics used on the leaf are missing. Do I just add them to metrics_standard.cpp? None of them are particularly leaf specific, so this seems the right place.</blockquote><br class=""></div><div class="">I just added the very basic ones, as a starting point and proof of concept. Hadn’t decided if I needed anything special for the bitmapped ones at the time (either a new MetricBitmap type, or extend MetricInt). Looking at how things have evolved, and bearing in mind the GAPP bluetooth stuff, and OVMS v3 MQTT, it seems that each bit should be a metric of their own. Not too hard for ovms_server_v2 to convert that back to an integer bitmap, for backwards compatibility. To do that, car_doors1 becomes:</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class="">v.d.frontleft: bool</li><li class="">v.d.frontright: bool</li><li class="">v.d.chargeport: bool</li><li class="">v.c.pilot: bool</li><li class="">v.c.charging: bool</li><li class="">v.e.handbrake: bool</li><li class="">v.e.caron: bool</li></ul></div><div class=""><br class=""></div><div class="">N.B. The ‘v.’ is the prefix for vehicle metrics, then the second part becomes the area of the vehicle (‘b.’ for battery, ‘p.’ for position, ‘tp.’ for tpms, ‘d.’ for doors, ‘c.’ for charger, etc).</div><div class=""><br class=""></div><div class="">So, if you have time, please go ahead and add the other standard ones that are simple and shared across all cars. You need to add a '#define MS_V_…’ for the string name, then a ‘ms_v_…’ member variable to MetricsStandard, then change MetricsStandard::MetricsStandard() constructor to create the metric itself and store a pointer in the member variable.</div><div class=""><br class=""></div><div class="">I guess we need to add all the car_ ones from ovms.h in the v2 project. Here are the ones outstanding:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_linevoltage; // Line Voltage</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_chargecurrent; // Charge Current</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_chargelimit; // Charge Limit (amps)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_chargeduration; // Charge Duration (minutes)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_chargestate; // 1=charging, 2=top off, 4=done, 13=preparing to charge, 21-25=stopped charging</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_chargesubstate;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_chargemode; // 0=standard, 1=storage, 3=range, 4=performance</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_charge_b4; // B4 byte of charge state</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_chargekwh; // Energy charged (1/10 kWh)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern chargetype car_chargetype;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_chargepower; // Charge Power (1/10 kW)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_battvoltage; // Battery Voltage (1/10 V)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_doors1;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">typedef struct {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned FrontLeftDoor:1;     // 0x01</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned FrontRightDoor:1;    // 0x02</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned ChargePort:1;        // 0x04</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned PilotSignal:1;       // 0x08</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned Charging:1;          // 0x10</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x20</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned HandBrake:1;         // 0x40</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned CarON:1;             // 0x80</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">} car_doors1bits_t;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define car_doors1bits (*((car_doors1bits_t*)&car_doors1))</span></font></div></div><div class=""><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_doors2;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">typedef struct {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x01</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x02</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x04</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned CarLocked:1;         // 0x08</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned ValetMode:1;         // 0x10</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned Headlights:1;        // 0x20</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned Bonnet:1;            // 0x40</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned Trunk:1;             // 0x80</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">} car_doors2bits_t;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define car_doors2bits (*((car_doors2bits_t*)&car_doors2))</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_doors3;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">typedef struct {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned CarAwake:1;          // 0x01</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned CoolingPump:1;       // 0x02</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x04</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x08</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x10</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x20</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned CtrlLoggedIn:1;      // 0x40 - logged into controller</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned CtrlCfgMode:1;       // 0x80 - controller in configuration mode</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">} car_doors3bits_t;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define car_doors3bits (*((car_doors3bits_t*)&car_doors3))</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_doors4;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">typedef struct {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x01</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned AlarmSounds:1;       // 0x02</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x04</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x08</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x10</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x20</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x40</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x80</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">} car_doors4bits_t;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define car_doors4bits (*((car_doors4bits_t*)&car_doors4))</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_doors5;</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">typedef struct {</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned RearLeftDoor:1;      // 0x01</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned RearRightDoor:1;     // 0x02</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned Frunk:1;             // 0x04</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x08</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned Charging12V:1;       // 0x10</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x20</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned :1;                  // 0x40</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">  unsigned HVAC:1;              // 0x80</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">} car_doors5bits_t;</span></font></div></div><div class=""><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_lockstate; // Lock State</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_drivemode; // Car specific encoding of current drive mode</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed int car_power; // Current battery power level (1/10 kW)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned long car_energy_used; // Energy used on trip (Wh)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned long car_energy_recd; // Energy recovered on trip (Wh)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned long car_time; // UTC Time</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned long car_parktime; // UTC time car was parked (or 0 if not)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_stopped_mincnt; // Minute countdown while stopped</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed char car_timermode; // Timer mode (0=onplugin, 1=timer)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_timerstart; // Timer start</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_gpslock; // GPS lock status & satellite count</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define GPS_LOCK()   ((car_gpslock & 0b11000000) >> 6)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define GPS_SATCNT() (car_gpslock & 0b00111111)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed char car_stale_ambient; // 0 = Ambient temperature is stale</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed char car_stale_temps; // 0 = Powertrain temperatures are stale</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed char car_stale_gps; // 0 = gps is stale</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed char car_stale_tpms; // 0 = tpms is stale</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed char car_stale_timer; // 0 = timer is stale</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char net_reg; // Network registration</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char net_link; // Network link status</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char net_iccid[MAX_ICCID]; // ICCID</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern char net_apps_connected; // Network apps connected</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern char sys_features[FEATURES_MAX]; // System features</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char net_sq; // GSM Network Signal Quality</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_12v_current; // 12V (DC converter) current in 1/10 A</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_gsmcops[9]; // GSM provider</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed int car_chargefull_minsremaining;  // ETR for 100%</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed int car_chargelimit_minsremaining_range; // ETR for range limit</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed int car_chargelimit_minsremaining_soc; // ETR for SOC limit</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_chargelimit_rangelimit;   // Range limit (in vehicle units)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_chargelimit_soclimit;    // SOC% limit</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_max_idealrange; // Maximum ideal range in miles</span></font></div></div><div class=""><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed char car_coolingdown;              // >=0 if car is cooling down</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_cooldown_chargemode;    // 0=standard, 1=storage, 3=range, 4=performance</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_cooldown_chargelimit;   // Charge Limit (amps)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern signed int car_cooldown_tbattery;         // Cooldown temperature limit</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned int car_cooldown_timelimit;      // Cooldown time limit (minutes) remaining</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_cooldown_wascharging;   // TRUE if car was charging when cooldown started</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern int car_chargeestimate;                   // ACC: charge time estimation for current charger capabilities (min.)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">extern unsigned char car_SOCalertlimit;           // Low limit of SOC at which alert should be raised</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class=""><br class=""></span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define CAR_IS_ON (car_doors1bits.CarON)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define CAR_IS_CHARGING (car_doors1bits.Charging)</span></font></div><div class=""><font face="Andale Mono" class=""><span style="font-size: 14px;" class="">#define CAR_IS_HEATING (car_chargestate==0x0f)</span></font></div></div></blockquote><div class=""><br class=""></div><div class="">Now, a bunch of those aren’t necessary to convert.</div><div class=""><br class=""></div><div class=""><ul class="MailOutline"><li class="">We have ‘modifiers’ to track whether something has been modified, and I’ve just added m_lastmodified (and GetLastModified()), and m_stale (and SetStale()) to metrics, to allow us to know if a metric is stale or not. So, now all those _stale variables can go (and ovms_server_v2 can work it out itself).</li><li class="">Then we have a bunch that seem to be not actually used in protocol messages. Those should either be vehicle-specific (so not in standard_metrics), or just stored in the vehicle module itself.</li></ul></div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">Is anyone working on the v2 server support code to send the S and D messages?</blockquote></div><div class=""><br class=""></div><div class="">Nope. Not at the moment. I’ve stubbed it.</div><div class=""><br class=""></div><div class="">The v2 code used CRCs to check if something has been modified. The stubbed version doesn’t use that. I think we can use modifiers on the metrics to know whether the metric itself has changed. I tried implementing one (TransmitMsgTPMS) and that went quite cleanly. It was wordy, but overall looked neat. Certainly easier for the vehicle modules not to have to maintain these CRCs and decrementing timers.</div><div class=""><br class=""></div><div class="">Let me know what you think, and if you have time to try to implement some of this.</div><div class=""><br class=""></div><div class="">Regards, Mark.</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 3 Oct 2017, at 5:33 PM, Tom Parker <<a href="mailto:tom@carrott.org" class="">tom@carrott.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hi all,<br class=""><br class="">I got my USB CAN bus interface working with the OVMS v3 hardware on my desk, it turns out you need at least one terminator before the bus will work!<br class=""><br class="">I cargo culted (I've never written C++) my way through transposing the Leaf OVMS v2 can bus decoder into the v3 code. When I play a can bus recording I see the metrics update!<br class=""><br class="">I see that quite a few of the metrics used on the leaf are missing. Do I just add them to metrics_standard.cpp? None of them are particularly leaf specific, so this seems the right place.<br class=""><br class="">Is anyone working on the v2 server support code to send the S and D messages?<br class=""><br class="">_______________________________________________<br class="">OvmsDev mailing list<br class=""><a href="mailto:OvmsDev@lists.teslaclub.hk" class="">OvmsDev@lists.teslaclub.hk</a><br class="">http://lists.teslaclub.hk/mailman/listinfo/ovmsdev<br class=""></div></div></blockquote></div><br class=""></div></body></html>