@@ -85,7 +85,8 @@ OvmsVehicleFactory::OvmsVehicleFactory()
85
85
cmd_charge->RegisterCommand (" current" ," Limit charge current" ,vehicle_charge_current," <amps>" ,1 ,1 );
86
86
cmd_charge->RegisterCommand (" cooldown" ," Start a vehicle cooldown" ,vehicle_charge_cooldown);
87
87
88
- MyCommandApp.RegisterCommand (" stat" ," Show vehicle status" ,vehicle_stat);
88
+ OvmsCommand* cmd_stat = MyCommandApp.RegisterCommand (" stat" ," Show vehicle status" ,vehicle_stat);
89
+ cmd_stat->RegisterCommand (" trip" ," Show trip status" ,vehicle_stat_trip);
89
90
90
91
OvmsCommand* cmd_bms = MyCommandApp.RegisterCommand (" bms" ," BMS framework" );
91
92
cmd_bms->RegisterCommand (" status" ," Show BMS status" ,bms_status);
@@ -248,6 +249,16 @@ OvmsVehicle::OvmsVehicle()
248
249
m_last_gentime = 0 ;
249
250
m_last_parktime = 0 ;
250
251
252
+ m_drive_startsoc = StdMetrics.ms_v_bat_soc ->AsFloat ();
253
+ m_drive_startrange = StdMetrics.ms_v_bat_range_est ->AsFloat ();
254
+ m_drive_startaltitude = StdMetrics.ms_v_pos_altitude ->AsFloat ();
255
+ m_drive_speedcnt = 0 ;
256
+ m_drive_speedsum = 0 ;
257
+ m_drive_accelcnt = 0 ;
258
+ m_drive_accelsum = 0 ;
259
+ m_drive_decelcnt = 0 ;
260
+ m_drive_decelsum = 0 ;
261
+
251
262
m_ticker = 0 ;
252
263
m_12v_ticker = 0 ;
253
264
m_chargestate_ticker = 0 ;
@@ -1083,6 +1094,96 @@ OvmsVehicle::vehicle_command_t OvmsVehicle::CommandStat(int verbosity, OvmsWrite
1083
1094
return Success;
1084
1095
}
1085
1096
1097
+ /* *
1098
+ * CommandStatTrip: default implementation of vehicle trip status report
1099
+ */
1100
+ OvmsVehicle::vehicle_command_t OvmsVehicle::CommandStatTrip (int verbosity, OvmsWriter* writer)
1101
+ {
1102
+ metric_unit_t rangeUnit = (MyConfig.GetParamValue (" vehicle" , " units.distance" ) == " M" ) ? Miles : Kilometers;
1103
+ metric_unit_t speedUnit = (rangeUnit == Miles) ? Mph : Kph;
1104
+ metric_unit_t accelUnit = (rangeUnit == Miles) ? MphPS : KphPS;
1105
+ metric_unit_t energyUnit = (rangeUnit == Miles) ? WattHoursPM : WattHoursPK;
1106
+ metric_unit_t altitudeUnit = (rangeUnit == Miles) ? Feet : Meters;
1107
+ const char * rangeUnitLabel = OvmsMetricUnitLabel (rangeUnit);
1108
+ const char * speedUnitLabel = OvmsMetricUnitLabel (speedUnit);
1109
+ const char * accelUnitLabel = OvmsMetricUnitLabel (accelUnit);
1110
+ const char * energyUnitLabel = OvmsMetricUnitLabel (energyUnit);
1111
+ const char * altitudeUnitLabel = OvmsMetricUnitLabel (altitudeUnit);
1112
+
1113
+ float trip_length = StdMetrics.ms_v_pos_trip ->AsFloat (0 , rangeUnit);
1114
+
1115
+ float speed_avg = (m_drive_speedcnt > 0 )
1116
+ ? UnitConvert (Kph, speedUnit, (float )(m_drive_speedsum / m_drive_speedcnt))
1117
+ : 0 ;
1118
+ float accel_avg = (m_drive_accelcnt > 0 )
1119
+ ? UnitConvert (MetersPSS, accelUnit, (float )(m_drive_accelsum / m_drive_accelcnt))
1120
+ : 0 ;
1121
+ float decel_avg = (m_drive_decelcnt > 0 )
1122
+ ? UnitConvert (MetersPSS, accelUnit, (float )(m_drive_decelsum / m_drive_decelcnt))
1123
+ : 0 ;
1124
+
1125
+ float energy_used = StdMetrics.ms_v_bat_energy_used ->AsFloat ();
1126
+ float energy_recd = StdMetrics.ms_v_bat_energy_recd ->AsFloat ();
1127
+ float energy_recd_perc = (energy_used > 0 ) ? energy_recd / energy_used * 100 : 0 ;
1128
+ float wh_per_rangeunit = (trip_length > 0 ) ? (energy_used - energy_recd) * 1000 / trip_length : 0 ;
1129
+
1130
+ float soc = StdMetrics.ms_v_bat_soc ->AsFloat ();
1131
+ float soc_diff = soc - m_drive_startsoc;
1132
+ float range = StdMetrics.ms_v_bat_range_est ->AsFloat ();
1133
+ float range_diff = range - m_drive_startrange;
1134
+ float alt = StdMetrics.ms_v_pos_altitude ->AsFloat ();
1135
+ float alt_diff = UnitConvert (Meters, altitudeUnit, alt - m_drive_startaltitude);
1136
+
1137
+ std::ostringstream buf;
1138
+ buf
1139
+ << " Trip "
1140
+ << std::fixed
1141
+ << std::setprecision (1 )
1142
+ << trip_length << rangeUnitLabel
1143
+ << " Avg "
1144
+ << std::setprecision (0 )
1145
+ << speed_avg << speedUnitLabel
1146
+ << " Alt "
1147
+ << ((alt_diff >= 0 ) ? " +" : " " )
1148
+ << alt_diff << altitudeUnitLabel
1149
+ ;
1150
+ if (wh_per_rangeunit != 0 )
1151
+ {
1152
+ buf
1153
+ << " \n Energy "
1154
+ << wh_per_rangeunit << energyUnitLabel
1155
+ << " , "
1156
+ << energy_recd_perc << " % recd"
1157
+ ;
1158
+ }
1159
+ buf
1160
+ << std::setprecision (1 )
1161
+ << " \n SOC "
1162
+ << ((soc_diff >= 0 ) ? " +" : " " )
1163
+ << soc_diff << " %"
1164
+ << " = "
1165
+ << soc << " %"
1166
+ << " \n Range "
1167
+ << ((range_diff >= 0 ) ? " +" : " " )
1168
+ << range_diff << rangeUnitLabel
1169
+ << " = "
1170
+ << range << rangeUnitLabel
1171
+ ;
1172
+ if (accel_avg > 0 )
1173
+ {
1174
+ buf
1175
+ << " \n Accel +"
1176
+ << accel_avg
1177
+ << " / "
1178
+ << decel_avg << accelUnitLabel
1179
+ ;
1180
+ }
1181
+
1182
+ writer->puts (buf.str ().c_str ());
1183
+
1184
+ return Success;
1185
+ }
1186
+
1086
1187
void OvmsVehicle::VehicleConfigChanged (std::string event, void * data)
1087
1188
{
1088
1189
OvmsConfigParam* param = (OvmsConfigParam*) data;
@@ -1125,6 +1226,15 @@ void OvmsVehicle::MetricModified(OvmsMetric* metric)
1125
1226
{
1126
1227
if (StandardMetrics.ms_v_env_on ->AsBool ())
1127
1228
{
1229
+ m_drive_startsoc = StdMetrics.ms_v_bat_soc ->AsFloat ();
1230
+ m_drive_startrange = StdMetrics.ms_v_bat_range_est ->AsFloat ();
1231
+ m_drive_startaltitude = StdMetrics.ms_v_pos_altitude ->AsFloat ();
1232
+ m_drive_speedcnt = 0 ;
1233
+ m_drive_speedsum = 0 ;
1234
+ m_drive_accelcnt = 0 ;
1235
+ m_drive_accelsum = 0 ;
1236
+ m_drive_decelcnt = 0 ;
1237
+ m_drive_decelsum = 0 ;
1128
1238
MyEvents.SignalEvent (" vehicle.on" ,NULL );
1129
1239
if (m_autonotifications)
1130
1240
{
@@ -1364,10 +1474,35 @@ void OvmsVehicle::MetricModified(OvmsMetric* metric)
1364
1474
if (m_autonotifications)
1365
1475
NotifyGenState ();
1366
1476
}
1477
+ else if (metric == StandardMetrics.ms_v_pos_speed )
1478
+ {
1479
+ // Collect data for trip speed average:
1480
+ const float min_speed = 5.0 ; // slow speed exclusion [kph]
1481
+ float speed = StandardMetrics.ms_v_pos_speed ->AsFloat ();
1482
+ if (speed > min_speed)
1483
+ {
1484
+ m_drive_speedcnt++;
1485
+ m_drive_speedsum += speed;
1486
+ }
1487
+ }
1367
1488
else if (metric == StandardMetrics.ms_v_pos_acceleration )
1368
1489
{
1369
1490
if (m_brakelight_enable)
1370
1491
CheckBrakelight ();
1492
+
1493
+ // Collect data for trip acceleration/deceleration average:
1494
+ const float min_accel = 2.5 / 3.6 ; // cruising range exclusion [m/s²]
1495
+ float accel = StandardMetrics.ms_v_pos_acceleration ->AsFloat ();
1496
+ if (accel > min_accel)
1497
+ {
1498
+ m_drive_accelcnt++;
1499
+ m_drive_accelsum += accel;
1500
+ }
1501
+ else if (accel < -min_accel)
1502
+ {
1503
+ m_drive_decelcnt++;
1504
+ m_drive_decelsum += accel;
1505
+ }
1371
1506
}
1372
1507
else if (metric == StandardMetrics.ms_v_bat_power )
1373
1508
{
@@ -1628,9 +1763,11 @@ void OvmsVehicle::NotifyVehicleOn()
1628
1763
1629
1764
void OvmsVehicle::NotifyVehicleOff ()
1630
1765
{
1631
- float min_trip_length = MyConfig. GetParamValueFloat ( " notify " , " log.trip.minlength " , 0.2 );
1632
- if (StdMetrics. ms_v_pos_trip -> AsFloat () >= min_trip_length )
1766
+ float trip = StdMetrics. ms_v_pos_trip -> AsFloat ( );
1767
+ if (trip >= MyConfig. GetParamValueFloat ( " notify " , " log.trip.minlength " , 0.2 ) )
1633
1768
NotifyTripLog ();
1769
+ if (trip >= MyConfig.GetParamValueFloat (" notify" , " report.trip.minlength" , 0.2 ))
1770
+ NotifyTripReport ();
1634
1771
NotifiedVehicleOff ();
1635
1772
}
1636
1773
@@ -1719,6 +1856,19 @@ void OvmsVehicle::NotifyTripLog()
1719
1856
MyNotify.NotifyString (" data" , " log.trip" , buf.str ().c_str ());
1720
1857
}
1721
1858
1859
+ void OvmsVehicle::NotifyTripReport ()
1860
+ {
1861
+ // Send trip report notification
1862
+ // Notification type "info", subtype "drive.trip.report"
1863
+ bool send_report = MyConfig.GetParamValueBool (" notify" , " report.trip.enable" , false );
1864
+ if (send_report)
1865
+ {
1866
+ StringWriter buf (200 );
1867
+ CommandStatTrip (COMMAND_RESULT_NORMAL, &buf);
1868
+ MyNotify.NotifyString (" info" , " drive.trip.report" , buf.c_str ());
1869
+ }
1870
+ }
1871
+
1722
1872
OvmsVehicle::vehicle_mode_t OvmsVehicle::VehicleModeKey (const std::string code)
1723
1873
{
1724
1874
vehicle_mode_t key;
0 commit comments