Ovms Commands
Ovms Commands
bms
2. can
3. charge
4. climatecontrol
5. config
OVMS stores all it’s configuration in a standardised protected configuration area accessed by
the ‘config’ command. The configurations are organised as follows:
<parameter> <instance> = <value>
For example:
Each parameter can be defined (by the component that owns it) as having readable and/or
writeable attributes, and these act as access control for the parameters.
Beginning with firmware release 3.2.009, a dedicated configuration section usr is provided for
plugins. Take care to prefix all instances introduced by a unique plugin name, so your plugin
can nicely coexist with others.
6. copen
6.1 CANopen
Communication Objects
A CANopen network consists of “masters” and “slaves”, masters are clients, slaves are servers.
At most one master may be active at a time.
CANopen supports addressing of up to 127 slaves on a bus using node IDs 1-127. Node address
0 is used for broadcasts to all nodes. Node addressing is simply mapped onto CAN IDs by
adding the node id to a base ID.
SYNC (synchronisation)
PDO are regular, normally periodical, status update frames, for example sensor data. You can
log them using the CAN monitor ( can log start monitor … ). PDOs can be sent at any CAN ID
except those reserved for other CANopen services.
SDO are memory registers of nodes that can be read and written by masters on request. SDO
requests are normally sent at ID 0x600 + nodeid, responses at ID 0x580 + nodeid. SDOs are
addressed by a 16 bit index + 8 bit subindex. Registers and data types for a given device are
documented by the device specific object dictionary, normally represented as an EDS
(electronic data sheet) file.
NMT are short datagrams to control node startup / shutdown. There’s a special node state
“pre-operational” allowing access to all operation and communication parameters of a node in
a standardized way. NMT requests are sent at ID 0x000, responses and unsolicited updates
(aka heartbeats) are sent at ID 0x700 + nodeid with length 1.
EMCY messages are sent if a node encounters some kind of alert or warning condition, they
are normally sent at ID 0x080 + nodeid with a length of 8 bytes.
Note:
CANopen coexists nicely with OBD-II and often does in a vehicle (i.e. Renault Twizy). OBD-II
devices normally are addressed at IDs > 0x780 so are outside the CANopen ID range. Even if
they use non-standard IDs, the devices normally will detect and ignore frames not matching
their protocol.
SDO Addresses
Index
Object
(hex)
For example, a device shall tell about the PDOs it transmits or listens to, their IDs, update
frequency and content structure at SDO registers 1400-1BFF. This is mandatory in theory but
real devices may not fully comply to that rule.
CANopen compliant standard device types like motor controllers need to implement some
standard profile registers. See CiA DS401 for the generic I/O device class definition and CiA
DS402 for motor controllers.
Most devices will require some kind of login before allowing you to change operational
parameters. This is also done using SDO writes, but there is no standard for this, so you’ll need
to dig into the device documentation.
Of course there’s a lot more on CANopen, but this should get you going.
CAN in Automation
CAN in Automation (CiA) is the international users’ and manufacturers’ group for the CAN
network (Controller Area Network), internationally standardized in the ISO 11898 series. The
nonprofit association was established in 1992. The aim is to provide an unbiased platform for
future developments of the CAN protocol and to promote the image of the CAN technology.
So you’ve got a CAN bus with some devices, but you don’t know which of them speaks
“CANopen”, if any? The OVMS v3 will help you to detect them and open their CANs ;)
… and then start the CANopen master for the bus(es), i.e.:
OVMS# copen can1 start
The “open” in “CANopen” means any implementation can decide how much of the standard it
implements. There are some few mandatory features though, a CANopen slave has to
implement, if it wants to comply with the standard.
The mandatory features helping to detect and identify CANopen nodes on a CAN bus are:
If you’ve got CANopen nodes on a bus, even silent ones, issuing copen … nmt reset will tell
all of them to reboot, and as bootup messages are mandatory, you will see them in the OVMS
log output like this:
I (162904) canopen: can1 node 1 new state: Booting
The OVMS CANopen master continously monitors the network for NMT and EMCY messages.
After bootup of all nodes, you can get a list of all nodes that have been detected by
issuing metrics list co. :
co.can1.nd1.emcy.code
co.can1.nd1.emcy.type
co.can1.nd1.state Operational
Note
if you request a reset, nodes may decide to boot into pre-operational state. That may
produce some error messages. Don’t worry, you can resolve this anytime by
issuing copen … nmt start .
In pre-operational state, a CANopen node must be accessible at the CANopen default IDs. That
means if the node supports SDO access, we can query some standard attributes from it.
Caution
There may be non-CANopen devices on the bus producing regular data frames at CANopen
response IDs and/or reading and possibly misinterpreting CANopen requests sent to node IDs
not planned by the manufacturer. Chances are low this triggers problems, but you should be
ready to switch off the vehicle when doing a scan – just in case.
A complete scan takes about 20 seconds. A typical scan could look like this:
OVMS# level debug canopen
Scan #1-127...
Node #1:
Product: 0x0712302d
Revision: 0x00010019
S/N: 0x47c5…………
HW version: 0x00000003
SW version: 0712.0001
Done.
D (227994) canopen: ReadSDO #23 0x1000.00: InitUpload failed, CANopen error code
0xffffffff
D (228194) canopen: ReadSDO #25 0x1000.00: InitUpload failed, CANopen error code
0xffffffff
D (228444) canopen: ReadSDO #27 0x1000.00: InitUpload failed, CANopen error code
0xffffffff
D (228844) canopen: ReadSDO #30 0x1000.00: InitUpload failed, CANopen error code
0xffffffff
D (238384) canopen: ReadSDO #87 0x1000.00: InitUpload failed, CANopen error code
0xffffffff
This means one CANopen node was found, and some non-CANopen frames were received on
IDs 0x580 +23, +25, +27, +30 and +87.
copen status
id 0 = broadcast
timeout > 0: wait for state change (heartbeat), 3 tries Note: state change response is not
a mandatory CANopen feature.
Read SDO
copen <bus> readsdo <id> <index_hex> <subindex_hex> [timeout_ms=50]
Write SDO
Synchronous API
The synchronous use is very simple, all you need is a CANopenClient instance.
The CANopenClient methods will block until the job is done (or has failed). Job
results and/or error details are returned in the caller provided job.
Caution
Do not make synchronous calls from code that may run in a restricted context,
e.g. within a metric update handler. Avoid using synchronous calls from time
critical code, e.g. a CAN or event handler.
Example
#include "canopen.h"
CANopenClient client(bus);
CANopenJob job;
uint32_t value;
* SendNMT: send NMT request and optionally wait for NMT state change
* Note: NMT responses are not a part of the CANopen NMT protocol, and
* If the node sends no state info, waiting for it will result in timeout
* even though the state has in fact changed -- there's no way to know
*/
/**
*/
/**
* for data types & sizes). As CANopen is little endian as ESP32, we don't
* need to check lengths on numerical results, i.e. anything from int8_t to
*/
uint8_t nodeid, uint16_t index, uint8_t subindex, uint8_t* buf, size_t bufsize,
/**
* - … or 4 bytes from buf if bufsize is 0 (use for integer SDOs of unknown type)
* Note: the caller needs to know data type & size of the SDO register (check
*/
uint8_t nodeid, uint16_t index, uint8_t subindex, uint8_t* buf, size_t bufsize,
If you want to create custom jobs, use the low level method ExecuteJob() to
execute them.
Asynchronous API
Instantiate the async client for a CAN bus and a queue size like this:
void MyAsyncTask()
CANopenJob job;
while (true) {
Sending requests is following the same scheme as with the synchronous API.
Standard result code is COR_WAIT , an error may occur if the queue is full.
// …handle error…
The API methods are similar to the synchronous methods (see above).
CANopenJob objects are created automatically by these methods. Jobs done need
to be fetched by looping ReceiveDone() until it returns COR_ERR_QueueEmpty .
If you want to create custom jobs, use the low level method SubmitJob() to add
them to the worker queue.
Error Handling
COR_OK = 0,
// API level:
COR_ERR_UnknownJobType,
COR_ERR_QueueFull,
COR_ERR_QueueEmpty,
COR_ERR_NoCANWrite,
COR_ERR_ParamRange,
COR_ERR_BufferTooSmall,
// Protocol level:
COR_ERR_Timeout,
COR_ERR_SDO_Access,
COR_ERR_SDO_SegMismatch,
COR_ERR_DeviceOffline = 0x80,
COR_ERR_UnknownDevice,
COR_ERR_LoginFailed,
COR_ERR_StateChangeFailed
To translate a CANopenResult_t and/or a known SDO abort code into a string, use
the CANopen class utility methods:
Example
if (job.result != COR_OK) {
CANopen::GetJobName(job).c_str(),
CANopen::GetResultString(job).c_str());
The standard clients use the CiA DS301 default IDs for node addressing, i.e.:
7. dbc
DBC is a CAN data description file format introduced by Vector Informatik GmbH. DBC files are
text files so can be created and edited using a simple text editor like the one built into the
OVMS web UI.
DBC files can be used to support vehicles that don’t have a dedicated native adaption yet. This
is done using the generic DBC vehicle type, which can use DBC files to translate CAN data into
metrics.
This section tries to show you how to create and use a DBC specification on the OVMS. Of
course you’ll need to know how to decode your vehicle’s CAN frames first. You can use the
OVMS RE (reverse engineering) toolkit to identify which messages are on the bus and which
changes correlate to actions and status on the car.
There’s also a very good general introduction to DBC from CSS Electronics including an
explanatory video: https://www.csselectronics.com/screen/page/can-dbc-file-database-
intro/language/en
DBC files only specify the passive (reading) part, they don’t provide a means to define
transmissions. If you need to send frames to request certain information, you can still use the
OVMS DBC engine to decode the results (instead of doing the decoding in C++ code). So a DBC
file can be used as a base for a real vehicle module. To request OBD2 data during
development, you can use the re obdii commands.
Basic Example
This example is taken from the Twizy, which sends some primary BMS status data at CAN ID
0x155 (341). Note: the Twizy module actually does not use DBC, this is just an example how
you would decode this message if using DBC.
Bytes 1+2: momentary battery current [A], big endian, lower 12 bits, scaled by -0.25, offset
+500: _6 E7 → 58.25A
Bytes 4+5: SOC [%], big endian, scaled by 0.0025, no offset: 6D 58 → 69.98%
BS_ defines the bus speed (500 kbit in this example) and bit timings (unused)
BO_ defines the data object, a CAN frame of length 8 with ID 341 (0x155) (“BMS_1” is just an
arbitrary name)
SG_ lines define the signals (values) embedded in the object (see below)
Vector__XXX is just a placeholder for any sender/receiver (currently unused by the OVMS)
Endianness: 0 = big endian (most significant byte first), 1 = little endian (least significant byte
first) (Note: the DBC format documentation is wrong on this)
Signedness: + = unsigned, - = signed
Scaling and offset: (-0.25,500) => real value = raw value * -0.25 + 500
Minimum/maximum: [-500|1000] = valid real values are in the range -500 to 1000
The metric to set can be given as the name of the signal. You may use the metric name directly
on the OVMS, but to conform to the DBC standard, replace the dots by _ .
Bit positions are counted from byte 0 upwards by their significance, regardless of the
endianness. The first message byte has bits 0…7 with bit 7 being the most significant bit of the
byte. The second byte has bits 8…15 with bit 15 being the MSB, and so on:
[ 7 6 5 4 3 2 1 0 ] [ 15 14 13 12 11 10 9 8 ] [ 23 22 21 20 …
For big endian values, signal start bit positions are given for the most significant bit. For little
endian values, the start position is that of the least significant bit.
Save the DBC example as: /store/dbc/twizy1.dbc (the directory will be created by the editor)
Open the shell. To see debug logs, issue log level debug dbc-
parser and log level debug v-dbc .
Note: the DBC parser currently isn’t graceful on errors, a wrong DBC file may crash the
module. So you should only enable automatic loading of DBC files on boot when you’re done
developing and testing it.
So let’s first try if the DBC engine can parse our file. The dbc autoload command loads all
DBC files from the /store/dbc directory:
The coverage tells us how much of our CAN data bits are covered by signal definitions.
Nice. Let’s simulate receiving our test frame and check the decoded metrics:
OVMS# can can1 rx standard 155 05 96 E7 54 6D 58 00 6F
OVMS# me li v.b.soc
v.b.soc 69.98%
OVMS# me li v.b.current
v.b.current 58.25A
OVMS# me li v.c.climit
v.c.climit 25A
To configure DBC mode for autostart we now just need to set the DBC vehicle mode to be
loaded on vehicle startup, and to enable autoloading of the DBC files from /store/dbc . You
can do so either by using the user interface page Config → Autostart (check “Autoload DBC
files” and set the vehicle type to “DBC”), or from the shell by…
OVMS# config set auto dbc yes
8. disable
9. egpio
Hardware
The OVMS has 10 general purpose I/O ports, provided by a MAX7317 I/O expander.
Depending on your hardware configuration, up to 4 ports may be used by the module. 6 are
generally free to use.
The module including modem needs a 12V current share of ~80mA in full operation. Calculate
with 100mA to be on the safe side. That leaves continuous 0.65A on a revision 3.1 board
and 0.9A on a revision 3.2 board for external devices and addons powered by the module. The
fuse has a little headroom, but don’t rely on that.
SW_12V is meant to power auxiliary devices from the OVMS, for example head-up displays. Of
course you can as well power a standard 12V automotive relay or fan directly from this
without additional hardware.
The EGPIO (EIO) ports are not connected directly to the DA26 connector but are available at
the internal expansion port. To route an EGPIO port to the DA26 connector, connect it to one
of the GEP_1…7 lines at the expansion port, either directly or via some additional driver.
Example: to route EIO_8 (port 9) to GEP_7 (pin 21 on the DA26), set a jumper on pins 10+12 on
the expansion port.
Commands
EGPIO control is provided by the egpio command set:
To configure a port for input, it needs to be switched to output level high (1). That is done
automatically by the input and monitor commands.
If you set multiple outputs, the ports will be set one at a time, so output levels will change with
a slight delay. You can use this behaviour to set data lines before a clock line, e.g. when
sending bits serially into a shift register.
Configuration
The default interval of 50 ms (= 20 Hz) means an input signal needs to be at least 50 ms long to
be detected. This polling frequency produces a CPU load of ~0.5% on core 1 and is normally
sufficient to detect even very short button pushes.
Metrics
Hint: to process these metrics from Javascript, read them into an array using eval() and test
for the presence of a port number using e.g. the includes() method in a browser plugin.
Duktape does not support includes() , you can test indexOf(port) instead.
Example:
var input = eval(OvmsMetrics.AsJSON("m.egpio.input"));
if (input.indexOf(9) < 0)
Events
Hint: to listen to events from Javascript, bind to msg:event on a .receiver object from
browser context or use PubSub from module context.
Example:
PubSub.subscribe("egpio.input.9.low", function(){
});
10. enable
11. event
Internally, OVMS raises events whenever significant events occur. An event is a lightweight
message of a name plus optionally associated internal binary data. Event names are top-down
structured (so can be filtered by prefix) and sufficient to identify the source and type of the
event. Individual vehicle types may also issue their own events, and custom user events are
also possible.
If you want to introduce a custom event (e.g. for a plugin), prefix the event name
by usr.<pluginname>. followed by the event purpose. Example: Foglight
Be aware events are processed in series from a queue, so depending on the system load and
the list of registered event listeners, there may be some delay from event generation to e.g. a
script execution
11.1 Commands
event list [<key>] – Show registered listeners for all or events matching a key (part of the
name)
event trace <on|off> – Enable/disable logging of events at the “info” level. Without
tracing, events are also logged, but at the “debug” level. Ticker events are never logged.
event raise [-d<delay_ms>] <event> – Manually raise an event, optionally with a delay.
You can raise any event you like, but you shouldn’t raise system events without good
knowledge of their effects.
12. exit
13. help
14. homelink
15. location
16. lock
17. log
Logging to the Console
Components of the OVMS system output diagnostic logs (information, warnings, etc). You can
choose to display these logs on your connected console with the ‘log monitor yes/no’
command:
By default, the USB console will have log monitoring ‘yes’, SSH (and telnet if enabled) ‘no’.
The web shell does not use the log monitor command but has a checkbox in the upper right
corner of the shell panel instead. The keyboard shortcut for the checkbox is L (Alt-L or Alt-Shift-
L depending on your browser). The web frontend gets the continuous stream of log messages
independent of the shell panel or the monitoring being active, and shows the last 100
messages received when opening the shell panel.
Logs are output at various levels of verbosity, and you can control what is shown both globally
and on a per-component basis:
OVMS# log level ?
│ │ │ └─ Log message
│ │ └─ Component name
Log levels are applied on log message generation, so a later change to a higher level will not
reveal messages generated previously.
Logging to SD CARD
You can also choose to store logs on SD CARD. This is very useful to capture debugging
information for the developers, as the log will show what happened before a crash or
misbehaviour.
The destination file can be changed any time. To disable logging to the file, issue log close ,
to restart logging after a close issue log open . You may choose an arbitrary file name, good
practice is using some date and/or bug identification tag. Note: logging will append to the file if
it already exists. To remove a file, use vfs rm ….
File logging does not persist over a reboot or crash (unless configured as shown below), you
can use a script bound to the sd.mounted event to re-enable file logging automatically or
configure automatic logging (see below).
You can use the webserver to view and download the files. The webserver default
configuration enables directory listings and access to files located under the document root
directory, which is /sd by default. Any path not bound to an internal webserver function is
served from the document root. So you can get an inventory of your log files now at the URL:
http://192.168.4.1/logs/X
…and access your log files from there or directly by their respective URLs. Another option to
retrieve the files without unmounting the SD card is by scp if you have configured SSH access.
Logging Configuration
Use the web UI or config command to configure your log levels and file setup to be applied
automatically on boot:
file.enable: yes
file.keepdays: 7
file.maxsize: 1024
file.path: /sd/logs/log
file.syncperiod: 3
level: info
level.simcom: info
level.v-twizy: verbose
level.webserver: debug
The log command can be used for temporary changes, if you change the configuration, it will
be applied as a whole, replacing your temporary setup.
If a maximum file size >0 is configured, the file will be closed and archived when the size is
reached. The archive name consists of the log file name with added suffix of the timestamp,
i.e. /sd/logs/log.20180421-140356 . Using a logs directory will keep all your archived logs
accessible at one place. If file.keepdays is defined, older archived logs will automatically be
deleted on a daily base.
Take care not to remove an SD card while logging to it is active (or any running file access). The
log file should still be consistent, as it is synchronized after every write, but the SD file system
currently cannot cope with SD removal with open files. You will need to reboot the module. To
avoid this, always use the “Close” button or the log close command before removing the SD
card.
You don’t need to re-enable logging to an SD path after insertion, the module will watch for
the mount event and automatically start logging to it.
Performance Impact
SD card I/O has an impact on the module performance. So file logging should generally be
switched off or run on a low level (i.e. “info” or “warn”) unless you’re hunting some bug or
checking some details of operation. We also recommend using a fast SD card for logging (check
the speed with sd status , check if you can raise config sdcard maxfreq.khz to 20000 kHz).
File logging is done by a separate task, but flushing the file buffers to the SD card still may
block the logging CPU core or even both CPU cores for a short period. To reduce the impact of
this, the log task by default only flushes the buffer after 1.5 seconds of log inactivity. This
means you may lose the last log messages before a crash.
The log task counts the time spent for flushes and outputs it with the log status command:
Log listeners : 3
Cycle count : 8
Dropped messages : 0
Messages logged : 70721
This is an example for the default configuration of file.syncperiod: 3, the logging here has on
average taken 651.1 / 70721 = 9 ms per message.
18. Metrics
Metrics are at the heart of the OVMS v3 system. They are strongly typed named parameters,
with values in specific units (and able to be automatically converted to other units). For
example, a metric to record the motor temperature may be an integer in Celsius units, and
may be convertible to Fahrenheit.
You can filter the metrics list output for names matching a given substring, for
example metrics list volt will show all voltage related metrics.
A base OVMS v3 system has more than 100 metrics available (see below), and vehicle modules
can add more for their own uses (see vehicle sections).
In general, vehicle modules (and some other system components) are responsible for updating
the metrics, and server connections read those metrics, reformat them, and send them on to
servers and Apps (for eventual display to the user). Status commands (such as STAT) also read
these metrics and display them in user-friendly forms:
OVMS# stat
Not charging
SOC: 50.0%
Ideal range: 200Km
Est. range: 160Km
ODO: 100000.0Km
CAC: 160.0Ah
SOH: 100%
For developer use, there are also some other metric commands used to manually modify a
metric’s value (for testing and simulation purposes), and trace changes:
OVMS# metrics ?
list Show all metrics
persist Show persistent metrics info
set Set the value of a metric
trace METRIC trace framework
Some metrics are presistent across warm reboots. This prevents values such as SOC from being
lost when firmware is updated (or in the event of a crash). You can display these
with metrics list -p and view general information about presistent metrics
with metrics persist.
19. module
20. network
21. notify
Notifications can be simple text messages or transport structured data. To distinguish by their
purpose and origin, notifications have a type and a subtype.
Channels process notifications differently depending on the way they work. For example, a v2
server will forward text notifications as push messages to connected smart phones and email
readers, a v3 server will publish them under an MQTT topic, and the webserver will display the
message as a modal dialog. See the respective manual sections for details.
The standard subtypes used are listed below, these can be used to filter messages. Vehicles
may introduce custom notifications and replace standard notifications, see the respective user
guide section for details.
Subtypes by convention are given in lower case, with dots ‘’.’’ as structural separators.
Channels may have multiple active instances (“readers”), for example you can open multiple
websocket connections. Channels may exclude notification types. Currently stream records
are only supported on a websocket connection, all other types are supported on all channels.
Use notify status to see the currently registered channels (“readers”). Example:
pushover(1): verbosity=1024
ovmsv2(2): verbosity=1024
ovmsweb(3): verbosity=65535
Notify types:
alert: 0 entries
data: 0 entries
error: 0 entries
info: 0 entries
stream: 0 entries
The channel’s “verbosity” defines the supported maximum length of a textual notification
message on that channel. Notification senders should honor this, but not all may do so. If
messages exceed this limit, they may be truncated.
Sending notifications
You can send custom notifications from the shell or command scripts by using
the notify raise command. The command can send the output of another command, an
error code (implies type error ), or any text you enter. For example, to send a custom text
message, do:
OVMS# notify raise text info usr.anton.welcome "Hello, wonderful person!"
In this case, the type would be info and the subtype usr.anton.welcome . The type must
match one of the defined types, the subtype can be chosen arbitrarily. Please use a
unique usr. prefix for custom notifications to avoid collisions.
To send notifications from Duktape scripts, use the API call OvmsNotify.Raise() .
Suppress notifications
You can filter the channels to be used for notifications by their subtypes. By default, no
subtypes are filtered on any channel, so all notifications are sent to all clients.
To disable (suppress) notifications, create a config entry based on the respective subtype, that
lists the channels to include or exclude:
OVMS# config set notify <subtype> <channels>
Standard notifications
The grid history log can be used as a source for long term statistics on your charges and typical
energy usages and to calculate your vehicle energy costs.
Log entries are created on each change of the charge or generator state
( v.c.state / v.g.state ).
You need to enable this log explicitly by configuring a storage time via config
param notify log.grid.storetime (in days) or via the web configuration page. Set to
0/empty to disable the log. Already stored log entries will be kept on the server until expiry or
manual deletion.
Note: the stability of the total energy counters included in this log depends on their source and
persistence on the vehicle and/or module. If they are kept on the module, they may lose their
values on a power outage.
Format: CSV
Fields/columns:
pos_gpslock
pos_latitude
pos_longitude
pos_altitude
pos_location
charge_type
charge_state
charge_substate
charge_mode
charge_climit
charge_limit_range
charge_limit_soc
gen_type
gen_state
gen_substate
gen_mode
gen_climit
gen_limit_range
gen_limit_soc
charge_time
charge_kwh
charge_kwh_grid
charge_kwh_grid_total
gen_time
gen_kwh
gen_kwh_grid
gen_kwh_grid_total
bat_soc
bat_range_est
bat_range_ideal
bat_range_full
bat_voltage
bat_temp
charge_temp
charge_12v_temp
env_temp
env_cabintemp
bat_soh
bat_health
bat_cac
bat_energy_used_total
bat_energy_recd_total
bat_coulomb_used_total
bat_coulomb_recd_total
The trip history log can be used as a source for long term statistics on your trips and typical trip
power usages, as well as your battery performance in different environmental conditions and
degradation over time.
Entries are created at the beginning and end of each “ignition” cycle ( v.e.on change).
Configure a minimum trip length for logging by the config
variable notify log.trip.minlength or via the web UI. If your vehicle does not support
the v.p.trip metric, set the minimum trip length to 0.
The log entry at the beginning of a trip is created to track non-driving SOC changes, vampire
drains and BMS SOC corrections that occurred in between. If you’re just interested in the
actual drive results, filter the records e.g. by pos_trip > 0.1 or env_drivetime > 10 (by
default log entries will be created 3 seconds after the v.e.on state change).
You need to enable this log explicitly by configuring a storage time via config
param notify log.trip.storetime (in days) or via the web configuration page. Set to
0/empty to disable the log. Already stored log entries will be kept on the server until expiry or
manual deletion.
Format: CSV
Fields/columns:
pos_gpslock
pos_latitude
pos_longitude
pos_altitude
pos_location
pos_odometer
pos_trip
env_drivetime
env_drivemode
bat_soc
bat_range_est
bat_range_ideal
bat_range_full
bat_energy_used
bat_energy_recd
bat_coulomb_used
bat_coulomb_recd
bat_soh
bat_health
bat_cac
bat_energy_used_total
bat_energy_recd_total
bat_coulomb_used_total
bat_coulomb_recd_total
env_temp
env_cabintemp
bat_temp
inv_temp
mot_temp
charge_12v_temp
tpms_temp_min
tpms_temp_max
tpms_pressure_min
tpms_pressure_max
tpms_health_min
tpms_health_max
22. obdii
23. ota
Over The Air (OTA) Updates
The remainder for bootloader, generic non-volatile storage, and other data
In general, the factory application firmware is stored in flash at the factory, during module
production. That firmware is never changed on production modules, and is always kept as a
failover backup.
That leaves two firmwares for Over The Air (OTA) updates. If the currently running firmware is
the factory one, an OTA updated firmware can be written to either of the OTA partitions. If the
current running firmware is ota_0, then any new OTA updates will be written to ota_1 (and
similarly if ota_1 is currently running, then new OTA updates will be written to ota_0). In this
way, the currently running firmware is never modified and is always available as a failover
backup.
You can check the status of OTA with the ‘ota status’ command:
If we wanted to boot from ota_1, we can do this with ‘ota boot ota_1’:
If the bootloader fails to boot from the specified OTA firmware, it will failover and boot from
factory.
We can flash firmware to OTA either from a file on VFS (normally /sd), or over the Internet (via
http). Let’s try a simple OTA update over HTTP:
...
Rebooting now (with ‘module reset’) would boot from the new ota_0 partition firmware:
OVMS maintains a record of the reason for each boot, in RAM that survives a reboot. It can
show you how long the module has been running for, and the reason for the last reboot:
OVMS# boot status
If an unexpected (not ‘module reset’) reboot occurs within the first 10 seconds of startup
(usually during the boot-time auto-loading of modules, scripts, etc), the crash counters are
incremented. If those crash counters reach 5 (without a clean reset in between), then the
auto-loading of modules is disabled for the 6th boot.
In case of a crash, the output will also contain additional debug information, i.e.:
Backtrace:
Please include this info when sending a bug report, along with the output of “ota status” and –
if available – any log files capturing the crash event (see Logging to SD CARD). If you can repeat
the crash, please try to capture a log at “log level verbose”.
24. power
25. pushover
26. re
27. script
28. sd
29. server
30. simcom
31. stat
32. store
33. test
34. time
35. tls
36. tpms
37. unlock
38. unvalet
39. valet
40. vehicle
41. vfs
Please take care. This is a very small microcontroller based system with limited storage. The
/store area should only be used for storage of configurations and small scripts. The /sd SD
CARD area is more flexibly and can be used for storing of configuration logs, firmware images,
etc.
Network Access
Network access to the VFS is available via SCP or through the web server.
#copy a new firmware to the sd card on an OVMS named "leaf" in my ssh config
scp leaf:/sd/backup/cfg-2019-12-05.zip .
In the upload example the firmware can then be loaded with the OTA flash vfs command
The web server offers read access rooted at the sd card. An example retrieving
that same config file from the SCP example would look like:
http://leaf-abr.local/backup/cfg-2019-12-05.zip
42. wakwup
43. wifi
WiFi Networking
The OVMS WiFi system is based on the ESP32 integrated WiFi transceiver. It uses and provides
WiFi protocols 802.11 b/g/n and WPA2 authentication. The current hardware can only use 2.4
GHz frequency bands.
The WiFi antenna is built into the ESP32 module (PCB antenna). It’s possible to replace that by
an external antenna, but you’ll need electronics knowledge and SMD soldering skills &
equipment.
The OVMS WiFi network can be configured as a client (connecting to existing WiFi networks)
and/or access point (providing it’s own private WiFi network). Both modes can be run
simultaneously, which is the recommended default. That way, you can always connect to your
module via WiFi.
Power: on
MAC: 30:ae:a4:5f:e7:ec
IP: 192.168.2.102/255.255.255.0
GW: 192.168.2.1
AP: 7c:ff:4d:15:2f:86
AP SSID: DEX106E
MAC: 30:ae:a4:5f:e7:ed
IP: 192.168.4.1
AP Stations: 0
In client mode, the module can connect to a fixed network, or automatically scan all channels
for known networks to connect to (“scanning mode”). Scanning mode is configured by
enabling client mode without a specific client SSID.
The module will normally receive an IP address, gateway and DNS from the WiFi access point
by DHCP. See below on how to connect with a manual static IP setup.
In access point mode, the module provides access for other WiFi devices on a private network
with the IP subnet 192.168.4.0/24 . The module’s IP address on this network is 192.168.4.1 .
The module does not provide a DNS or routing to a public WiFi or GSM network on this subnet.
You can define multiple AP networks, but only one can be active at a time.
Use the wifi mode command to manually set the mode, use the auto start configuration to
configure your default mode and networks.
To manually scan your environment for available WiFi networks, do a wifi scan :
===========================================================================
This can also be done in the web UI’s WiFi client network configuration page by clicking on
the Select button.
After the module lost connection to a network, a scan is performed automatically every 10
seconds until a new connection can be established. If you’d like to see the background scans
and results in the log, enable log level verbose for component esp32wifi.
Scan Troubleshooting
If the module doesn’t find your access point, or can only see it occasionally in the scan results,
you may need to raise your scan times. This has been observed on some older Android
hotspots.
By default, the module will scan each channel for 120 milliseconds. To raise that, set your scan
time in milliseconds using the config command like this, e.g. to 200 milliseconds:
200 milliseconds have been reported to solve the Android hotspot issue. In addition to
the tmin configuration you may need to allow more time looking for further access points
after finding the first one. Do so by setting tmax , e.g.:
Note that every increase will increase the time a full scan takes, so don’t set too high values.
Too high values may result in connection drops on the AP network of the module.
The module monitors the WiFi client signal quality and drops a WiFi connection (switches to
modem if available) if it becomes too bad. The WiFi connection will be kept active and
monitored, and as the signal recovers, the module will automatically reconnect to the AP.
The default threshold is to stop using the connection if it drops below -89 dBm. A connection is
assumed to be usable if the signal is above -87 dBm.
Depending on your WiFi environment, the WiFi connection may still be usable at lower signal
levels.
To tweak the thresholds, use the web UI WiFi configuration or change the following
configuration variables:
In normal operation, the module will try to stick to an established connection as long as
possible. If signal quality drops, it will switch to the modem connection, but monitor the WiFi
signal and reassociate to the current AP if possible.
If using a mesh network, you may want to force scanning for a better mesh AP as soon as the
signal drops below the “bad” threshold. To do so, set the network configuration
wifi.bad.reconnect to true, either using the web UI or by doing:
With this, the module will perform a full WiFi reconnect cycle as soon as the signal becomes
bad.
To configure persistent static details for a known SSID, set these using the following
configuration syntax:
You can also force connection to a specific AP by it’s MAC address, “BSSID” in WiFi terms. To
do so, you need to supply the MAC address as a second argument to the wifi mode client or
as the third argument to the wifi mode apclient command:
This currently needs manual activation by command. Hint: use a script, for example bound to a
location.
AP Bandwidth Configuration
In normal operation, the default AP bandwidth is set to 20Mhz to reduce interference and
improve the signal quality. If a wider 40Mhz bandwidth is preferred, eg for high throughput
logging, set the network configuration wifi.ap.bw with the command:
Once the parameter is set the module will require rebooting to take effect. The default
bandwidth can be restored by either removing the parameter or setting it to 20.