<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br></div>I've just pushed to github the stub for an implementation of this.<div><br></div><div>The key data structure is:</div><div><br></div><div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><div><div><font face="Andale Mono">#define LOG_TYPE_CHARGE 'C' // A charge log record</font></div><div><font face="Andale Mono">#define LOG_TYPE_CHARGING 'c' // A charging log record</font></div><div><font face="Andale Mono">#define LOG_TYPE_DRIVE 'D' // A drive log record</font></div><div><font face="Andale Mono">#define LOG_TYPE_DRIVING 'd' // A driving log record</font></div><div><font face="Andale Mono">#define LOG_TYPE_FREE 'F' // A free log record</font></div><div><font face="Andale Mono"><br></font></div><div><font face="Andale Mono">#define LOG_CHARGERESULT_OK 'D' // Result if charge was ok</font></div><div><font face="Andale Mono">#define LOG_CHARGERESULT_STOP 'S' // Result if charge was stopped</font></div><div><font face="Andale Mono">#define LOG_CHARGERESULT_FAIL 'F' // Result if charge failed</font></div><div><font face="Andale Mono"><br></font></div><div><font face="Andale Mono">#define LOG_RECORDSTORE 4 // Number of records that can be stored</font></div><div><font face="Andale Mono"><br></font></div><div><font face="Andale Mono">struct logging_record</font></div><div><font face="Andale Mono"> {</font></div><div><font face="Andale Mono"> unsigned char type; // One of LOG_TYPE_*</font></div><div><font face="Andale Mono"> unsigned long start_time; // Time (car_time) log record created</font></div><div><font face="Andale Mono"> unsigned int duration; // Log record duration</font></div><div><font face="Andale Mono"> union</font></div><div><font face="Andale Mono"> {</font></div><div><font face="Andale Mono"> struct</font></div><div><font face="Andale Mono"> {</font></div><div><font face="Andale Mono"> unsigned char charge_mode; // Mode vehicle was charging in</font></div><div><font face="Andale Mono"> signed long charge_latitude; // Raw GPS Latitude</font></div><div><font face="Andale Mono"> signed long charge_longitude; // Raw GPS Longitude</font></div><div><font face="Andale Mono"> unsigned int charge_voltage; // Largest line voltage during charge</font></div><div><font face="Andale Mono"> unsigned char charge_current; // Largest lien current during charge</font></div><div><font face="Andale Mono"> unsigned char charge_result; // One of LOG_CHARGERESULT_*</font></div><div><font face="Andale Mono"> unsigned char start_SOC;</font></div><div><font face="Andale Mono"> unsigned int start_idealrange;</font></div><div><font face="Andale Mono"> unsigned char end_SOC;</font></div><div><font face="Andale Mono"> unsigned int end_idealrange;</font></div><div><font face="Andale Mono"> } charge;</font></div><div><font face="Andale Mono"> struct</font></div><div><font face="Andale Mono"> {</font></div><div><font face="Andale Mono"> unsigned char drive_mode; // Mode vehicle was driven in</font></div><div><font face="Andale Mono"> signed long start_latitude; // Raw GPS Latitude</font></div><div><font face="Andale Mono"> signed long start_longitude; // Raw GPS Longitude</font></div><div><font face="Andale Mono"> signed long end_latitude; // Raw GPS Latitude</font></div><div><font face="Andale Mono"> signed long end_longitude; // Raw GPS Longitude</font></div><div><font face="Andale Mono"> unsigned long distance; // Distance driven (or start odometer for 'd')</font></div><div><font face="Andale Mono"> unsigned char start_SOC;</font></div><div><font face="Andale Mono"> unsigned int start_idealrange;</font></div><div><font face="Andale Mono"> unsigned char end_SOC;</font></div><div><font face="Andale Mono"> unsigned int end_idealrange;</font></div><div><font face="Andale Mono"> } drive;</font></div><div><font face="Andale Mono"> } record;</font></div><div><font face="Andale Mono"> };</font></div></div><div><font face="Andale Mono"><br></font></div><div><div><font face="Andale Mono">#pragma udata LOGGING</font></div><div><font face="Andale Mono">struct logging_record log_recs[LOG_RECORDSTORE];</font></div></div><div><div><font face="Andale Mono">signed char logging_pos = -1;</font></div></div></blockquote></div><div><br></div><div>The idea is that we create an array data structure containing up to LOG_RECORDSTORE log records. I've got this set to 4 at the moment, and that is the number of charges/drives that can be stored without GPRS connectivity, before drive/charge records are lost. One slot is needed the for 'current' drive/charge, and the others are used for historical data.</div><div><br></div><div>Each record (slot) has a type - either a current/historical drive, or a current/historical charge, or free. When the system needs a free slot, it tries to find one marked 'free', otherwise it will dump the oldest one.</div><div><br></div><div>We'll have a process that looks for GPRS connectivity, and if it is good and stable it will try to send completed drive and charge records to the server. Once sent, the slot can be freed. I'm going to try to introduce a send/ack style protocol for this, so the server can ack the data record it receives.</div><div><br></div><div>The data returned to the server will be whatever is in those records.</div><div><br></div><div>Comments / suggestions welcome (particularly from vehicles other that Tesla Roadster, as I need to know if this meets your needs).</div><div><br></div><div>Regards, Mark.</div><div><br></div><div>P.S. Michael: I added the standard car_* variables for limited charge estimates. I'll update the documentation soon, but in the meantime I hope the change is self-explanatory and you can make use of it in the Twizy code.</div><div><br><div><div>On 11 Mar, 2013, at 5:57 AM, Tom Saxton <<a href="mailto:tom@idleloop.com">tom@idleloop.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Mark,<br><br>This will be a great feature!<br><br>Cathy and I have logged every charge and drive on all three of our EVs since<br>2008. Our goal with logging is to enable us to use historical data to answer<br>the question: how much charge do I need to drive from point A to B in these<br>conditions? We're also interested in how the performance of each car changes<br>through seasons and over the years. I've even written an iPhone app just for<br>the manual logging we do.<br><br>The data you propose seems good. I have two suggestions:<br><br>1. I think it's more important to track charge depletion than kWh used. If<br>you're driving hard, either high speed or up elevation, you'll get more<br>voltage sag and thus less power per amp-hour than you would with more<br>nominal driving. In these cases, kWh out of the pack understates how much of<br>the pack's charge you used. So, I'd rather know how much the SOC changed on<br>a drive or charge segment, preferably in energy units if available.<br><br> Tesla Roadster: ideal mi|km<br> Tesla Model S: ideal or rated mi|km<br> LEAF: Gids<br><br>On cars that don't have an energy unit SOC measurement, then SOC % would<br>work.<br><br>On drive records, if there's isn't enough room for kWh and change in SOC,<br>I'd prefer change in SOC. I even prefer computing miles per ideal mile (or<br>miles per charge %) to know Wh per mile.<br><br>On charges, the kWh drawn from the wall is useful data, but I'd also like to<br>know how the SOC changed.<br><br>2. On the charge record, what do you mean by current used? Peak current or<br>average current? With tapering near the top of a charge, they can be quite<br>different. I'd suggest peak current. You could even get rid of it if you<br>need the space for something else. You can determine peak power from the<br>available voltage and current (plus knowing the car's limit), and you can<br>calculate average power from energy and duration.<br><br> Tom<br><br>on 3/10/13 7:42 AM, Mark Webb-Johnson wrote:<br><br><blockquote type="cite">I have wanted to implement charging and driving logs, for some time now. The<br>idea is the car will record 'drives' and 'charges' and report them back as<br>historical records. This will be independent of the vehicle module, so should<br>work for all supported vehicles.<br><br>For each drive, we need:<br><br>End time [4 bytes]<br>Duration (seconds) [2 bytes]<br>Drive mode [1 byte]<br>Start location [8 bytes]<br>End location [8 bytes]<br>Distance driven [2 bytes]<br>kWh used [2 bytes]<br><br>For each charge, we need:<br><br>End time [4 bytes]<br>Duration (seconds) [2 bytes]<br>Charge mode [1 byte]<br>Charge location [8 bytes]<br>Current available [1 byte]<br>Current used [1 byte]<br>Voltage [2 bytes]<br>Result (completed, stopped, failed) [1 byte]<br>kWh used [1 byte]<br><br>That is 27 bytes per drive, or 21 bytes per charge.<br><br>The problem is that GPRS connectivity may not be there at the end of the drive<br>or charge, so we need to store these records. RAM would be good, but we only<br>have 429 bytes left (and I think 256 bytes of that may be stack). EEPROM is<br>also possible, but full of parameters at the moment.<br><br>I'm thinking of using the top 4 parameters (#20 through #23) - these appear to<br>be free at the moment, and would give us 128 bytes of permanent storage.<br>Easiest would be 32 bytes for each record.<br><br>This would be turned on with a FEATURE_CARBITS (suggestion: 0x80), so it would<br>default off (for privacy).<br><br>Comments / suggestions?<br><br>Regards, Mark.<br><br>_______________________________________________<br>OvmsDev mailing list<br><a href="mailto:OvmsDev@lists.teslaclub.hk">OvmsDev@lists.teslaclub.hk</a><br>http://lists.teslaclub.hk/mailman/listinfo/ovmsdev<br></blockquote><br><br>_______________________________________________<br>OvmsDev mailing list<br><a href="mailto:OvmsDev@lists.teslaclub.hk">OvmsDev@lists.teslaclub.hk</a><br>http://lists.teslaclub.hk/mailman/listinfo/ovmsdev<br></blockquote></div><br></div></body></html>