Syruslang
Language to quickly interface with the device and generate events/messages to your server
Intro
Syrus IoT Telematics Gateway can be programmed with a proprietary language called Syruslang.
With Syruslang you can create custom definitions to quickly interface with the device and its internal components (network, inputs/outputs, accelerometer, gnss, etc) in order to customize the Syrus' reporting behavior.
The custom definitions are part of a Smart Event Engine which constantly evaluate conditions.
For example configurations checkout our Github Repo.
Quick 5 minute introduction presentation that goes over the main points of this documentation.
What is SyrusJS?
Syruslang runs on an embedded application inside the Syrus 4 called SyrusJS which manages a syruslang configuration file and all of its definitions.
Within SyrusJS there's a directory that holds the device's configuration and important files, the location of this directory is also referred to as the application data directory: /data/app_data/<INSTANCE_NAME>/
.
The important files to consider within this directory are:
Filename | Description |
---|---|
appends.syrus.conf | Any remote command sent to the device (automatically generated). |
configuration.syrus.conf | Device's main configuration file. |
destinations.syrus.conf | Device's destination definitions. |
Comments within any of the filenames above can be written with #
in front of the line with the comment.
# comment
define command
# >[email protected]#% this is another comment
The Syrus Cloud Applications can be used to manage the files within SyrusJS and create your own script.
Configuration access
Via shell you can edit the configuration using an editor like vi
or tail logs.
- Logs directory:
/data/logs
- Application data:
/data/app_data/<INSTANCE_NAME>
Please note that the logs file rotates every hour and if the size is greater than 30KB then it will be compressed. Maximum of 8 log files are created.
The system tool syrus-apps-manager
can be used to interact with the application itself (start, stop, restart).
Just make sure after you update the configuration to restart the application.
syrus-apps-manager restart syrusjs
Definitions
There are 3 main definitions that control what we call the Smart Event Engine of the device.
- Signals
- Actions
- Events
With these 3 definitions you can create thresholds, and trigger messages to be sent to a destination, or actions to be executed locally on the device.
It all starts by creating the definitions.
Units
Unless otherwise specified, Syruslang will follow the basic units of the metric system for time, distance, and speed (seconds, meters, and km/h, respectively).
Create
In order to create a definition you have to start a new line with define
followed by the name of the definition you want to create:
define *definition* custom_name
As you create the definitions you assign a unique custom_name to each one. Be aware that the naming must follow these rules:
- are case-sensitive
- 3 to 25 characters
- cannot start with a number
- only underscore is allowed as a special character
_
- cannot be special keywords like:
and
,or
,not
,exec
,apx
,group
[a-zA-Z_][a-zA-Z0-9_]{2,24}
There is no limit as to how many definitions you can create, but keep in mind that no two definitions can share the same custom_name.
:::warning ⚠️
Using the same definition and custom_name
will overwrite the original definition.
❌ define signal my_signal ... <- original
✅ define signal my_signal ... <- this will overwrite the original
Using a different definition with the same custom_name
is not good practice.
✅ define signal custom1
❌ define event custom1
:::
:::tip 💡
Definitions can also span multiple lines
✅ define signal
my_signal ...
more ...
✅ define event
custom1 ...
:::
Evaluation
The event engine is evaluated in the order mentioned above, first with signals, then the actions and finally the events.
This is important because you may have a signal that fires an action that triggers an event, and you need to keep in mind which one is going to trigger first.
Manipulation
Definitions can be deleted with the delete
keyword, followed by the definition and its name:
delete *definition* custom_name
:::warning ⚠️
Deleting a definition has a cascade effect in terms of what's associated to that definition, thus you have to consider what actions and events are associated to each definition.
:::
Event Engine
The unit's reporting is controlled by an Event Engine which constantly evaluates user definitions.
The 3 main definitions are signals, actions, and events.
- Signals: used to evaluate when you want something to happen (i.e. when the input is pressed, or when the speed is above a certain value)
- Actions: used to fire a specific task once a signal is met (i.e. activate an output or make a call)
- Events: used to notify an endpoint once a signal is met (i.e. generate a message to send to the server to indicate that the panic was pressed)
Signals
The main component of Syruslang is the definition of signals.
There are two types of signals:
- fixed signals - built-in device signals, start with
@
symbol - custom signals - custom created signals that require an operator and value
To create a signal you have to use the following format (values with []
mean they're optional):
define signal signal_name [min_duration] $device_component [operator] [value]
or
define signal signal_name
[min_duration] $device_component [operator] [value]
Once defined, a signal can be used to trigger actions, events, or both.
Keep in mind that the signals you create evaluate when the conditions change, in other words, once a signal is defined and its condition becomes true, the signal will not reevaluate or trigger again until it changes from false to true again.
So if you have an action or event that depends on a signal that stays true, it will only evaluate 1 time until the signal changes from false to true again.
Signal definition example:
define signal ignitionIsOn min_duration=10sec $io.ign == true
The default operator and value are ==
and true
so the signal definition above can also be rewritten to:
define signal ignitionIsOn
min_duration=10sec $io.ign
Breakdown of the signal definition:
min_duration
The minimum duration that the condition (made up of the $device_component
, operator
, and value
) must be met in order for the signal to transition to true. It has the following format, #A
where #
is any number and A
represents the time unit:
sec
- secondsmin
- minuteshr
- hours
a min_duration=10sec
for example, means that the condition must be met for 10 consecutive seconds, before the signal transitions to true.
$device_component
Device components refer to the internal modules and interfaces that the device is capable of interacting with. The device components section has a list of the available signals that can be constructed with each internal module/interface.
$gnss.speed
$net_wifi.ip_address
$net_cell.connected
$accelerometer.motion
operators
The operators supported are:
== > < >= <= !=
value
The value varies depending on the field selected, can be bool, string, or a number.
Example of Signal Definitions
define signal ignitionON min_duration=5sec $io.ign
define signal ignitionOFF min_duration=5sec $io.ign == false
define signal speeding min_duration=2sec $gnss.mph > 70
define signal parked min_duration=10sec $accelerometer.motion == false
define signal buzzer $io.out2
define signal siren $io.out3
define signal usa_country_code $net_cell.mcc == 310
define signal att_network_code $net_cell.mnc == 410
define signal slow
min_duration=10sec $gnss.kph < 10
define signal work_wifi
$net_wifi.ip_address == 123.123.123.123
Trigger (Signal Combination)
Various signals can be combined to form a combination of several situations that can trigger an event or an action.
The parameter trigger
is used to create an equation using signals and logical operators: and, or, not, in a post fixed notation syntax.
Post-fixed notation means that the signals are placed first, and the operator is at the end of the signals to be evaluated, the signals and the operators are separated by a comma.
Examples
A or B → A,B,or
A and B → A,B,and
A and B and C → A,B,and,C,and
same as..
A and B and C → A,B,C,and,and
(A and B) or C → A,B,and,C,or
A and (!B or C) → A,B,not,C,or,and
(A and B) or (C and D) → A,B,and,C,D,and,or
thus you can combine the signals defined previously like this:
# idling
ignitionON,parked,and
# attached to AT&T in US
usa_country_code,att_network_code,and
# not moving
ignitionON,parked,slow,or,and,ignitionOFF,or
# parked at the office
ignitionOFF,work_wifi,and
As mentioned above, the signals can be combined in actions and events.
Keep in mind that when you define a trigger for the first time, if all the signals within the trigger are true, the trigger will evaluate and fire.
Next we will look at how to define an action.
Actions
Actions can be defined to tell the device what to do when a trigger goes off. They have the following format:
define action action_name [rate] trigger=signal1[,signal2,operator,...] command
:::tip 💡
Multiple actions can be fired from a single trigger by separating each action with a new line and tab
define action action_name trigger=signal1[,signal2,operator,...]
command1
command2
define action ac_my_action trigger=signal1
set out1 on
set out2 on
start recording
:::
rate
Similar to the rates of an event, actions can have their own rates in order to avoid executing excess number of actions.
The format for rates is A/Bunit
where A
is the amount of fires to allow, and Bunit
is the time frame to allow it for. The possible units are sec
, min
, hr
.
For example a rate of 1/2hr
allows only 1 fire every 2 hours. After the 2 hours complete the rate is reset back to 0 and the unit can fire once more in the span of 2 hours.
:::tip 💡
This is very useful for actions that have to do with voice alerts, as these can get annoying really quick, unless of course that's your goal
:::
command
The command that can be executed can be found in the device components section, as action
use
Action definition example:
define action speedingBuzzer trigger=speeding set out2 on
:::tip 💡
You can substitute == true
and == false
for the words on
& off
respectively
define action enable_hotspot trigger=work_wifi,ignitionOFF,and set out2 on
:::
:::tip 💡
You can execute any system tool command with the exec
keyword.
The command can be a standalone line with the instruction:
exec apx-ethernet off
or part of an action
define action my_action trigger=no_gps exec apx-gps cold-start
:::
Events
Events can be triggered by the same signals as an action and they can be used to notify an endpoint when a condition is met.
When an event is triggered it follows this sequence of steps:
- Creates a message according to the protocol on the events destination definition
- Appends any additional fields to the payload via the fieldsets
- Queues the payload on a data buffer (FIFO) per endpoint defined
- Attempts to communicate with the endpoints in order to remove the payload from its queue
- Depending on the Acknowldgement configured it either waits for a confirmation from the endpoint or moves on to the next event in queue.
- If no response from the endpoint is received the messages are retried in increasing timeouts, after 5sec, 10sec, 30sec, 60sec, etc. til it reaches 1min and keeps retrying every 1min.
The event definition format is as follow:
define event event_name group [fieldset] [rate] [ack] [label] [code] [photo] trigger=signal1[,signal2,and,...]
param | description | default value |
---|---|---|
group | is a way to group several events for destination handling | default |
fieldset | refers to the additional information that can be attached to an event besides the location information, we'll look at this in more detail later | |
rate | refers to a firing limit for this event | |
ack | refers to the acknowledgement message that's used by an endpoint to handle the correct reception of the event, for mqtt endpoints this is the equivalent of QoS | seq |
retain | set to false to disable the retain message flag for mqtt destinations | true |
label | refers to a short string, up to 10 characters (alphanumeric, period [.] accepted), that's used to identify the event generated on an endpoint using syrus3g protocol | trckpnt |
code | is a numeric code for the event generated (range: 0, 9999), useful for syrus3g protocol messages | 0 |
photo | whether the event will have a photo associated to it | false |
video | variable with a video id attached to ithe event | |
trigger | are the signals that we defined earlier that can be combined with logical operators. |
Event definition examples:
define event movement group=default fieldset=minimum rate=5/1min ack=disabled label=trckpnt code=1 trigger=moving
define event ignition_on group=tracking fieldset=default ack=seq label=ignon code=2 trigger=ignitionON
define event speeding_70 group=alerts fieldset=important ack=seq label=spd code=3 trigger=speeding
define event parked group=default fieldset=minimum rate=2/1hr ack=disabled label=park code=4 trigger=isON,slow,and,nomov,and
Event Grouping (group)
Groups can be defined in order to get multiple events reporting to the same destination.
The first step is to define a group:
define group group_name
Once defined you can append this group_name
to any event and later on apply fieldsets or destinations to that group of events.
To relate the group to a destination use the following command:
set destinations group=group_name destination_name1[,destination_name2]
Example, if we have the following events defined:
define event ignition_is_on group=important ack=seq label=ignon trigger=ignitionON
define event ignition_is_off group=important ack=seq label=ignoff trigger=ignitionOFF
define event panic_and_parked group=important ack=seq label=panic trigger=panic,parked,and
define event speeding_70 group=important ack=seq label=spd trigger=speeding
the first 3 events we can direct towards the main_server and the backup server with:
set destinations group=important main_server,backup
the 4th event falls in the default group so those can be directed to just the main_server for example:
set destinations group=default main_server
Thus, the destination file will depend on the groups of events defined in your configuration.syrus.conf
.
Note, if an event has no destination set it will simply be discarded.
Fieldset
Fieldsets are data fields that can be appended to the payload of an event.
Start by defining a fieldset
# fieldset definition my_fields
define fieldset my_fields fields=field1,field2,etc..
Then you can use it on any event
# appends my_fields to my_event
define event my_event fieldset=my_fields ...
The fields come from the device components section, look for fieldset
use.
To define or transform fieldset values & sets:
VALUES
fields=$battery.voltage
{
"$battery": {
"voltage": 4.1
}
}
fields="foo":$battery.voltage or fields=foo:$battery.voltage
{
"foo": 4.095
}
fields=foo.bar:$battery.voltage
{
"foo": {
"bar": 4.098
}
}
SETS
fields=$battery
{
"$battery": {
"connected": true,
"voltage": 4.098,
"mv": 4098,
"level": 100
}
}
fields="foo":$battery
{
"foo.connected": true,
"foo.voltage": 4.098,
"foo.mv": 4098,
"foo.level": 100
}
fields=bar:$battery
{
"bar": {
"connected": true,
"voltage": 4.098,
"mv": 4098,
"level": 100
}
}
fields=foo.bar:$battery
{
"foo": {
"bar": {
"connected": true,
"voltage": 4.098,
"mv": 4098,
"level": 100
}
}
}
Example:
fields=position.context.lat:$gnss.latitude,position.context.lng:$gnss.longitude,position.value:$gnss.fix
{
"position": {
"context": {
"lat": 25.783618,
"lng": -80.293516
}
},
"value": 3
}
For TAIP protocol, you just need to define a csv of all the compatible sets from device components.
Example:
define fieldset taip_pegasus fields=$gnss,$io,$net_cell,$ecu,$accelerometer
SyrusJS will automatically fill those fields with the appropriate subfields for TAIP messages.
One fieldset per destination
Make sure to define one fieldset per destination you create.
# group definitions define group tracking define group bluetooth # fieldset definitions define fieldset default fields=$gnss,$io define fieldset btdata fields=$ecu,$net_eth # event definitions define event braking group=tracking ack=seq fieldset=default [email protected]_braking.signal define event movement group=bluetooth ack=seq fieldset=btdata [email protected] # groups destinations set destinations group=tracking destination_peg1 set destinations group=bluetooth bt_event_destination
# multiple destinations define destination destination_peg1 taip tcp://pegasus1.peginstances.com:5001 define destination bt_event_destination json bluetooth://_:_ ack=disabled
Rate
The rates are used to avoid firing an event in excess by limiting the amount of fires an event can have within a period of time.
The format for rates is A/Bunit
where A
is the amount of fires to allow, and Bunit
is the time frame to allow it for. The possible units are sec
, min
, hr
.
For example a rate of 5/1min
allows only 5 fires of the event in the span of 1 minute. After the minute completes the rates are reset to 0 and the unit can fire 5 times again in the span of 1 min.
💡Tip: This is very useful for events that have to do with physical connections like inputs, analog values, ignition, because these are proned to installation failures which can lead to multiple false fires
Label
Labels are important for TAIP protocol, when sending the data to Pegasus for example. They are used to identify an event. Labels must follow these guidelines:
- 1 to 10 characters
- letters can only be lowercased
- only period
.
is allowed as a special character - cannot have consecutive periods
[a-z0-9.]{1,10}
- can have the same name as a definition
Photo
The photo parameter is used to associate a photo to an event. When a compatible accessory is connected, like a fatigue_sensor, you can associate any photo captured or a specific photo captured with this.
Destinations
Destinations are the the endpoints where the data generated by the device will be reported, they are saved in a separate file called: destinations.syrus.conf
within the app directory /data/app_data/syrusjs/
To define a destination:
define destination name protocol transport:endpoint[?args] [allowed_] [ack] [disabled]
name
Name is the custom name given to the destination, can be up to 50 alphanumeric characters.
protocol
The protocol refers to the data format that the payload is transmitted in:
json
taip
(Syrus 3 format used for Pegasus platform)csv
used for file type destinations
transport
Transport refers to the method of transportation of the data, the following methods are supported:
mqtt
tcp
http
/https
file
satcom
bluetooth
MQTT Protocol Support on Syruslang
MQTT 3.1.1 | MQTT 5.0 | SSL/TLS | TCP | WS/WSS | QoS |
---|---|---|---|---|---|
Yes | Yes | Yes | Yes | Yes | 0,1,2 |
endpoint
The endpoint refers to the destination of the data, it can be various formats depending on the transport, for now given the transports defined earlier, the following are supported:
mqtt, tcp, http[s]:
://url[:port]
://ip_address[:port]
file
:///path/to/file.log
satcom
://_:_
bluetooth
://_:_
- endpoint for S4GBT Destination Point (used for broadcasting)
://apps:_
- endpoint for S4GBT User Application Console (allows acknowledgement of messages)
Note that you can use variables in the endpoint from the components section by adding it inside two curly brackets {{}}
:
Examples:
://url.com/syrus/{{$modem.imei}}
Protocol, Transport, Endpoint Support Matrix
The following table shows a relationship between the supported protocols for each transport method and their destination
transport | supported protocol(s) | endpoint |
---|---|---|
mqtt | json , taip | mqtt://test.mosquitto.org:1883 |
tcp | taip | tcp://iot.yoursite.com:1234 |
http /http | json , taip | <https://yoursite.com/device/listener > |
file | json , taip , csv | file:///media/mmcblk0p1/logs.csv |
satcom | taip | satcom://_:_ |
bluetooth | json | bluetooth://_:_ |
bluetooth | taip | bluetooth://apps:_ |
?args
The optional ?args
refers to params that can be appended to the endpoint.
?ssid=value&pass=pass1
allowed_
The connection to this destination will only be available when the specified network is within range/connectable. Outside of the allowed interfaces the destination will queue all messages until it's available again.
value | description |
---|---|
allowed_ssid | when connected to a specific wireless network ssid |
allowed_ip | when connected to a specific ip_address |
allowed_interface | when connected to one or many of these network interfaces wifi , eth , cell |
Example:
# This connection will only allow messages sent via wifi inteface once it's connected/in range. Any other interface that's used will queue the messages.
define destination mqtt_broker json mqtt://test.mosquitto.org:1883 protocol="mqtt" subscribe="dev/messagestx" publish="dev/messagestx" allowed_interface=wifi
# This example will only send messages when it's connected via ethernet, cellular network or a specific ssid
define destination server json tcp://test.server.com allowed_interface="eth,cell" ssid="Linksys Home Router"
ack
Configure the message acknowledgement to be used by a destination:
transport | ack supported | details |
---|---|---|
mqtt | ✅ | ack supported using QoS |
tcp | ✅ | ack supported via taip protocol |
http | 🚫 | no ack support |
https | 🚫 | no ack support |
file | 🚫 | no ack support |
satcom | 🚫 | no ack support |
bluetooth | ✅ | seq/imei ack supported via bluetooth://apps:_ destination endpoint |
See the Message Acknowledgement and Queues section for more information on the specific ack configurations.
disabled
Disables the endpoint, this is useful if you want to control it via an action, for Satcom/Sigfox destinations for example.
define destination satcom_destination taip satcom://_:_ ack=disabled disabled=true
The commands to enable and disable the destination are:
enable destination name
or
disable destination name
and some sample actions:
define action enable_satcom trigger=disconnected enable destination satcom_destination
define action disable_satcom trigger=disconnected,not disable destination satcom_destination
Useful for the satcom destination
MQTT
MQTT can be used as a destination transport method, for a full tutorial that incorporates mqtt checkout this walkthrough.
The following parameters are available when creating a destination definition for an MQTT endpoint:
param | description | example |
---|---|---|
clean | indicate whether or not a persistent session is required (set to false to keep a persistent session) | false |
clientId | client identifier | "client-1" |
keepalive | keep alive period to maintain a connection open with broker | 60 |
lastWillPayload | message to send when client disconnects ungracefully | "unexpected exit" |
lastWillQoS | last will quality of service | 1 |
lastWillRetain | whether or not to retain the last will message | true |
lastWillTopic | last will topic | "dev/imei/connect/status" |
username | username for client authentication | "user" |
password | password for client authentication | "pass" |
protocol | used to define the transport method and security, see below for protocol list | "mqtts" |
publish | topic to publish event messages | "dev/imei/events" |
commands_pub | topic to publish command responses | "dev/imei/commands/resp" |
subscribe or commands_sub | topic that handles syruslang commands | "dev/imei/commands" |
Note that only one topic to publish event messages can be set per definition, but you can have multiple definitions with different topics.
Other parameters like the QoS
& retain
of each message are handled in the events definition.
method | port | protocol | secure |
---|---|---|---|
mqtt over tcp | 1883 | mqtt | no |
mqtt over tls | 8883 | mqtts | yes |
mqtt websockets | 80 | ws | no |
mqtt websockets over tls | 443 | wss | yes |
Example MQTT endpoints
define destination mqtt_over_tcp json mqtt://mqtt.pegasusgateway.com:1883 protocol="mqtt" publish="dev/{{$modem.imei}}/pub" subscribe="dev/{{$modem.imei}}/sub" commands_pub="dev/{{$modem.imei}}/commands"
define destination mqtt_over_tcp_ssl json mqtt://mqtt.pegasusgateway.com:8883 protocol="mqtts" publish="dev/{{$modem.imei}}/pub" subscribe="dev/{{$modem.imei}}/sub" commands_pub="dev/{{$modem.imei}}/commands"
define destination mqtt_over_ws json mqtt://mqtt.pegasusgateway.com:80 protocol="ws" publish="dev/{{$modem.imei}}/pub" subscribe="dev/{{$modem.imei}}/sub" commands_pub="dev/{{$modem.imei}}/commands"
define destination mqtt_over_wss json mqtt://mqtt.pegasusgateway.com:443 protocol="wss" publish="dev/{{$modem.imei}}/pub" subscribe="dev/{{$modem.imei}}/sub" commands_pub="dev/{{$modem.imei}}/commands"
HTTP(S)
When creating an http endpoint you can use the following notation to append headers: headers.HEADER_NAME=VALUE
# endpoint with application/json content-type
define destination my_endpoint json http://api.mysite.com/devices headers.content-type="application/json"
# endpoint with authorization and content-type
define destination other_endpoint json https://api.mysite.io/devices headers.authorization="Bearer XXXXXXXXX" headers.content-type="application/json"
Message acknowledgement and queues
Once an event is generated the device stores it in a queue per endpoint that the event is sent to.
Any event in queue is transmitted to the endpoint every second as long as a connection is established.
If the endpoint requires internet connection, there's 3 possibilities to reach it:
- Ethernet
- Wi-Fi
- Cellular (4G/LTE)
The data traffic by default is sent in that order of priority, with Ethernet being the preferred method.
By default SyrusJS uses the TCP stack to guarantee message delivery, however under special circumstances it's recommended to implement an application level ACK, this is where the ack
param comes in.
The ack
param of the event verifies if Syrus is expecting any sort of response from the endpoint indicating that it received the event.
protocol & transport | ack | format of ACK Syrus expects | example |
---|---|---|---|
taip over tcp | disabled | none | |
taip over tcp | imei | 15 digit modem's IMEI | 867698040023056 |
taip over tcp | seq | >SAK;1,# ,0,0< where # is the sequential number generated by Syrus | >SAK;1,1234,0,0 |
for MQTT the ack
controls the QoS
and retain
flags of the MQTT specification
protocol & transport | ack | QoS | retain |
---|---|---|---|
json over mqtt | disabled | 0 | false |
json over mqtt | seq | 2 | true |
Maximum queue size
SyrusJS uses Redis and the device's filesystem to store event messages that have not been transmitted to an endpoint.
The maximum number of possible messages stored is equivalent to the amount of memory available in the user's storage partition, this partition is roughly 2.2GB and can be monitored in the Syrus 4 UI system page, divided by the size of the messages. Typical message sizes for TAIP can vary between 50 bytes to 500 bytes depending on the accessory, while MQTT can vary from a few bytes up to 5KB.
Clearing destination queues with TAIP ack
To clear a taip destination queue you can send the command >SRT;SFBUFF<
using the send-message command.
$ syrus-apps-manager send-message __cloud_syrusjs '>SRT;SFBUFF<'
HTTP Errors
In the output/error logs you may get a message:
ECONNABORTED
. This is a disconnection message that means that the Syrus abruptly cut the communication with the remote server. It could be due to several reasons, for example:
- Exceeded maximum timeout
- Network congestion / loss of coverage
Logging to a file
A destination can also be a path to a file, this can be used to log data in any of the protocols defined above. By default, file destinations use the log rotation tool to automatically rotate the file that's being logged according by size and/or amount of days.
The format to create the file destination is:
define destination NAME PROTOCOL file:///PATH ACK ROTATE SIZE COMPRESS
The possible parameters to configure when defining a file destination are:
param | description |
---|---|
NAME | Name of the destination |
PROTOCOL | json , taip , or csv protocols |
PATH | path to where the logs will be saved; specify the name of the file with an optional extension name, also note that this can be a path on the local file system or an external SD card that's mounted on the Syrus. Be sure to format the SD card before using it to log data |
ACK | leave as disabled for file type destinations |
ROTATE | rotation duration, format NT - where N is a number, and T is a duration (D - days, W - weeks, M - months) |
SIZE | max file size before the file is rotated (optional) |
COMPRESS | set to true to enable compression of the files once they are rotated (optional) |
*Note: if the file destination does not exist a new one is created, but if the file does exist already it will be overwritten!*
Example destination definition:
define destination logger csv file:///data/app_data/syrusjs/output.csv ack=disabled rotate=5D size=10MB compress=true
Once the log starts you can use a command like zip
to download the file to make sure it's capturing the correct data.
# zip the output file into the /data/logs folder
# format: zip DESTINATION_PATH SOURCE_FILE
$ zip /data/logs/output.zip /data/logs/output.csv
# then download the file using Syrus Cloud
download-file /data/logs/output.zip
For more information on the signals and fieldsets possible when logging data check out the blackbox section.
Remote interaction
Depending on the protocol and transport of the destination you defined, you can interact with the device remotely.
If you are using JSON over MQTT you can publish commands to a topic from your remote message broker on your destination definition.
By default SyrusJS will be connected to the topic defined by the params subscribe
or commands_sub
using QoS
= 1.
Once a message (command) is received SyrusJS will publish to the topic commands_pub
using QoS
= 1 and retain
= true.
Thus, to send commands remotely to the Syrus over MQTT you can publish messages to the commands_sub
topic.
You can send an action, define something, or retrieve data remotely.
# activate output 2
set out2 on
OK
# define a new definition
define signal signal_name ...
OK
# get a list of all signals
get signals
define signal ignOn $io.ign == true, define signal isIdle ...
:::tip 💡
Note that any definition that you configure remotely to the device will be appended to a file called appends.syrus.conf
on the application's data folder
:::
Commands to retrieve data, definitions, or values
definitions | description |
---|---|
get action custom_name | returns action definition of custom_name |
get actions | returns all action definitions |
get counter custom_name | returns counter definition of custom_name |
get counters | returns all counters definitions |
get destinationstate _custom_name | returns enable if destination is used |
get destination custom_name | returns destination definition of custom_name |
get destinations | returns all destinations definitions |
get event custom_name | returns event definition of custom_name |
get events | returns all events definitions |
get fieldset custom_name | returns fieldset definition of custom_name |
get fieldsets | returns all fieldsets definitions |
get geofence custom_name | returns geofence definition of custom_name |
get geofences | returns all geofences definitions |
get group custom_name | returns group definition of custom_name |
get groups | returns all groups definitions |
get signal custom_name | returns signal definition of custom_name |
get signals | returns all signals definitions |
get signalvalue _signal_name | returns the value of the signal |
get value $device.component | returns the value of the device component |
Note that if you're using the TAIP protocol, you'll need to encapsulate the message within the SL (SyrusLang) command: >SSLmessage<
, the response will have the following format: >RSLresponse<
Examples:
# Get fieldset definition
>SSLget fieldset default<
>RSLdefine fieldset default fields="device_id":$modem.imei,"latitude":$gnss.latitude,"longitude":$gnss.longitude,"direction":$gnss.heading,"hdop":$gnss.hdop,"pdop":$gnss.pdop,"vdop":$gnss.vdop,"mph":$gnss.mph,"io_in1":$io.in1,"io_in2":$io.in2,"io_in3":$io.in3,"io_out1":$io.out1,"io_out2":$io.out2,"io_ign":$io.ign,"io_pwr":$io.pwr<
# Get signal value
>SSLget value $net_wifi.ip_address<
>RSL192.168.1.205<
# Action enable hotspot
>SSLenable hotspot<
>RSLOK<
Signals, Actions, and Fieldsets
accelerometer
Accelerometer related information
property | use | type | description |
---|---|---|---|
$accelerometer | fieldset | Object | json appends all accelerometer fields |
$accelerometer | fieldset | String | taip compatible field |
@accelerometer.backward_collision.signal | signal | Boolean | True when detected |
@accelerometer.cornering_left.signal | signal | Boolean | True when detected |
@accelerometer.cornering_right.signal | signal | Boolean | True when detected |
@accelerometer.forward_collision.signal | signal | Boolean | True when detected |
@accelerometer.hard_braking.signal | signal | Boolean | True when detected |
@accelerometer.harsh_fwd_acceleration.signal | signal | Boolean | True when detected |
@accelerometer.lat_collision_from_left.signal | signal | Boolean | True when detected |
@accelerometer.lat_collision_from_right.signal | signal | Boolean | True when detected |
@accelerometer.motion.signal | signal | Boolean | True when detected |
$accelerometer.backward_collision.time | fieldset | String | Time of event |
$accelerometer.backward_collision.value | fieldset, signal | Number | Acceleration force in milli-g |
$accelerometer.cornering_left.time | fieldset | String | Time of event |
$accelerometer.cornering_left.value | fieldset, signal | Number | Acceleration force in milli-g |
$accelerometer.cornering_right.time | fieldset | String | Time of event |
$accelerometer.cornering_right.value | fieldset, signal | Number | Acceleration force in milli-g |
$accelerometer.forward_collision.time | fieldset | String | Time of event |
$accelerometer.forward_collision.value | fieldset, signal | Number | Acceleration force in milli-g |
$accelerometer.hard_braking.time | fieldset | String | Time of event |
$accelerometer.hard_braking.value | fieldset, signal | Number | Acceleration force in milli-g |
$accelerometer.harsh_fwd_acceleration.time | fieldset | String | Time of event |
$accelerometer.harsh_fwd_acceleration.value | fieldset, signal | Number | Acceleration force in milli-g |
$accelerometer.lat_collision_from_left.time | fieldset | String | Time of event |
$accelerometer.lat_collision_from_left.value | fieldset, signal | Number | Acceleration force in milli-g |
$accelerometer.lat_collision_from_right.time | fieldset | String | Time of event |
$accelerometer.lat_collision_from_right.value | fieldset, signal | Number | Acceleration force in milli-g |
$accelerometer.motion | fieldset, signal | Boolean | Appends the motion state |
$accelerometer.time | fieldset, signal | Boolean | Time of motion event |
$accelerometer.value | fieldset, signal | Boolean | Acceleration force in milli-g |
set accelerometer self_alignment | action | Executes the self alignment |
actions
Actions related info.
property | use | description |
---|---|---|
trigger action action_name | action | Force the execution of an action |
adas (ecu)
ADAS accessory related info, configured via the ecu monitor.
property | use | type | description |
---|---|---|---|
$ecu.adas_speed | signal | Number | Speed detected by adas accessory in km/h |
$ecu.brakes_enabled | signal | Boolean | True if brakes detected |
$ecu.distance_from_front_vehicle | signal | Number | Distance from front vehicle in meters |
$ecu.failsafe | signal | Boolean | True if adas triggers one of the internal FailSafe modes, more info |
$ecu.forward_collision_warning | signal | Boolean | True if forward collision warning detected |
$ecu.headway_measurement | signal | Number | Headway measurement. Unit 0.1s. Range (0 - 9.9s) |
$ecu.headway_valid | signal | Boolean | True when CIPV (close in path vehicle) is detected |
$ecu.headway_warning_level | signal | Number | Headway warning level, more info |
$ecu.headway_warning_repeatable_enabled | signal | Boolean | True when Headway Warning repeatable feature is ON |
$ecu.high_beam_signal | signal | Boolean | True if high beam signal detected |
$ecu.lane_departure_warning_disabled | signal | Boolean | True if lane departure warning is disabled |
$ecu.left_lane_departure_warning | signal | Boolean | True if left lane departure warning detected |
$ecu.left_signal | signal | Boolean | True if left signal is detected |
$ecu.low_beam_signal | signal | Boolean | True if low beam signal detected |
$ecu.maintenance | signal | Boolean | True if adas accessory is maintenance mode |
$ecu.pedestrian_danger_zone | signal | Boolean | True if pedestrian in danger zone is detected |
$ecu.pedestrian_forward_collision_warning | signal | Boolean | True if pedestrian forward collision warning is detected |
$ecu.relative_speed_from_front_vehicle | signal | Boolean | True if relative speed from front vehicle is detected |
$ecu.right_lane_departure_warning | signal | Boolean | True if right lane departure warning is detected |
$ecu.right_signal | signal | Boolean | True if right signal is detected |
$ecu.sound_type | signal | Number | Sound type, more info |
$ecu.speed_available | signal | Boolean | True if speed is available |
$ecu.speed_limit_recognition_sensitivity | signal | Number | Speed limit recognition sensitivity |
$ecu.speed_limit_recognition_state | signal | Number | Speed limit recognition state |
$ecu.speed_limit_recognition_value | signal | Number | Speed limit recognition value |
$ecu.tamper_alert | signal | Boolean | True if a tamper alert is detected (fired when camera is blocked) |
$ecu.time_indicator | signal | Number | Time indicator, more info |
$ecu.traffic_signs_recognition_enabled | signal | Boolean | True when traffic signal recognition feature is on |
$ecu.traffic_signs_recognition_warning_level | signal | Number | Traffic signs recognition warning level, more info |
$ecu.wipers_signal | signal | Boolean | True when a wiper passes the windshield, 0 if wipers are static |
$ecu.zero_speed | signal | Boolean | True if zero speed is detected (vehicle is stopped) |
blackbox
Blackbox functionality allows you to save data to a file.
property | use | description |
---|---|---|
@logs.event | signal | Triggered when any log event is detected. |
$logs.name | signal fieldset | Stores log rotation name for apx-logrotate |
$logs.path | signal fieldset | Stores log file path |
$logs.used | signal fieldset | Stores media used memory |
$logs.available | signal fieldset | Stores media available memory |
$logs.size | signal fieldset | Stores media total size |
$logs.percentage | signal fieldset | Stores media memory usage in percentage |
$logs.period | signal fieldset | Stores the rotation period configuration (daily, weekly, monthly) |
$logs.rotate | signal fieldset | Stores the total log files stored before rotation (ex. 5 days) |
battery
Device internal battery information.
property | use | type | description |
---|---|---|---|
$battery | fieldset | Object | json appends all battery fields |
$battery | fieldset | String | taip compatible field |
$battery.connected | fieldset,signal | Boolean | True if the internal battery is connected |
@battery.critical | signal | Number | Battery <= 10% |
@battery.low | signal | Number | Battery <= 20% |
@battery.full | signal | Number | Battery = 100% |
$battery.mv | fieldset,signal | Number | Internal battery voltage in milliVolts |
$battery.level | fieldset,signal | Number | Internal battery level (%) |
$battery.voltage | fieldset,signal | Number | Internal battery voltage |
bluetooth
Bluetooth functionality. To speak via the bluetooth check out the modem speak action.
property | use | description |
---|---|---|
bluetooth connect 'AABBCCDDEEFF' | action | Connect to bluetooth device |
bluetooth disconnect 'AABBCCDDEEFF' | action | Disconnect from bluetooth device |
bluetooth pair 'AABBCCDDEEFF' | action | Pair to a bluetooth device |
bluetooth pairforced '_AABBCCDDEEFF' | action | Force pairing |
bluetooth reset 'AABBCCDDEEFF' | action | 🛑 Resets bluetooth paired devices |
bluetooth restart 'AABBCCDDEEFF' | action | Restart bluetooth |
bluetooth scan seconds | action | Replace with amount of seconds |
bluetooth switchaudio '_AABBCCDDEEFF' | action | Switch main audio |
bluetooth unpair 'AABBCCDDEEFF' | action | Unpair from bluetooth device |
@bluetooth.button.call_2x | signal | Bluetooth call button pressed 2 times |
@bluetooth.button.volume_up | signal | Bluetooth volume up |
@bluetooth.button.volume_down | signal | Bluetooth volume down |
@bluetooth.button.mute | signal | Bluetooth mute button pressed |
bluetooth beacons (ble)
Bluetooth low energy that can communicate with sensors and tags.
property | use | type | description |
---|---|---|---|
@ble.event | signal | Triggered at any ble event | |
@ble. (MAC or ALIAS).temperature.change | signal | Triggered when a change in temperature is detected | |
@ble. (MAC or ALIAS).mac | fieldset, signal | String | Device mac address |
@ble. (MAC or ALIAS).name | fieldset, signal | String | Advertised name |
@ble. (MAC or ALIAS).alias | fieldset, signal | String | Assigned alias |
@ble. (MAC or ALIAS).timestamp | fieldset, signal | Number | Scanned time |
@ble. (MAC or ALIAS).temperature | fieldset, signal | Number | Reported temperature value in degrees celsius |
@ble. (MAC or ALIAS).humidity | fieldset, signal | Number | Reported humidity value in percentage |
@ble. (MAC or ALIAS).movement | fieldset, signal | Number | Reported number of movements detected |
counters
Device counters information.
property | use | type | description |
---|---|---|---|
$counters | fieldset | Object | json appends all counter fields |
$counters | fieldset | String | taip compatible field |
$counters.name.odometer | fieldset, signal | Number | Total distance traveled with ignition ON (meters) |
$counters.name.ignition_time | fieldset, signal | Number | Total ignition time (seconds) |
$counters.name.idle_time | fieldset, signal | Number | Total time spent in idling (seconds) |
$counters.name.over_speed | fieldset, signal | Number | Total time spent over speed (seconds) |
$counters.name.over_rpm | fieldset, signal | Number | Total time spent over RPMs (seconds) |
$counters.name.hard_brakes | fieldset, signal | Number | Total amount of hard brake events (count) |
$counters.name.harsh_fwd_acceleration | fieldset, signal | Number | Total amount of harsh forward acceleration events (count) |
$counters.name.total_count | fieldset, signal | Number | Stores number of times a signal becomes true |
$counters.name.total_time | fieldset, signal | Number | Stores the total time a signal stays true, stops counting when false |
$counters.name.time_increment | fieldset, signal | Number | Stores the time passed while a signal is true, reset count when false |
$counters.name.total_distance | fieldset, signal | Number | Stores the total distance traveled while a signal is true, stops counting when false |
$counters.name.distance_increment | fieldset, signal | Number | Stores the distance traveled while a signal is true, reset count when false |
$counters.name.state | fieldset, signal | Number | Stores the counter state (true when counting) |
define counters name | action | Create a counter definition | |
start counters name | action | Start/enable the counting function and listen for change in the selected signals | |
stop counters name | action | Stop/disable the counting function, any change in the signals will be ignored | |
reset counters name | action | Reset/restart the states values, like total_count, total_time, etc. | |
get counters name | action | Get a counter definition | |
set counters name field=value | action | Set counter threshold |
destinations
Destinations related actions.
property | use | description |
---|---|---|
enable destination destination_name | action | Enable the destination |
disable destination destination_name | action | Disable the destination |
ecu
Engine Control Unit related information. For more info visit: Engine Control Unit (ECU).
property | Use | type | description |
---|---|---|---|
$ecu | fieldset | Object | json appends all valid ecu parameters |
$ecu | fieldset | String | taip compatible fieldset |
$ecu.id | fieldset, signal | Multiple | id refers to the specific pgn + start_position |
$ecu.param_name | fieldset, signal | Multiple | param_name refers to the parameters listed in the SDK ECU.d directory files |
$ecu.error_codes.spn | fieldset, signal | Number | ECU diagnostic trouble code SPN number. More info |
$ecu.error_codes.fmi | fieldset, signal | Number | ECU diagnostic trouble code FMI number. More info |
events
Events related actions.
property | use | description |
---|---|---|
send event event_name | action | Generate an event to the defined destinations |
fire signal signal_name | action | Simulate a signal |
fatigue_sensor
Fatigue sensor accessory related information. Note that the fatigue sensor information can come from either the CAN bus or Serial (RS-232) cables.
property | use | type | description |
---|---|---|---|
$fatigue_sensor | fieldset | Object | Akmppends relevant fatigue_sensor information to the payload |
@serial.fatigue_sensor.SIGNAL | signal | Boolean | Serial fatigue sensor specific signals |
@fatigue_sensor.fatigue_remind | signal | Boolean | True when a fatigue reminder was detected |
@fatigue_sensor.fatigue_warning | signal | Boolean | True when yawning or a fatigue warning was detected |
@fatigue_sensor.fatigue_alarm | signal | Boolean | True when drowsiness or fatigue alert was detected |
@fatigue_sensor.no_portrait | signal | Boolean | True when no driver is detected |
@fatigue_sensor.distraction | signal | Boolean | True when the driver is distracted |
@fatigue_sensor.phone | signal | Boolean | True when a driver is on their phone |
@fatigue_sensor.smoking | signal | Boolean | True when a driver is smoking |
@fatigue_sensor.seatbelt_off | signal | Boolean | True when a driver is driving without the seatbelt |
@fatigue_sensor.camera_blocked | signal | Boolean | True when the fatigue sensor's camera is blocked |
@fatigue_sensor.photo | signal | Boolean | True when a photo was captured manually |
@fatigue_sensor.signal | signal | Boolean | True when any fatigue sensor event is triggered |
$fatigue_sensor.connected | signal fieldset | Boolean | True if fatigue sensor is connected |
$fatigue_sensor.state | signal fieldset | String | "connected" or "disconnected" |
$fatigue_sensor.sensitivity | signal fieldset | Number | Sensitivity of the fatigue sensor |
$fatigue_sensor.speaker_volume | signal fieldset | Number | Volume of the fatigue sensor |
$fatigue_sensor.min_speed | signal fieldset | Number | Minimum speed to trigger fatigue sensor alerts |
$fatigue_sensor.speeding | signal fieldset | Number | Speeding threshold |
$fatigue_sensor.max_photos | signal fieldset | Number | Total number of photos that can be captured |
$fatigue_sensor.nbr_photos | signal fieldset | Number | Number of photos captured |
$fatigue_sensor.latest_photo | signal fieldset | Number | Latest photo |
$ecu.distraction | signal fieldset | Boolean | True when the driver is distracted |
$ecu.yawning | signal fieldset | Boolean | True if the driver is yawning |
$ecu.drowsiness | signal fieldset | Boolean | True when drowsiness was detected |
$ecu.phone | signal fieldset | Boolean | True if the driver is on their phone |
$ecu.smoking | signal fieldset | Boolean | True when smoking was detected by the driver |
$ecu.driver_absence | signal fieldset | Boolean | True when there's no driver present |
$ecu.camera_blocked | signal fieldset | Boolean | True if the camera is blocked |
$ecu.camera_error | signal fieldset | Boolean | True when a camera error was detected |
$ecu.zero_speed | signal fieldset | Boolean | True when the vehicle is parked |
$ecu.error_valid | signal fieldset | Boolean | True when an error was detected by the fatigue sensor |
$ecu.tamper_alert | signal fieldset | Boolean | True if tampering is detected by the fatigue sensor |
capture fatigue_sensor photo | action | Captures a photo with the fatigue sensor camera | |
upload fatigue_sensor photos | action | Manually upload all photos to an ftp destination | |
set fatigue_sensor sensitivity | action | Change sensitivity (Range: 2-11) | |
set fatigue_sensor speaker_volume | action | Change the speaker volume (Range: 0-2) | |
set fatigue_sensor minimum_speed | action | Change the minimum speed to trigger fatigue alerts (Range: 10-60)kph | |
set fatigue_sensor speeding_alarm | action | Change the speeding alarm (Range: 0-255)kph | |
set fatigue_sensor buffer_size | action | Change the max photos that can be captured (Range: 10-100) | |
set fatigue_sensor autoupload | action | Manage the auto upload of photos to the DCT ftp directory, default is 0 | |
clear fatigue_sensor buffer | action | Deletes all photos in the fatigue_sensor directory |
fuel sensor
Fuel sensor related information
property | use | type | description |
---|---|---|---|
$fuel | fieldset | String | json and taip compatible fieldset. Appends all fuel sensor fields or ;FF tag for TAIP |
@fuel.event | signal | Boolean | Triggered when any fuel event is detected |
@fuel.state | signal | Boolean | Triggered when a state arrives |
@fuel.fueling | signal | Boolean | Triggered when a fueling notification arrives |
@fuel.warning | signal | Boolean | Triggered when a discharge warning notification arrives |
@fuel.connected | signal | Boolean | Triggered when a transition from disconnected to connected is detected |
@fuel.disconnected | signal | Boolean | Triggered when a transition from connected to disconnected is detected |
$fuel.connected | fieldset, signal | Boolean | Stores the last connected state |
$fuel.level | fieldset, signal | Number | Stores the last fuel level |
$fuel.temperature | fieldset, signal | Number | Stores the last temperature level |
$fuel.frequency | fieldset, signal | Number | Stores the last frequency |
$fuel.timestamp | fieldset, signal | Number | Stores the last notification timestamp |
$fuel.event | fieldset, signal | String | Stores the last event |
geofences
Geofences related information
property | use | type | description |
---|---|---|---|
$geofences.name.inside | fieldset, signal | Boolean | Inside <name> |
$geofences.name.time | fieldset, signal | Number | Time when device entered <name> |
$geofences.$groups.group_name.inside | signal | Boolean | Inside any fence in <group_name> |
$geofences.$groups.group_name.outside | signal | Boolean | Outside all fences in <group_name> |
@last_geofence.name | fieldset | String | Last geofence name |
@last_geofence.state | fieldset | String | inside, outside |
@last_geofence.time | fieldset | Number | Time of last geofence |
gnss
GNSS position information
property | use | type | description |
---|---|---|---|
$gnss | fieldset | Object | json appends all gnss fields |
$gnss | fieldset | String | taip compatible fieldset |
$gnss.accuracy | fieldset, signal | Number | Position accuracy in meters |
$gnss.altitude | fieldset, signal | Number | Altitude AMSL |
$gnss.altitudeAccuracy | fieldset, signal | Number | Altitude accuracy |
$gnss.bearing | fieldset, signal | Number | Relative bearing to a base station |
$gnss.criteria | fieldset, signal | String | GNSS criteria |
$gnss.fix | fieldset, signal | Number | 1: no fix, 2: 2D fix, 3: 3D fix |
$gnss.hdop | fieldset, signal | Number | Horizontal DOP |
$gnss.heading | fieldset, signal | Number | Heading 0°N, 90°E, ... |
$gnss.kph | fieldset, signal | Number | Speed in kph (float) |
$gnss.latitude | fieldset, signal | Number | WGS84 Latitude |
$gnss.longitude | fieldset, signal | Number | WGS84 Longitude |
$gnss.mph | fieldset, signal | Number | Speed in mph (float) |
$gnss.pdop | fieldset, signal | Number | Position DOP |
$gnss.satsActive | fieldset, signal | Number | Satellites used |
$gnss.speed | fieldset, signal | Number | Speed value in m/s (float) |
$gnss.timestamp | fieldset, signal | Number | Epoch gps timestamp |
$gnss.vdop | fieldset, signal | Number | Vertical DOP |
$kph | fieldset, signal | Number | Speed in kph (integer) |
$mph | fieldset, signal | Number | Speed in mph (integer) |
$speed | fieldset, signal | Number | Speed value in m/s (integer) |
$timestamp | fieldset | String | dddd, MMMM D, YYYY h:hh A format |
$timestamp.es | fieldset | String | dddd, D de MMMM de YYYY HH:hh format |
$timestamp.fr | fieldset | String | dddd D MMMM YYYY HH:hh format |
$timestamp.pt | fieldset | String | dddd, D de MMMM de YYYY HH:hh format |
set gnss hot-start | action | Executes a gps hot start | |
set gnss warm-start | action | Executes a gps warm start | |
set gnss cold-start | action | Executes a gps cold start |
ibutton
IButton component, note that a total of 500 onewire devices can be created (between ibutton and temperature sensors)
property | Use | type | description |
---|---|---|---|
$ibutton | fieldset | Object | json appends all ibutton fields |
IB:$ibutton.connected.id | fieldset | String | taip connected ibutton id |
IS:$ibutton.last.id | fieldset | String | taip last connected ibutton id |
$ibutton.authorized.connected.alias | fieldset, signal | String | Alias of authorized ibutton |
$ibutton.authorized.connected.connected | fieldset, signal | Boolean | Authorized ibutton connected |
$ibutton.authorized.connected.id | fieldset, signal | String | ID of the authorized ibutton |
$ibutton.authorized.connected.conn_epoch | fieldset, signal | Number | Epoch of when it was connected |
$ibutton.authorized.last.alias | fieldset, signal | String | Alias of last authorized ibutton |
$ibutton.authorized.last.id | fieldset, signal | String | Current ID of the last authorized ibutton |
$ibutton.authorized.last.conn_epoch | fieldset, signal | Number | Epoch of last authorized ibutton connection |
$ibutton.authorized.last.disc_epoch | fieldset, signal | Number | Epoch of last authorized ibutton disconnection |
$ibutton.connected.alias | fieldset, signal | String | Alias of connected ibutton |
$ibutton.connected.connected | fieldset, signal | Boolean | True if any ibutton is currently detected |
$ibutton.connected.id | fieldset, signal | String | ID of the connected ibutton |
$ibutton.connected.whitelisted | fieldset, signal | Boolean | True while the ibutton connected is authorized |
$ibutton.connected.conn_epoch | fieldset, signal | Number | Epoch of ibutton connection |
$ibutton.last.alias | fieldset, signal | String | Alias of last connected ibutton |
$ibutton.last.connected | fieldset, signal | Boolean | True if ibutton is connected |
$ibutton.last.id | fieldset, signal | String | ID of last connected ibutton |
$ibutton.last.whitelisted | fieldset, signal | Boolean | True if last ibutton is authorized |
$ibutton.last.conn_epoch | fieldset, signal | Number | Epoch of last ibutton connection |
$ibutton.last.disc_epoch | fieldset, signal | Number | Epoch of last ibutton disconnection |
add ibutton alias_name id | action | add ibutton to authorized list | |
remove ibutton alias_name | action | remove ibutton from authorized list by alias_name | |
remove ibutton id | action | remove ibutton from authorized list by id | |
remove ibuttons | action | 🛑 remove all ibuttons from authorized list | |
clear ibutton | action | clears the last ibutton read | |
get ibutton alias_name | action | get ibutton by alias_name | |
get ibutton id | action | get ibutton by id | |
get ibuttons | action | get list of ibutton defined |
io
Inputs/Outputs component
property | Use | type | description |
---|---|---|---|
$io | fieldset | Object | json appends all io fields |
$io | fieldset | String | taip compatible fieldset |
$io.an1 | fieldset, signal | Number | Analog input channel 1 (range: 0-28000mV) |
$io.an2 | fieldset, signal | Number | Analog input channel 2 (range: 0-28000mV) |
$io.dan | fieldset, signal | Number | Differential analog values (range: 0-10000mV) |
$io.ign | fieldset, signal | Boolean | True when the state of the ignition is ON |
$io.in1 | fieldset, signal | Boolean | True when input 1 is ON |
$io.in2 | fieldset, signal | Boolean | True when input 2 is ON |
$io.in3 | fieldset, signal | Boolean | True when input 3 is ON |
$io.in4 | fieldset, signal | Boolean | True when input 4 is ON |
$io.in5 | fieldset, signal | Boolean | True when input 5 is ON |
$io.in6 | fieldset, signal | Boolean | True when input 6 is ON |
$io.in7 | fieldset, signal | Boolean | True when input 7 is ON |
$io.out1 | fieldset, signal | Boolean | True when output 1 is ON |
$io.out2 | fieldset, signal | Boolean | True when output 2 is ON |
$io.out3 | fieldset, signal | Boolean | True when output 3 is ON |
$io.out4 | fieldset, signal | Boolean | True when output 4 is ON |
$io.pwr | fieldset, signal | Boolean | True when external power is ON |
$io.so1 | fieldset, signal | Boolean | True when a short circuit on output 1 is detected |
$io.so2 | fieldset, signal | Boolean | True when a short circuit on output 2 is detected |
$io.so3 | fieldset, signal | Boolean | True when a short circuit on output 3 is detected |
$io.so4 | fieldset, signal | Boolean | True when a short circuit on output 4 is detected |
$io.tig | fieldset, signal | Boolean | True when ignition detected from power |
$safe_immo | variable, signal | Boolean | True when Pegasus sends safe immobilization (SECO) command to device (more information here) |
set out# on | action | activate output # | |
set out# off | action | deactivate output # |
mdt
RS-232 Mobile Data Terminal info
modem
Modem information.
property | use | type | description |
---|---|---|---|
$modem | fieldset | Object | json appends all modem fields |
$modem | fieldset | String | taip compatible fieldset (includes ;SC tag) |
$modem.band | fieldset, signal | String | LTE band |
$modem.cid | fieldset, signal | String | Cell ID in hex format |
$modem.esim_id | fieldset, signal | String | Embedded sim ID |
$modem.esim_imsi | fieldset, signal | String | Embedded sim IMSI |
$modem.esim_state | fieldset, signal | String | Embedded sim card state ("READY", "Not in Use") |
$modem.gprs_reg | fieldset, signal | Number | GPRS registration status |
$modem.gsm_reg | fieldset, signal | Number | GSM registration status |
$modem.imei | fieldset, signal | Number | Unique numeric identifier |
$modem.ip | fieldset, signal | String | IP address assigned by operator |
@modem.jamming_detected | signal | Boolean | Triggered when a jamming condition is detected |
@modem.jamming_persistence | signal | Boolean | Triggered when the jamming condition persist for one minute |
@modem.jamming_ended | signal | Boolean | Triggered when jamming action stops |
$modem.state | fieldset, signal | String | The jamming state [ JAMMED , NOT_JAMMING ] |
$modem.jamming_detected | fieldset, signal | Boolean | The jamming state |
$modem.jamming_persistence | fieldset, signal | Boolean | The persistence flag state |
$modem.jamming_ended | fieldset, signal | Boolean | The ended flag state |
$modem.lac | fieldset, signal | Number | Location area code |
$modem.manufacturer | fieldset, signal | String | Modem's manufacturer |
$modem.mcc_mnc | fieldset, signal | Number | Mobile Country and Network Code |
$modem.model | fieldset, signal | String | Model of modem |
$modem.modem_state | fieldset, signal | String | State of the modem ("ON", "OFF") |
$modem.no_conn_time | fieldset, signal | String | Time spent with no connection in minutes, note that this is exclusively for the modem, so the device could be connected via ethernet/wifi and not LTE |
$modem.operator | fieldset, signal | String | Network operator |
$modem.rat | fieldset, signal | String | Radio access technology |
$modem.revision | fieldset, signal | String | Modem's revision |
$modem.rssi | fieldset, signal | Number | Received Signal Strength Indicator (0-32) |
$modem.sim_id | fieldset, signal | Number | External sim ID |
$modem.sim_imsi | fieldset, signal | Number | External sim IMSI |
$modem.sim_state | fieldset, signal | Number | External sim State ("READY", "Not in Use") |
$modem.temperature | fieldset, signal | Number | Modem's temperature (generally higher than ambient temperature |
set airplane_mode true | action | Set to true to enable airplane_mode | |
set sim_switch_interval 8 | action | Time interval in hours to wait to switch from external to internal sim card | |
start call +1234567890 | action | Start a phone call | |
end call | action | End a phone call | |
send sms 3013333333 'testing sms' | action | Send an SMS message to 3013333333 | |
add phone +1234567890 | action | Add phone +1234567890 to phonebook | |
remove phone +1234567890 | action | Remove phone +1234567890 from phonebook | |
set call_validation true | action | Enable call validation from phonebook | |
set sms_validation true | action | Enable call validation from phonebook | |
speak lang=en 'hello world' | action | Speak via the bluetooth |
net_cell
Cellular interface
property | use | type | description |
---|---|---|---|
$net_cell.connected | fieldset, signal | Boolean | True when connected |
$net_cell.iccid | fieldset, signal | Number | SIM card ICCID |
$net_cell.imei | fieldset, signal | Number | Device unique IMEI number |
$net_cell.imsi | fieldset, signal | Number | SIM card IMSI |
$net_cell.ip_address | fieldset, signal | String | IP assigned by MNO |
$net_cell.mcc | fieldset, signal | Number | Mobile country code |
$net_cell.mnc | fieldset, signal | Number | Mobile network code |
$net_cell.operator | fieldset, signal | String | Network operator |
$net_cell.rx_bytes | fieldset, signal | Number | Bytes received |
$net_cell.tx_bytes | fieldset, signal | Number | Bytes transmitted |
net_eth
Ethernet interface
property | use | type | description |
---|---|---|---|
$net_eth.connected | fieldset, signal | Boolean | Ethernet connected |
$net_eth.ip_address | fieldset, signal | String | IP address |
$net_eth.rx_bytes | fieldset, signal | Number | Bytes received |
$net_eth.tx_bytes | fieldset, signal | Number | Bytes transmitted |
enable ethernet | action | Enables the ethernet interface | |
disable ethernet | action | Disables the ethernet interface |
net_wifi
Wifi interface
property | use | type | description |
---|---|---|---|
$net_wifi.connected | fieldset, signal | Boolean | WiFi connected |
$net_wifi.ip_address | fieldset, signal | String | IP address |
$net_wifi.key_mgmt | fieldset, signal | String | Key management protocol |
$net_wifi.mac | fieldset, signal | String | WiFi MAC address |
$net_wifi.rx_bytes | fieldset, signal | Number | Bytes received |
$net_wifi.signal | fieldset, signal | Number | Signal strength in dbm |
$net_wifi.ssid | fieldset, signal | String | SSID name |
$net_wifi.state | fieldset, signal | String | Wifi connection ("Completed", "Disabled", "Interface_disabled" (when hotspot is on)) |
$net_wifi.tx_bytes | fieldset, signal | Number | Bytes transmitted |
enable wifi | action | Enables the wifi interface | |
disable wifi | action | Disables the wifi interface | |
restart wifi | action | Restarts the wifi interface |
net_wlan1 (hotspot)
Hotspot interface
property | use | type | description |
---|---|---|---|
$net_wlan1.connected | fieldset, signal | Boolean | Hotspot connected |
$net_wlan1.ip_address | fieldset, signal | String | IP address |
$net_wlan1.rx_bytes | fieldset, signal | Number | Bytes received |
$net_wlan1.tx_bytes | fieldset, signal | Number | Bytes transmitted |
enable hotspot | action | Enables the hotspot | |
disable hotspot | action | Disables the hotspot |
people_counting
People counting camera signals, actions, and recommended fieldsets.
property | use | type | description |
---|---|---|---|
@people.adult_enter | signal | Boolean | Adult entered |
@people.adult_exit | signal | Boolean | Adult exited |
@people.children_enter | signal | Boolean | Child entered |
@people.children_exit | signal | Boolean | Child exited |
@people.requested | signal | Boolean | Type of report obtained, whether daily or weekly |
@people.start | signal | Boolean | Starts people counting |
@people.stop | signal | Boolean | Ends people counting |
@people.restarted | signal | Boolean | People counting camera restarted |
@people.cam_connected | signal | Boolean | Camera connected |
@people.cam_disconnected | signal | Boolean | Camera disconnected |
@people.daily_report | signal | Boolean | Daily report generated |
@people.weekly_report | signal | Boolean | Weekly report generated |
$people.event | signal, fieldset | String | Last people counting event |
$people.adult.enter | signal, fieldset | Number | Adults entered |
$people.adult.exit | signal, fieldset | Number | Adults exited |
$people.children.enter | signal, fieldset | Number | Children entered |
$people.children.exit | signal, fieldset | Number | Children exited |
$people.adults_inside | signal, fieldset | Number | Adults inside |
$people.children_inside | signal, fieldset | Number | Children inside |
$people.global_adult.enter | signal, fieldset | Number | Total adults entered |
$people.global_adult.exit | signal, fieldset | Number | Total adults exited |
$people.global_children.enter | signal, fieldset | Number | Total children entered |
$people.global_children.exit | signal, fieldset | Number | Total children exited |
power_save
Power save mode
property | use | type | description |
---|---|---|---|
@power_save.ign | signal | Boolean | Wake up by ignition |
@power_save.in1 | signal | Boolean | Wake up from input 1 |
@power_save.in2 | signal | Boolean | Wake up from input 2 |
@power_save.in3 | signal | Boolean | Wake up from input 3 |
@power_save.in4 | signal | Boolean | Wake up from input 4 |
@power_save.in5 | signal | Boolean | Wake up from input 5 |
@power_save.in6 | signal | Boolean | Wake up from input 6 |
@power_save.in7 | signal | Boolean | Wake up from input 7 |
@power_save.motion | signal | Boolean | Wake up from motion |
@power_save.pwr | signal | Boolean | Wake up from ext power |
@power_save.sleep | signal | Boolean | Entering power save |
@power_save.so1 | signal | Boolean | Wake up from short circuit on out1 |
@power_save.so2 | signal | Boolean | Wake up from short circuit on out2 |
@power_save.so3 | signal | Boolean | Wake up from short circuit on out3 |
@power_save.so4 | signal | Boolean | Wake up from short circuit on out4 |
@power_save.tig | signal | Boolean | Wake up from ignition on power |
@power_save.time | signal | Boolean | Wake up by time |
@power_save.wakeup | signal | Boolean | Wakes up from power save |
$power_save.mode | fieldset | String | Power save mode string |
$power_save.reason | fieldset | String | Wake up reason |
$power_save.status | fieldset | Boolean | Power save mode status |
set power_save immediate | action | Force start power save mode | |
set power_save mode [PSM_STRING] | action | Modify power save mode |
rfid
Serial RFID component
property | Use | type | description |
---|---|---|---|
$rfid | fieldset | Object | json appends all rfid fields |
RI:$rfid.last.id | fieldset | String | taip last connected rfid id |
$rfid.last.id | fieldset, signal | String | ID of last connected rfid |
$rfid.last.alias | fieldset, signal | String | Alias of last connected rfid |
$rfid.last.whitelisted | fieldset, signal | Boolean | True if last rfid is authorized |
$rfid.last.conn_epoch | fieldset, signal | Number | Epoch of the last rfid connection |
$rfid.authorized.last.id | fieldset, signal | String | ID of the last authorized rfid |
$rfid.authorized.last.alias | fieldset, signal | String | Alias of last authorized rfid |
$rfid.authorized.last.whitelisted | fieldset, signal | Boolean | True if last rfid was authorized |
$rfid.authorized.last.conn_epoch | fieldset, signal | Number | Epoch of last authorized rfid |
@rfid.event | signal | Boolean | Triggered when any rfid event is detected |
@rfid.change | signal | Boolean | Triggered when the rfid changed |
@rfid.read | signal | Boolean | Triggered when a card approaches the reader, even if it's the same id |
@rfid.authorized | signal | Boolean | Triggered when the id is whitelisted |
@rfid.unauthorized | signal | Boolean | Triggered when the id is not whitelisted |
add rfid --id=1234 --alias=driver1 | action | add an RFID to the authorized list, or update alias of existing RFID | |
clear rfid | action | clears the last RFID read | |
remove rfid --id=1234 | action | removes an RFID from the authorized list | |
remove rfids | action | 🛑 removes all RFIDs from the authorized list | |
get rfid | action | get the last RFID read | |
get rfids | action | get a list of all RFIDs |
satellite (satcom/sigfox)
property | Use | type | description |
---|---|---|---|
$satcom | fieldset | Object | json appends all timer fields |
$satcom | fieldset | String | taip appends satellite modem's information |
$satcom.state | signal | String | State is connected when satellite is connected |
$satcom.id | signal | String | Satellite modem's id (imei) |
$satcom.signal | signal | Number | Signal strength, 0: weakest, 5: strongest |
$satcom.buff_size | signal | Number | Maximum allowed messages to be stored |
$satcom.buff_count | signal | Number | Amount of messages stored |
enable destination destination_name | action | Enables a destination | |
disable destination destination_name | action | Disables a destination | |
clear satcom buffer | action | Clears the satellite destination buffer | |
set satcom buffer_size | action | Set the satcom buffer size (Range from 10 to 500). | |
get satcom buffer_size | action | Get the satcom buffer size. |
timers
property | Use | type | description |
---|---|---|---|
$timers | fieldset | Object | json appends all timer fields |
@timers.timer_name | signal | Boolean | True if timer timer_name reaches its duration |
start timer timer_name | action | Start a timer | |
stop timer timer_name | action | Stops and clears a timer | |
enable timer timer_name | action | Enables a timer | |
disable timer timer_name | action | Disables a timer |
time windows
property | Use | type | description |
---|---|---|---|
@windows.name.start | signal | Boolean | One shot boolean, true when time-window starts |
@windows.name.end | signal | Boolean | One shot boolean, true when time-window ends |
$windows.name.in | signal | Boolean | State, true when current time is in time-window |
$windows.name.out | signal | Boolean | State, true when current time out of time-window |
temperature
Temperature component, note that a total of 500 onewire devices can be created (between temperature sensors and ibuttons)
property | Use | type | description |
---|---|---|---|
$temp | fieldset | Object | json appends all temp fields |
$temp.aliases | fieldset | Object | json Temperature info for all sensors |
$temp.aliases.alias_name | fieldset | Object | json Temperature info for particular alias |
$temp.sensor_list | fieldset | Object | json Temperature value for all sensors |
$temp.sensorlist._n | fieldset | Object | json Temperature value for nth index |
EA[A|B|C]:$temp.aliases._alias_name.value | fieldset | Number | taip Temperature value for alias_name |
EA[A|B|C]:$temp.sensor_list._n.value | fieldset | Number | taip Temperature value for nth index |
$temp.aliases.alias_name.id | fieldset, signal | String | ID of temperature sensor alias_name |
$temp.aliases.alias_name.value | fieldset, signal | Number | Temperature value in °C |
$temp.aliases.alias_name.connected | fieldset, signal | Boolean | True if alias_name is connected |
$temp.aliases.alias_name.epoch | fieldset, signal | Number | Timestamp of temperature sensor alias_name reading |
$temp.sensorlist._n.id | fieldset, signal | String | ID of nth temperature sensor |
$temp.sensorlist._n.value | fieldset, signal | Number | Temperature value in °C |
$temp.sensorlist._n.connected | fieldset, signal | Boolean | True if nth sensor is connected |
$temp.sensorlist._n.epoch | fieldset, signal | Number | Timestamp of nth temperature sensor reading |
add temperaturesensor _alias_name id | action | add temperature sensor | |
remove temperaturesensor _alias_name | action | remove temperature sensor by alias_name | |
remove temperaturesensor _id | action | remove temperature sensor by id | |
remove temperature_sensors | action | 🛑 remove all temperature sensors defined | |
get temperaturesensor _alias_name | action | get temperature sensor by alias_name | |
get temperaturesensor _id | action | get temperature sensor by id | |
get temperature_sensors | action | get list of temperature sensors defined | |
get temperature | action | get last temperature |
tpms (ecu)
TPMS information from the engine control unit.
property | Use | type | description |
---|---|---|---|
$ecu | fieldset | Object | json appends all valid ecu data including tpms data |
$tpms | fieldset | Object | json appends all the tpms fields according to each alert reported |
$ecu | fieldset | String | taip compatible fieldset |
$ecu.id | fieldset, signal | Multiple | id refers to the specific pgn + start_position |
$ecu.param_name | fieldset, signal | Multiple | param_name refers to the parameters listed in the SDK ECU.d directory files |
$ecu.$tires.axleindex__X.tire_Y.pressure | fieldset, signal | Number | Pressure in kPa for a specific tire where X refers to the axle index (starts at 0), and Y refers to the tire index |
$ecu.$tires.axleX_.tireY_.pressure | fieldset, signal | Number | Pressure in kPa for a specific tire where X refers to the axle index (starts at 1), and Y refers to the tire index |
$ecu.$tires.axleindex__X.tire_Y.temperature | fieldset, signal | Number | Temperature in °C for a specific tire where X refers to the axle index (starts at 0), and Y refers to the tire index |
$ecu.$tires.axleX_.tireY_.temperature | fieldset, signal | Number | Temperature in °C for a specific tire where X refers to the axle index (starts at 1), and Y refers to the tire index |
@tpms.alarm_ok | signal | Boolean | True when there's no tpms alerts/alarms detected |
@tpms.sensor_mute | signal | Boolean | True when any tire reports a missing signal |
@tpms.sensor_defective | signal | Boolean | True if any tire reports a defective sensor |
@tpms.tire_leak | signal | Boolean | True if any tire reports a tire leak |
@tpms.temperature_warning | signal | Boolean | True if a tire reports a temperature warning |
@tpms.over_inflation_critical | signal | Boolean | True if a tire reports a critical over inflation |
@tpms.over_inflation_warning | signal | Boolean | True if a tire reports a warning over inflation |
@tpms.under_inflation_critical | signal | Boolean | True if a tire reports a critical under inflation |
@tpms.under_inflation_warning | signal | Boolean | True if a tire reports a warning under inflation |
tracking_resolution
Tracking resolution information
property | use | type | description |
---|---|---|---|
@trackingresolution._name.distance | signal | Boolean | Distance is met |
@trackingresolution._name.heading | signal | Boolean | Heading is met |
@trackingresolution._name.time | signal | Boolean | Time is met |
@trackingresolution._name.signal | signal | Boolean | Any criteria is met |
set trackingresolution _name degrees time distance | action | Modify a tracking resolution |
variables
Variables related information
property | use | type | description |
---|---|---|---|
$variables | fieldset | Object | json appends all valid ecu data including tpms data |
$variables.name | fieldset, signal | Number or String | Contents of the variable name |
set variable name VALUE | action | Set variable name to a VALUE | |
set variable name increment | action | Increments the variable value by 1 | |
set variable name decrement | action | Decreases the variable value by 1 | |
set variable name reset | action | Set the variable value to 0 |
video
Video related information, more info
property | use | type | description |
---|---|---|---|
start recording | action | Starts a video recording | |
stop recording | action | Stops a video recording | |
create video | action | Creates a video clip |
Features
Accelerometer
The accelerometer allows you to configure the signals related to driving including collision and aggressive driving behavior.
To get accurate results you must first calibrate the accelerometer once the device is properly installed in a vehicle, you can visit the CONNECT page for more info.
Set
You can calibrate the accelerometer with the following command
set accelerometer self_alignment
and set individual thresholds with
set accelerometer CFG_FORWARD_COLLISION -2500
set accelerometer CFG_BACKWARD_COLLISION 2150
set accelerometer CFG_LAT_COLLISION_FROM_RIGHT -1930
set accelerometer CFG_LAT_COLLISION_FROM_LEFT 1930
set accelerometer CFG_HARSH_FWD_ACCELERATION 300
set accelerometer CFG_HARD_BRAKING -250
set accelerometer CFG_CORNERING_RIGHT -590
set accelerometer CFG_CORNERING_LEFT 430
Get
Get the values of a single parameter or all accelerometer parameters
get accelerometer forward_collision
get accelerometer all
Signal
The available signals for the accelerometer are:
Signal | Description |
---|---|
@accelerometer.forward_collision.signal | True when a forward collision is detected |
@accelerometer.backward_collision.signal | True when a backward collision is detected |
@accelerometer.lat_collision_from_right.signal | True when a collision from the right was detected |
@accelerometer.lat_collision_from_left.signal | True when a collision from the left was detected |
@accelerometer.harsh_fwd_acceleration.signal | True when a harsh acceleration was detected |
@accelerometer.hard_braking.signal | True when a sudden braking was detected |
@accelerometer.cornering_right.signal | True when hard cornering to the right was detected |
@accelerometer.cornering_left.signal | True when hard cornering to the left was detected |
Fieldset
You can append the actual g-force value and the exact time that the accelerometer signal was triggered with
$accelerometer.ACCELEROMETER_EVENT.value
- appends the force in milli-g when the accelerometer event was triggered
$accelerometer.ACCELEROMETER_EVENT.time
- appends the timestamp of when the accelerometer event was triggered (YYYY-MM-DDTHH:mm:ss.sssZ)
define fieldset default fields=$accelerometer.hard_braking.value,"time_of_hardbraking":$accelerometer.hard_braking.time
{
...
"accelerometer.hard_braking.value": -340,
"time_of_hardbraking": "2020-07-03T19:59:43.140Z"
}
ADAS
ADAS is an accessory that allows you to obtain advanced information about the behavior of drivers on the road.
It communicates via the ECU monitor.
Signals
The following table describes the list of signals available with the specific ADAS accessory you connect:
Comparison of Signals and Accessory
Description | Signal | Movon MDAS-9 Signal | Mobileye Signal |
---|---|---|---|
Brakes detecting | $ecu.brakes_enabled | ✅ | ✅ |
FailSafe (Error state) detection | $ecu.failsafe | ✅ | ✅ |
Forward collision warning detection | $ecu.forward_collision_warning | ✅ | ✅ |
Headway measurement (in meters) | $ecu.distance_from_front_vehicle | ✅ | 🚫 |
Headway measurement (in seconds) | $ecu.headway_measurement | ✅ | ✅ |
Headway valid (boolean) | $ecu.headway_valid | ✅ | ✅ |
Left and right signals | $ecu.left_signal & $ecu.right_signal | ✅ | ✅ |
Left lane departure warning | $ecu.left_lane_departure_warning | ✅ | ✅ |
Low and high beams detection | $ecu.low_beam_signal & $ecu.high_beam_signal | 🚫 | ✅ |
Parked (zero speed) detection | $ecu.zero_speed | ✅ | ✅ |
Pedestrian forward collision warning | $ecu.pedestrian_forward_collision_warning | ✅ | ✅ |
Pedestrian in danger zone | $ecu.pedestrian_danger_zone | ✅ | ✅ |
Relative speed from front of vehicle | $ecu.relative_speed_from_front_vehicle | ✅ | 🚫 |
Right lane departure warning | $ecu.right_lane_departure_warning | ✅ | ✅ |
Speed limit recognition | $ecu.speed_available | ✅ | ✅ |
Tamper detection | $ecu.tamper_alert | ✅ | 🚫 |
Time indicator | $ecu.time_indicator | 🚫 | ✅ |
Wipers detection | $ecu.wipers_signal | 🚫 | ✅ |
For a complete list of signals head to the Device Components Library. This section goes into details on specific signals.
$ecu.failsafe
True if the adas accessory triggers any of the following failsafe modes: blurred image, saturated image, low sun, partial blockage, or partial transparent.
$ecu.headway_warning_level | Description |
---|---|
0 | When no CIPV (Close in path vehicle) is present |
1 | When a CIPV is present with Headway Warning > Headway Warning configured |
2 | When a CIPV is present with Headway Warning <= Headway Warning configured |
3 | When a CIPV is present with Headway Warning < 0.6 |
$ecu.time_indicator | Description |
---|---|
0 | Day |
1 | Dusk |
2 | Night |
$ecu.traffic_signs_recognition_warning_level | Description |
---|---|
0 | Speed <= road speed |
1 | Speed > road speed + [0 - 5 km/h] |
2 | Speed > road speed + [5 - 10 km/h] |
3 | Speed > road speed + [10 - 15 km/h] |
4 | Speed > road speed + [15 - 20 km/h] |
5 | Speed > road speed + [20 - 25 km/h] |
6 | Speed > road speed + [25 - 30 km/h] |
7 | Speed > road speed + [30 - 35 km/h] |
8 | Speed > road speed + 35 km/h |
$ecu.sound_type | Description |
---|---|
0 | Silent |
1 | Lane departure warning Left |
2 | Lane departure warning Right |
3 | Headway warning 1 |
4 | Traffic sign recognition |
5 | Urban forward collision warning |
6 | Forward collision warning + Pedestrian collision warning |
# Forward collision warning detected
define signal fcw $ecu.forward_collision_warning
# Night signal
define signal night_time $ecu.time_indicator == 2
# FCW at night event
define event fcw_at_night group=tracking fieldset=default ack=seq label=fcwnight trigger=fcw,night_time,and
Blackbox
The blackbox feature allows you to save data to a file periodically. It is enabled automatically for any destination file definition. For information on how to configure the destination file see Logging to a file.
Once you create the definition in your destinations file you're ready to start saving data to it.
$MEDIA_PATH and USER_PATH
Note that you can use
$MEDIA_PATH
or$USER_PATH
to indicate/media/mmcblk0p1
or/data/users/syrus4g
For example, if you want to log data second by second to a file on an SD card and have that file automatically compress and rotate after 1 week you can use a destination like:
define destination gps_data csv file://$MEDIA_PATH/gps_data.csv ack=disabled rotate=1D
and a configuration file with:
# create a group for logging
define group blackbox
# create a fieldset to append data to the csv
define fieldset csvfields fields=gnss_timestamp:$gnss.timestamp,
speed:$speed,
acceleration:$gnss.acceleration.value,
latitude:$gnss.latitude,
longitude:$gnss.longitude,
heading:$gnss.heading,
bearing:$gnss.bearing,
altitude:$gnss.altitude,
fix:$gnss.fix,
sats_active:$gnss.satsActive,
accuracy:$gnss.accuracy,
hdop:$gnss.hdop,
vdop:$gnss.vdop,
pdop:$gnss.pdop,
power:$io.pwr,
ignition:$io.ign,
input1:$io.in1,
$ecu.fef4,
# signals for detection of ignition
define signal sg_ignON $io.ign
define signal sg_ignOFF $io.ign == false
# create a timer every second
define timer tm_csv duration=1sec enabled=true repeat=true
# timer conditions to start and stop based on ignition state
define action ev_startlog trigger=sg_ignON start timer tm_csv
define action ev_stoplog trigger=sg_ignOFF stop timer tm_csv
# event that's generated and saved to the file
define event ev_writelog group=blackbox fieldset=csvfields rate=1/1sec label=blackbox code=88 [email protected]_csv,sg_ignON,and
# log the events from group logs to the destination
set destinations group=blackbox gps_data
This will create files with the following format: NAME-YYYYMMDD.gz
where NAME is the destination file name, so in this case gps_data.csv and YYYYMMDD is year, month, and date, example: 20220621. Note that the first file is created at midnight for the previous day.
In the previous example, logs will be created for up to 5 days and then the oldest file is rotated out.
[email protected] /media/sd_card
-rwxrwxrwx 1 root plugdev 228.9K Jun 18 00:00 gps_data.csv-20220617.gz
-rwxrwxrwx 1 root plugdev 164.7K Jun 19 00:00 gps_data.csv-20220618.gz
-rwxrwxrwx 1 root plugdev 175.2K Jun 20 00:00 gps_data.csv-20220619.gz
-rwxrwxrwx 1 root plugdev 175.3K Jun 21 00:00 gps_data.csv-20220620.gz
-rwxrwxrwx 1 root plugdev 175.4K Jun 22 00:00 gps_data.csv-20220621.gz
-rwxrwxrwx 1 root plugdev 7.9M Jun 22 19:04 gps_data.csv
Once the files are generated you can use the download file feature in SyrusCloud to download the logs remotely at any time.
Bluetooth
Bluetooth allows you to pair and connect to a bluetooth speakerphone that support HFP bluetooth profiles only. Other bluetooth profile variations like JL-HFP
, or HSP.HFP
are not supported at the moment.
Scan and pair a bluetooth speakerphone with the apx-bt system tool.
You can also use the Pegasus command console if you have access to it, simply write: >SSL
followed by the bluetooth command
command | description |
---|---|
bluetooth scan seconds | Scans for this amount of seconds |
bluetooth pair 'AABBCCDDEEFF' | Pair to a bluetooth device |
bluetooth pairforced '_AABBCCDDEEFF' | Force pairing |
bluetooth unpair 'AABBCCDDEEFF' | Unpair from bluetooth device |
bluetooth connect 'AABBCCDDEEFF' | Connect to bluetooth device |
bluetooth disconnect 'AABBCCDDEEFF' | Disconnect from bluetooth device |
bluetooth switchaudio '_AABBCCDDEEFF' | Switch main audio |
bluetooth restart 'AABBCCDDEEFF' | Restart bluetooth |
bluetooth reset 'AABBCCDDEEFF' | 🛑 Resets bluetooth paired devices |
>SSLbluetooth scan 15<
>SSLbluetooth connect 'AABBCCDDEEFF'<
command results | description |
---|---|
bluetooth info 'AABBCCDDEEFF' | Shows bluetooth info |
bluetooth infoall '_AABBCCDDEEFF' | Shows all info |
bluetooth listdiscovered '_AABBCCDDEEFF' | Shows list of discovered |
bluetooth listpaired '_AABBCCDDEEFF' | Shows list of paired |
bluetooth listconnected '_AABBCCDDEEFF' | Shows list of connected |
>SSLbluetooth list_discovered<
>RSL{"FC65DE2040E1":"Echo Show-1SN","7C6456A13E51":"[TV] Samsung Frame (43)","A0E6F8D3A66E":"Syrus 3GBT 05949"}<
Note that not all bluetooth devices that are discovered can be connected to for audio purposes, some bluetooth devices are connectable, but would not reproduce audio, check the bluetooth profile.
Actions
A possible action may be to connect to a separate speaker when you reach home
define action switch_bluetooth trigger=inside_home bluetooth connect '7C6456A13E51'
or force switch audio whenever the ignition turns on
define action force_audio trigger=ignition_on bluetooth switch_audio 'FC65DE2040E1'
Bluetooth Destinations
Bluetooth destinations can be defined to either broadcast messages to the S4GBT Destination Point characteristic or communicate with the user application console S4GBT User Application Console.
The main difference between the two is that the Destination Point characteristic only allows for messages to be notified, while the User application console allows you to write and read to that characteristic giving you the possibility of acknowledging messages.
Destination Point Characteristic
A sample configuration file (configuration.syrus.conf
) may look like the following:
# create a group for bluetooth
define group bluetooth
# fieldset for json message
define fieldset default fields=$gnss,$io
# create event definition
define event movement group=bluetooth ack=disabled fieldset=default [email protected]
# set destination to bluetooth endpoint
set destinations group=bluetooth bt_event_destination
A sample destinations file (destinations.syrus.conf
) may look like the following:
# bluetooth destination
define destination bt_event_destination json bluetooth://_:_ ack=disabled
In the above scenario the movement event will be generated and sent to the S4GBT Destination Point characteristic.
User Application Characteristic
This configuration allows you to enable acknowledgement for event messages allowing you to queue and de-queue once your application receives an event notification.
Note that only taip
protocol can be used for message acknowledgement.
A sample configuration file (configuration.syrus.conf
) may look like the following:
# create a group for bluetooth
define group bluetooth
# create fieldset for taip messages
define fieldset default fields=$gnss,$io
# create event definition
define event movement group=bluetooth ack=seq fieldset=default [email protected]
# set destination to bluetooth endpoint
set destinations group=bluetooth bt_apps_destination
A sample destinations file (destinations.syrus.conf
) may look like the following:
# bluetooth destination
define destination bt_apps_destination taip bluetooth://apps:_ ack=seq
In the above scenario the movement event will be generated and sent to the S4GBT User Application characteristic, the message will continue to be resent until it's ACK, see acknowledgement section for more info.
Bluetooth beacons
Once you have configured a bluetooth BLE sensor, you can trigger signals and detect states in the following way:
Signals
Fields | Description |
---|---|
@ble.event | Triggered at any ble event |
@ble.(MAC or ALIAS).temperature.change | Triggered when a change in temperature is detected |
States
Fields | Description |
---|---|
$ble.(MAC_ADDRESS or ALIAS).mac | Device mac address |
$ble.(MAC_ADDRESS or ALIAS).name | Advertised name |
$ble.(MAC_ADDRESS or ALIAS).alias | Assigned alias |
$ble.(MAC_ADDRESS or ALIAS).timestamp | Scanned time |
$ble.(MAC_ADDRESS or ALIAS).temperature | Reported temperature value in degrees celsius |
$ble.(MAC_ADDRESS or ALIAS).humidity | Reported humidity value in percentage |
$ble.(MAC_ADDRESS or ALIAS).movement | Reported number of movements detected |
The next script send events when detect a change in the temperature
# -- Variables definitions
define variable movement
set variable movement 0
define variable temperature
set variable temperature 0
# -- Fieldsets - add $ble to enable taip or json fieldset
define fieldset default fields=$io,$ble
# -- Signals - Used prevously defined alias "Kitchen"
define signal sg_hightemp $ble.Kitchen.temperature > 20
define signal sg_lowtemp $ble.Kitchen.temperature <= 20
define signal sg_movement $ble.E7973F682A94.movement > {{$variables.movement}}
# -- Events - trigger only used on the action
define event ev_hightemp group=tracking ack=seq label=hitemp code=70 fieldset=tracking
define event ev_lowtemp group=tracking ack=seq label=lotemp code=71 fieldset=tracking
define event ev_tmpchg group=tracking ack=seq label=tmpchng code=73 fieldset=tracking
define event ev_movement group=tracking ack=seq label=mvnt code=74 fieldset=tracking
# -- Actions
define action ac_hightemp trigger=sg_hightemp
set variable temperature {{$ble.Kitchen.temperature}}
send event ev_hightemp
speak "High temperature detected at {{$variables.temperature}}"
define action ac_lowtemp trigger=sg_lowtemp
set variable temperature {{$ble.Kitchen.temperature}}
send event ev_lowtemp
speak "Low temperature detected at {{$variables.temperature}}"
define action ac_tempchng [email protected]
set variable temperature {{$ble.Kitchen.temperature}}
send event ev_tmpchg
speak "Temperature change to {{$variables.temperature}}"
define action ac_movement trigger=sg_movement
set variable movement {{$ble.E7973F682A94.movement}}
send event ev_movement
speak "Movement detected at {{$variables.movement}}"
Counters
Syrus has built-in counters that include counts for common metrics such as:
- Total Distance Traveled
- Total Ignition ON Time
- Total Time While Idling
- Total Time Overspeeding
- etc...
Syrus can also build counters based on custom signals, these can be used to count the:
- Number of times a signal occurred
- Accumulated time (total time) in seconds
- Difference in time since last event (delta)
- Traveled distance (total distance) in meters
- Difference in distance since the last event (delta)
Create Built-in Counter
To create a counter that uses the built-in metrics you can define it as follow:
define counters name
This automatically creates an internal count of the following fields.
Field | Description |
---|---|
odometer | Total distance traveled with ignition ON (meters) |
ignition_time | Total ignition time (seconds) |
idle_time | Total time spent in idling (seconds) |
over_speed | Total time spent over speed (seconds) |
over_rpm | Total time spent over RPMs (seconds) |
hard_brakes | Total amount of hard brake events (count) |
harsh_fwd_acceleration | Total amount of harsh forward acceleration events (count) |
distance | Total distance traveled with ignition ON or OFF (meters) |
Initializing
By default, these fields start at 0 but can be initialized from any value on the first time it's defined.
define counters name [odometer] [ignition_time] [idle_time] [over_speed] [over_rpm] [hard_brakes] [harsh_fwd_acceleration] [distance]
Initialize counters
Note that once counters are initialized they can't be modified with the same definition.
# initialize counters define counters globals odometer=0 ignition_time=0 idle_time=0 over_speed=0 over_rpm=0 hard_brakes=0 harsh_fwd_acceleration=0
to modify use the
set commands
You can initialize the values of the counters like this:
# odometer of 23405km and hourmeter of 9502hrs
define counters name odometer=23405000 ignition_time=34207200
Thresholds
The speed, rpm and idling times are controlled by the following threshold values:
Field | Default threshold | Description |
---|---|---|
speed_threshold | 50 | Default units: km/h. The over_speed counter will increase for every second the device is above this speed |
rpm_threshold | 3000 | Default units: rpm. The over_rpm counter will increase for every second the device is above this rpm |
begin_idle_time | 5 | Default units: minutes. The idle_time counter begins to increase after (no movement detected AND ignition ON) for longer than the begin_idle_time - this time is in minutes. |
they can be set when you define the counter as follow:
define counters name [speed_threshold] [rpm_threshold] [begin_idle_time]
define counters name speed_threshold=80 rpm_threshold=3500 begin_idle_time=3
Modify thresholds
You can change the threshold of the counter with set command:
set counters name field=value
set counters name odometer=12345
set counters name speed_threshold=80
Create Custom Counter
When you create a counter for a custom signal Syrus will automatically create an internal count of the following fields.
Field | Description | Units |
---|---|---|
total_count | Total amount of times the signal has been true | Count |
total_time | Total duration that the signal is true | Seconds |
time_increment | Time passed while a signal is true since its last event | Seconds |
total_distance | Total distance traveled while the signal is true | Meters |
distance_increment | Distance passed while a signal is true since its last event | Seconds |
To create a signal counter you just need to define the signal, then create the counter:
# start by defining the signal
define signal sg_in1_on $io.in1
# create a counter for this signal
define counters input1_counts signal=sg_in1_on start=true
Fieldset
The fieldsets can be defined with
field_name:$counters.name.field
# built-in counters for "driver1"
define counters driver1 odometer=50925
# fieldset for driver1
define fieldset driver_1 fields=
distance:$counters.driver1.odometer,
ignition:$counters.driver1.ignition_time
#########
# custom counters for signal: input1_counts
define counters input1_counts signal=sg_in1_on start=true
# fieldset for input1
define fieldset input1_fieldset fields=
total_in1_count:$counters.input1_counts.total_count,
total_in1_duration:$counters.input1_counts.total_time,
total_in1_distance:$counters.input1_counts.total_distance
Transmitting to Pegasus over TAIP
If you are transmitting to Pegasus Gateway you'll need to define the following fieldset fields
Field | TAIP Equivalent |
---|---|
odometer | VO |
ignition_time | CE |
idle_time | CI |
over_speed | CS |
over_rpm | CR |
hard_brakes | Use a CV counter like CV00 , (CV00-CV49 available) |
harsh_fwd_acceleration | Use a CV counter like CV01 , (CV00-CV49 available) |
total_count | Use a CV counter like CV02 , (CV00-CV49 available) |
total_time | Use a CV counter like CV03 , (CV00-CV49 available) |
time_increment | Use a CV counter like CV04 , (CV00-CV49 available) |
total_distance | Use a CV counter like CV05 , (CV00-CV49 available) |
distance_increment | Use a CV counter like CV06 , (CV00-CV49 available) |
define fieldset peg fields=
VO:$counters.driver1.odometer,
CE:$counters.driver1.ignition_time,
CV00:$counters.driver1.hard_brakes,
CV01:$counters.driver1.harsh_fwd_acceleration,
CV02:$counters.input1_counts.total_count,
CV03:$counters.input1_counts.total_time,
CV04:$counters.input1_counts.time_increment,
CV05:$counters.input1_counts.total_distance,
CV06:$counters.input1_counts.distance_increment
Actions
The following actions can be performed over counters:
Action | Description |
---|---|
start | Starts/resumes a counter |
stop | Stops a counter |
reset | Resets counter values back to 0. |
resetall | Resets all counter values back to 0 and changes the thresholds to the default values. |
delete | Deletes a counter definition (make sure it's not being used in a fieldset) |
The format is:
action counters name
These actions can be added to an action definition, for example:
## Built-in Counter Example
# start counters when signal john_connected is detected
define action trigger=john_connected start counters john
# stop counters when signal john_connected is not detected
define action trigger=john_connected,not stop counters john
## Custom Counter Example
# stop custom counter
define action ac_stop_in1_count trigger=sg_in1_count stop counters input1_counts
Signals
You can define signals with the counter values as follow:
## Built-in Counter Example
# signal when the ignition_time reaches 200 hours
define signal hourmeter200 $counters.john.ignition_time > 720000
# signal when the odometer reaches 20km
define signal odometer20km $counters.john.odometer > 20000
# fire respective events
define event hourmeter group=default fieldset=default ack=seq label=200hr code=25 trigger=hourmeter200
define event odometer group=default fieldset=default ack=seq label=20km code=25 trigger=odometer20km
## Custom Counter Example
# signal when a value is reached
define signal sg_input1_duration_limit $counters.input1_counts.total_time >= 60
# signal when number of times is >= 10
define signal sg_input1_amount_of_times $counters.input1_counts.total_count >= 10
Head to the deploy section to see an example showcasing the counters with HoS.
Engine Control Unit (ECU)
The ECU gives you the ability to read any engine parameter that a vehicle reports through its CAN bus interface.
To configure and set up the ECU please visit the management tool section and read the corresponding ECU documentation.
Get Values
Once the ECU is reading data from the CAN bus you can retrieve values with:
get value $ecu.$id
get value $ecu.$name
get value $ecu.fef4_1
get value $ecu.tires_provisioning
The $name
and $id
values come from the ECU directory from the SDK, if the parameter name is not listed then you'll always have the option to use the $id
.
Signals
Signals can be constructed in 2 main ways, either using the name of the parameter along with an operator and a value, or a change using delta parameter.
Using the name along with the operator and value allows you to do things like: detect when the odometer is greater than or equal to 100,000km, while the delta changes allow you to do things like: detect when the fuel value drops by 15% in 2 minutes.
Signals with operators
To construct signals in the traditional way using operators use the same convention as above, either the $name
or $id
from the ECU directory
define signal my_signal $ecu.$id
define signal my_signal $ecu.$name
# signal definition using $id
define signal low_fuel $ecu.fefc_2 < 10
# signal definition using $name
define signal low_fuel $ecu.fuel_level < 10
:::tip 💡 💡
parameters with Count
units are reported in numerical decimal values, for example, seat belt switch
:::
State | Syruslang equivalent | Meaning |
---|---|---|
00 | 0 | NOT Buckled |
01 | 1 | OK - Seat Belt is buckled |
10 | 2 | Error - Switch state cannot be determined |
11 | 3 | Not Available |
# true when the coolant temperature is > 100°C
define signal sg_coolant_temp $ecu.coolant_temp > 100
# true when the oil level is below 20%
define signal sg_oil_level $ecu.oil_level < 20
# true when the vehicle battery is < 8V
define signal sg_battery_power $ecu.battery_power < 8
# true when the the seat belt is buckled
define signal sg_seat_belt_buckled $ecu.seat_belt == 1
Delta changes
To define signals using the deltas (changes) in values, refer to the following section in the ECU development.
It explains how to create a file that allows you to detect changes for particular parameters when the value increases or decreases by X
value in Y
seconds.
Assuming we have the following: ecuparams.conf.json
{
"fefc_2": {
"warnings": [
"delta?time=60&value=10",
"delta?time=120&value=-10"
]
}
}
We can trigger the signals like so:
define signal fuel_refill @ecu_warning.fefc_2.delta?time=60&value=10
define signal fuel_theft @ecu_warning.fefc_2.delta?time=120&value=-10
and trigger the accompanying events like this
define event ev_fuel_theft group=tracking fieldset=default ack=seq label=excsvfl code=90 trigger=fuel_theft
define event ev_fuel_refill group=tracking fieldset=default ack=seq label=flrfl code=91 trigger=fuel_refill
Diagnostic Trouble Codes
The diagnostic trouble codes for the ECU can be constructed using the field: $ecu.error_codes
.
The fields to keep in mind are:
Field | Description |
---|---|
$ecu.error_codes.spn | Suspect Parameter Number |
$ecu.error_codes.fmi | Failure Mode Identifier |
$ecu.error_codes.cm | SPN Conversion Method |
$ecu.error_codes.oc | Occurrence Count |
An example of the fields reported can look like this:
{
...
"$ecu.error_codes.spn": 177,
"$ecu.error_codes.fmi": 3,
"$ecu.error_codes.cm": 0,
"$ecu.error_codes.oc": 126
}
Thus you can use this to construct signals based on specific error codes detected.
# Engine Pre-filter Oil Pressure
define signal spn_oil_pressure $ecu.error_codes.spn == 1208
# FMI Voltage above normal
define signal fmi_voltage_above $ecu.error_codes.fmi == 3
# Event for Engine Oil Pressure Voltage Above Normal
define event engine_oil_pressure_voltage_above_normal group=tracking ack=seq label=diagoilpsi trigger=spn_oil_pressure,fmi_voltage_above,and
Fieldset
When working with TAIP protocol, you can set the fieldset $ecu
and the ECU parameters read will automatically be transmitted as the corresponding TAIP values to an endpoint.
You can also define your own fieldsets
define fieldset default fields="fuel_level":$ecu.fefc_2,"rpm":$ecu.rpm
{
...
"fuel_level": 80,
"rpm": 1430
}
DMS / Fatigue Sensor
The fatigue sensor accessory can alert if a driver is falling asleep, depending on which fatigue sensor you install you could capture photos or videos that can be uploaded to an ftp server.
For more information on video media click here.
Signals
The following table describes the list of signals compatible with all fatigue sensor accessories that Syrus can interact with. Some signals are exclusive to a particular accessory, while some signals are fired by multiple accessories.
Fatigue Signals and Media Supported
Check the Fatigue Sensor's connect page for the accessories that support each type of media.
Normal events
Description | Fatigue Sensor Signal | Photo | Video | Recommended label |
---|---|---|---|---|
Driver fatigue warning (yawning) | @fatigue_sensor.fatigue_warning | ✅ | ✅ | ftgwarning |
Driver fatigue reminder | @fatigue_sensor.fatigue_remind | ✅ | 🚫 | ftgwarning |
Driver fatigue alarm (drowsiness) | @fatigue_sensor.fatigue_alarm | ✅ | ✅ | ftgalarm |
Driver distracted | @fatigue_sensor.distraction | ✅ | ✅ | ftgdistrct |
Driver not detected | @fatigue_sensor.no_portrait | ✅ | 🚫 | ftgnodrivr |
Driver on phone | @fatigue_sensor.phone | 🚫 | ✅ | ftgcamphon |
Driving with no seatbelt | @fatigue_sensor.seatbelt_off | 🚫 | ✅ | ftgnosblt |
Driver smoking | @fatigue_sensor.smoking | 🚫 | ✅ | ftgcamsmok |
Driver identified | @fatigue_sensor.driver_identified | 🚫 | ✅ | ftgdrvid |
Driver changed | @fatigue_sensor.driver_changed | 🚫 | ✅ | ftgdrvchg |
Driver unknown | @fatigue_sensor.unknown_driver | 🚫 | ✅ | ftgukwdrv |
Driver missing | @fatigue_sensor.driver_missing | 🚫 | ✅ | ftgdrvmis |
Camera blocked | @fatigue_sensor.camera_blocked | 🚫 | ✅ | ftgcamblck |
Ignition ON | @fatigue_sensor.ignition_on | 🚫 | ✅ | ftgignon |
Ignition OFF | @fatigue_sensor.ignition_off | 🚫 | ✅ | ftgignoff |
Tamper alert | @fatigue_sensor.tamper_alert | 🚫 | ✅ | ftgtamper |
Photo captured | @fatigue_sensor.photo | ✅ | 🚫 | ftgphoto |
Diagnostic events
Compatible with Cipia FS-10 DMS only
Note that by default the fatigue diagnostic events come with no video or photo evidence, to add it you have to edit the camera's configuration.
"SystemBootFailure": {
"Activation": true,
"FeedbackAudio": true,
"FeedbackOutput": false,
"FeedbackSpeech": false,
"FeedbackVisual": true,
"ReportEvent": true,
"ReportFootage": false, # set to true to record a video
"ReportImage": false # set to true to capture an image
}
Description | Fatigue Sensor Signal | Photo | Video | Recommended label |
---|---|---|---|---|
Device successful system tests after bootup | @fatigue_sensor.system_boot | 🚫 | 🚫 | ftgsboot |
Detection of any error in built-in system tests after boot | @fatigue_sensor.system_boot_failure | 🚫 | 🚫 | ftgsbootfl |
Recovery from any system error code | @fatigue_sensor.system_ok | 🚫 | 🚫 | ftgok |
Generated post system boot after a self-reset event. | @fatigue_sensor.system_reset | 🚫 | 🚫 | ftgsrst |
System boot failure due to Embedded Multimedia Card | @fatigue_sensor.system_error.emmc_failed | 🚫 | 🚫 | ftgerr |
Camera detected an overexposure (note that this can be considered tampering) | @fatigue_sensor.system_error.over_exposure | 🚫 | 🚫 | ftgtamper |
Camera detected a blurred_image (note that this can be considered tampering) | @fatigue_sensor.system_error.blurred_image | 🚫 | 🚫 | ftgtamper |
Camera is not calibrated | @fatigue_sensor.system_error.device_not_calibrated | 🚫 | 🚫 | ftgerrcal |
Camera power lost | @fatigue_sensor.system_error.power_lost | 🚫 | 🚫 | ftgpwrloss |
Camera mcu upgraded ok | @fatigue_sensor.system_error.mcu_upgrade_ok | 🚫 | 🚫 | ftgok |
Camera shifted locations | @fatigue_sensor.system_error.device_shifted | 🚫 | 🚫 | ftgshft |
Camera cable disconnected | @fatigue_sensor.system_error.cable_disconected | 🚫 | 🚫 | ftgdisc |
Camera over heating | @fatigue_sensor.system_error.overheat | 🚫 | 🚫 | ftgerr |
Camera lost gps | @fatigue_sensor.system_error.gps_loss | 🚫 | 🚫 | ftgnogps |
Camera sd card malfunction | @fatigue_sensor.system_error.sdcard_hw_malfunction | 🚫 | 🚫 | ftgerr |
Fieldsets
The fatigue sensor fields can be added with $fatigue_sensor
for json protocol, if you're using taip there's no need to add fieldsets as it is done automatically whenever a photo is captured.
Sample payload
{
"fatigue_sensor": {
"state": "connected",
"sensitivity": 3,
"speaker_volume": 2,
"min_speed": 10,
"speeding": 50,
"max_photos": 50,
"nbr_photos": 24,
"latest_photo": "1616442180-photo.jpeg"
}
}
When using the CAN bus interface the sample payload will look like this
{
"$ecu": {
"yawning": 1,
"drowsiness": 0,
"distraction": 0,
"driver_absence": 0,
"phone": 0,
"smoking": 0,
"camera_blocked": 0,
"fefc_2": 10
...
}
}
You can also build a payload to include fatigue sensor information
define fieldset fatigue fields=fatigue_alert:$ecu.fatigue_drowsiness
Events
Fatigue sensor events can have media such as a photo or video clip attached to it.
Photos
To specify a photo use the photo
param on the event definition:
photo=photo_source
where photo_source
can be
fatigue_sensor
- for the last photo captured by the fatigue sensorfatigue_sensor.fatigue_remind
fatigue_sensor.fatigue_warning
fatigue_sensor.fatigue_alarm
fatigue_sensor.no_portrait
fatigue_sensor.distraction
fatigue_sensor.photo
Example events:
define event any_photo group=tracking
ack=seq label=ftgphoto
photo=fatigue_sensor
[email protected]_sensor.signal
define event distracted group=tracking
ack=seq label=ftgdistrct
photo=fatigue_sensor.distraction
[email protected]_sensor.distraction
define event nodriver group=tracking
ack=seq label=ftgnodrivr
photo=fatigue_sensor.no_portrait
[email protected]_sensor.no_portrait
Videos
Refer to the Fatigue Sensor Comparison to see the compatible video events per accessory.
To attach a video clip to an event for Cipia FS-10 or Movon MDSM7 sensors you need to define the event with the signal trigger that you need, and attach it to a video with $fatigue_sensor.media.event
# Fatigue Sensor (Manufacturer: Cipia, Model: FS-10)
# Fatigue Sensor (Manufacturer: Movon, Model: MDSM-7)
##NOTE: video is attached with $fatigue_sensor.media.event
define event ev_fatigue_alarm_video group=tracking
ack=seq label=ftgalrmvid code=88
fieldset=default
video=$fatigue_sensor.media.event
[email protected]_sensor.fatigue_alarm
define event ev_fatigue_phone_use group=tracking
ack=seq label=ftgphonvid code=89
fieldset=default
video=$fatigue_sensor.media.event
[email protected]_sensor.phone
# --
# Fatigue Sensor (Manufacturer: Cipia, Model: FS-10)
## NOTE: this event is exclusive for this sensor ^
define event ev_fatigue_driver_changed_video group=tracking
ack=seq label=ftgdrvchng code=90
fieldset=default
video=$fatigue_sensor.media.event
[email protected]_sensor.driver_changed
# Send a delayed video clip (waits for an ack from the server to upload it)
define event ev_fatigue_driver_distraction group=tracking
ack=seq label=ftgdistrct code=91
fieldset=default
video=$fatigue_sensor.media.event
upload=ondemand
[email protected]_sensor.distraction
Videos and Photos
You can capture both a video and a photo by specifying both on the event as follow.
This is compatible with the Cipia FS-10 camera, and you must specify in the camera's configuration that you want to capture both video and photo.
# DMS Camera (Manufacturer: Cipia, Model: FS-10)
define event ev_fatigue_alarm group=tracking
ack=seq label=ftgalarm code=92
fieldset=default
video=$fatigue_sensor.media.event
photo=fatigue_sensor.fatigue_alarm
[email protected]_sensor.fatigue_alarm
# --
# DMS Camera (Manufacturer: Cipia, Model: FS-10)
# Fatigue tampering detection
# photo uploaded automatically
# video uploaded on demand (requires an ack from the server to upload it)
define event ev_fatigue_tamper group=tracking
ack=seq label=ftgtamper code=93
fieldset=default
video=$fatigue_sensor.media.event
photo=fatigue_sensor.fatigue_alarm
upload=ondemand
camera=cipia
[email protected]_sensor.tamper_alert
Actions
Fatigue sensor actions allow you to configure some fatigue sensor's parameters, or help you capture videos.
For the serial interface fatigue sensor accessory these are the list of compatible commands you can add to an action:
Command | Description |
---|---|
capture fatigue_sensor photo | Captures a photo with the fatigue sensor camera |
upload fatigue_sensor photos | Manually upload all photos to an ftp destination |
set fatigue_sensor sensitivity | Change sensitivity (Range: 2-11) |
set fatigue_sensor speaker_volume | Change the speaker volume (Range: 0-2) |
set fatigue_sensor minimum_speed | Change the minimum speed to trigger fatigue alerts (Range: 10-60)kph |
set fatigue_sensor speeding_alarm | Change the speeding alarm (Range: 0-255)kph |
set fatigue_sensor buffer_size | Change the max photos that can be captured (Range: 10-100) |
set fatigue_sensor autoupload | Manage the auto upload of photos to the DCT ftp directory, default is 0 |
clear fatigue_sensor buffer | Deletes all photos in the fatigue_sensor directory |
For the ethernet interface fatigue sensor accessory you can capture a video using an action with the create video
command.
The create video command takes two parameters, the name of the video --name=
(it's useful to have a timestamp as the start of the name of the video clip, $gnss.timestamp
) and --time_win
which is the time window back and forward in seconds to record a clip for.
# Ethernet Fatigue Sensor (Manufacturer: Movon, Model: MDSM-7)
define action ac_fatigue_alarm_drowsiness [email protected]_sensor.fatigue_alarm
create video --name={{$gnss.timestamp}}-drowsiness --time_win=-5,+5
define action ac_fatigue_distraction [email protected]_sensor.distraction
create video --name={{$gnss.timestamp}}-distraction --time_win=-5,+5
define action ac_fatigue_warning_yawning [email protected]_sensor.fatigue_warning
create video --name={{$gnss.timestamp}}-yawning --time_win=-5,+5
define action ac_fatigue_phone [email protected]_sensor.phone
create video --name={{$gnss.timestamp}}-phone --time_win=-5,+5
define action ac_fatigue_smoking [email protected]_sensor.smoking
create video --name={{$gnss.timestamp}}-smoking --time_win=-5,+5
define action ac_fatigue_cam_blocked [email protected]_sensor.camera_blocked
create video --name={{$gnss.timestamp}}-cam_blocked --time_win=-5,+5
Fuel Sensor
The Fuel Sensor feature is available through a serial accessory that's capable getting fuel readings and take actions over the values.
Signals
The signals that can be triggered include one-shot and states
signal | description |
---|---|
@fuel.event | Triggered when any fuel event is detected |
@fuel.state | Triggered when a state arrives |
@fuel.fueling | Triggered when a fueling notification arrives |
@fuel.warning | Triggered when a discharge warning notification arrives |
@fuel.connected | Triggered when a transition from disconnected to connected is detected |
@fuel.disconnected | Triggered when a transition from connected to disconnected is detected |
$fuel.connected | Stores the last connected state (boolean) |
$fuel.level | Stores the last fuel level (number) |
$fuel.temperature | Stores the last temperature level (number) |
$fuel.frequency | Stores the last frequency (number) |
$fuel.timestamp | Stores the last notification timestamp (epoch) |
$fuel.event | Stores the last event (string) |
# possible fuel theft event
define event fuel_theft group=tracking fieldset=default label=fuelloss [email protected]
# low fuel level event
define event low_fuel group=tracking fieldset=default label=lwfuel trigger=$fuel.level < 20
Fuel level
Note that the fuel level units are variable and depend on how the sensor is configured; SyrusJS treats the fuel value as the raw value.
Geofences
Geofences definitions are managed by the apx-geofences tool, up to 3000 of them.
Syruslang will manage 1 namespace.
Geofences can be defined in Syruslang the following format:
# circle
define geofence geofence_name [group=group_name] radius=50mts lon,lat
#polygon
define geofence geofence_name [group=group_name] lon1,lat1 lon2,lat2 lon3,lat3, ...
If no group is defined, the geofences will automatically belong to a group called: default
.
The radius consists of a number, minimum 50 meters or 165 feet, followed by one of the following units mts
, ft
, km
, mile
for meters, feet, kilometers, and miles respectively.
Polygons consists of a minimum 3 coordinate pairs, up to 500 coordinate pairs.
geofence_name & group_name
The name and group of the geofence has to follow these guidelines:
- Case sensitive
- 3 to 50 characters
- 🛑 cannot start with a number!
_
and-
are the only allowed special characters[a-Z0-9][a-Z0-9_-]{3,50}
Once a geofence is defined the event engine evalutes the following signals constantly:
signal | Type | Description |
---|---|---|
$geofences.geofence_name.inside | boolean | True if geofence is inside |
$geofences.geofence_name.time | number | Epoch timestamp of last geofence state change |
$geofences.$groups.group_name.inside | boolean | True if geofence is inside any geofence in the group group_name |
$geofences.$groups.group_name.outside | boolean | True if the geofence is outside all geofences in the group group_name |
There is a also a fixed-signal @last_geofence
which contains the last geofence that was modified, either by entering or exiting:
signal | Type | Description |
---|---|---|
@last_geofence.name | String | Name of the last geofence that was modified |
@last_geofence.state | String | inside or outside state of the last geofence |
@last_geofence.time | Number | Epoch timestamp of the last state change |
geofences:
# two geofences in same group
define geofence hilton_blue_lagoon group=hotels radius=150mts -80.27856,25.78155
define geofence hilton_miami group=hotels radius=165ft -80.18867,25.79092
# one geofence in different group
define geofence dolphin_mall group=malls -80.38476,25.79042 -80.37606,25.79044 -80.37613,25.784339 -80.38449,25.78506
signals
# reference 1 geofence
define signal in_mall_for_30 min_duration=30min $geofences.dolphin_mall.inside
# reference any hotel
define signal in_any_hotel min_duration=20sec $geofences.$groups.hotels.inside
actions
# speak to a paired bluetooth speaker
define action parked_in_mall trigger=in_mall_for_30 speak 'welcome to {{@last_geofence.name}}'
# activate output 2
define action visit_hotel trigger=in_any_hotel set $io.out2 on
events
# entered hotel
define event arrived_at_hotel group=tracking fieldset=default ack=seq label=hotel code=40 trigger=in_any_hotel
# stay in mall
define event in_mall group=tracking fieldset=default ack=seq label=mall code=41 trigger=in_mall_for_30
GNSS (Event Data Recorder)
The GNSS of the Syrus 4 allows you to obtain location information of the device.
One of the important features of the GNSS is the ability to act as a blackbox, allowing you to record second-by-second location data before and after a certain point, this feature is also referred to as Event Data Recorder.
Event Data Recording
In order to record event data second by second you need to use the apx-gps backlog command as part of an action.
To associate the action to an event you need to have a common variable between them.
# action that executes a gps backlog of last 20 seconds and next 5 seconds
define action ac_backlog [email protected]_fwd_acceleration.signal
set variable accel_backlog {{$gnss.timestamp}}-accel_backlog
exec apx-gps backlog create --name={{$variables.accel_backlog}} --time-win=-20,+5
send event ev_ac_backlog
# event that's sent when the backlog is triggered
define event ev_ac_backlog group=tracking
code=60 label=backlog
backlog=$variables.accel_backlog
Note that in TAIP protocol extended tags are not supported yet for the GPS backlog.
IButton
The ibutton is a onewire compatible accessory that is useful for driver identification. It is a key fob with a unique ID allowing you to 'add' or 'authorize' a particular ibutton on the device to take actions with. Note that a total of 500 onewire devices can be defined, this list is shared with the temperature sensor accessory.
The following examples will look at how to use the ibutton to identify drivers, for information on how to connect and configure the ibutton head to our accessories section.
To authorize an ibutton in syruslang use the following format:
add ibutton alias_name id
add ibutton driver1 91000014A0707F01
Once added, you can use the 'whitelisted' signal to take an action when that particular ibutton is presented since it's now authorized
# authorized driver
define signal auth_ibutton $ibutton.connected.whitelisted
# unauthorized driver
define signal unauth_ibutton $ibutton.connected.whitelisted == false
# action to deactivate output1 if driver authorized
define action auth_driver_deactivate_out trigger=auth_ibutton set out1 off
# action to activate output2 if driver is unauthorized
define action unauth_activate_out trigger=unauth_ibutton set out2 on
You may also choose to clear the last known ibutton when the ignition is turned off for example.
# clear last ibutton when ignition is OFF
define action clear_ib trigger=ign_on,not clear ibutton
Fieldset
In order to append ibutton data to your event fields you can use the $ibutton
field for JSON protocol.
define fieldset json_ibutton fields=$ibutton
{
"$ibuttons": [
{
"alias": "driver1",
"id": "123456789012345",
"whitelisted": true,
"connected": true,
"conn_epoch": 1608048266,
"disc_epoch": 1608048273
}
]
}
for TAIP protocol you have two possibilities, either the last value read, or the current value.
define fieldset taip_current_ibutton fields=IB:$ibutton.connected.id
define fieldset taip_last_ibutton fields=IS:$ibutton.last.id
Inputs/Outputs
The device's inputs and outputs can be used to sense the state of things or activate others. For more information on the installation refer to connect docs.
Virtual Ignition
Note that you can virtualize the ignition of the device so that it uses a different signal as the "Ignition" detection.
To virtualize use the apx-io system tool.
# Set virtual ignition with Analog Input 2
# Detects ON when the value is above 5000mV for 5 seconds, OFF when below 5000 for 5 seconds
exec apx-io set virtualign --signal=AN2 --on_threshold=5000 --off_threshold=5000 --on_time=5 --off_time=5
Once set this will allow you to use the io.ign
signal like normal, just that underneath it's being treated as a different signal, also keep in mind that this will affect the counters that depend on this signal.
# the signal for ignition ON would be detected once Analog Input 2 is above 5V for 5 seconds
define signal sg_ignition_on $io.ign == true
# counters affected by the virtual ignition are: odometer, ignition_time, idle_time
define counters name odometer=0 ignition_time=0 idle_time=0
Safe immobilization
You can enable the activation of output 1 safely using the safe-engine-cut-off mechanism - apx-seco.
# enable safe immobilization mechanism
exec apx-seco set --mode=enable
# activate output immediately after ignition is OFF
define signal ignition_off $io.ign == false
define action seco_activate trigger=ignition_off
exec apx-seco set --trigger=enable
# report an event when the output is activated
define signal out1_active $io.out1 == true
define event incoming_message group=tracking
fieldset=default label=out1on code=10 trigger=out1_active
# deactivate the output when an ibutton is presented
define signal auth_ibutton $ibutton.connected.whitelisted
define action ib_out1off trigger=auth_ibutton
exec apx-seco set --trigger=disable
Safe Immobilization on Pegasus
Pegasus application allows you to specify whether you want to instruct the device to activate output 1 in a traditional 'normal' way or send a special instruction that instructs the device to execute a 'safe activation' of output 1. This is called Safe Engine Cut Off mechanism, more info here.
When Pegasus instructs the Syrus to activate output 1 via the safe immobilization mechanism a special variable in Syruslang is activated:
$safe_immo
, this variable can be used as a signal to fire custom logic to activate the output 1 based on your own criteria for 'safe immobilization'.An example would be once the flag is detected as true, waiting a certain amount of time for the vehicle to remain under speed limit and the accelerometer to detect no movement for the output to effectively take effect.
define signal safeimmo $variables.$safe_immo == 1 # ... # Custom logic to meet conditions for activating output 1 # ... define action applysafeimmo trigger=safeimmo,logic_result_signal,and set out1 on define action removesafeimmo trigger=logic_result_signal,not,safeimmo,not,and set out1 off # if a customer cancels an active safeimmo you can also use the safeimmo signal to make sure the output is restored define action cancelsafeimmo trigger=safeimmo,not set out1 off
Jamming
Jamming refers to the deliberate blocking or interference with wireless communication signals. Syrus can detect jamming with built in signals:
Signals
@modem.jamming_detected
- Triggered when a jamming condition is detected@modem.jamming_persistence
- Triggered when the jamming condition persist for one minute@modem.jamming_ended
- Triggered when the jamming action stops
States
$modem.jamming.state
- The jamming state [JAMMED
|NOT_JAMMING
]$modem.jamming_detected
- The jamming state [ true | false ]$modem.jamming_persistence
- The persistence flag state [ true | false]$modem.jamming_ended
- The ended flag state [ true | false ]
Events
define event ev_jamming group=tracking fieldset=tracking
ack=seq label=jammed code=90
[email protected]_detected
define event ev_jampers group=tracking fieldset=tracking
ack=seq label=jampers code=91
[email protected]_persistence
define event ev_not_jamming group=tracking fieldset=tracking
ack=seq label=jammend code=92
[email protected]_ended
MDT
MDT or Mobile Data Terminal is a mode that the Syrus can be configured in which allows you to receive data via the device's rs-232 serial port, encapsulate it and send it to a destination.
To get started make sure you follow the installation instructions in our connect page.
Once you have the serial accessory connected and it's transmitting data periodically via the serial port you can configure an event upon an incoming mdt message with the following signal @mdt.message
.
Note, it's recommended that you do not mix this with other signals
define event incoming_message group=mdt fieldset=default code=0 [email protected]
When a message is received the event will generate and the data appended to a json message will come in $mdt
message
{
"$mdt": {
"message": "68656c6c6f20776f726c64"
}
}
For TAIP protocol you don't need to add the field, as long as you define the event with @mdt.message
it will generate and send to the server.
Actions
You can set the MDT settings with the set mdt
command, and send a message with send mdt message
set mdt '115200 x 1 5 0 0 0 0'
define action ignition_on_send_msg trigger=sg_ign_on send mdt message '0304020d0a'
People Counting
Actions and Signals List, System Tool
The people counting camera counts how many people enter and exit a given area with the help of an overhead camera.
You can build signals to count the amount of adults and children that have entered and exited giving you a total head count and take actions over it.
Events
The signals can be used to build an event whenever something specific occurs.
Possible signals
signal | description | recommended label |
---|---|---|
@people.adult_enter | Adult entered | pcenter , pcadltent |
@people.adult_exit | Adult exited | pcexit , pcadltxit |
@people.children_enter | Child entered | pcenter , pchldent |
@people.children_exit | Child exited | pcexit , pchldxit |
@people.start | People counting started | pcstrt |
@people.stop | People counting ended | pcstp |
@people.restarted | People counting camera restarted | pcrst |
@people.cam_connected | Camera connected | pcrstd |
@people.cam_disconnected | Camera disconnected | pcloss |
@people.daily_report | Daily report generated | pcdlyrprt |
@people.weekly_report | Weekly report generated | pcwkrprt |
Note that the daily and weekly report are generated automatically by the camera and they trigger these signals. It can be useful to know that the camera is operating correctly.
# adult or child entered send an event
define event ev_person_entered group=tracking fieldset=default
ack=seq label=pcenter code=50
[email protected]_enter,@people.children_enter,or
# child entered send an event
define event ev_person_entered group=tracking fieldset=default
ack=seq label=pchldent code=51
[email protected]_enter
# people count started or restarted
define event ev_pc_cam_start group=tracking fieldset=default
ack=seq label=pcstart code=52
[email protected],@people.restarted,or
# alert if camera is disconnected
define event ev_pc_cam_disconnected group=tracking fieldset=default
ack=seq label=pcdscnt code=53
[email protected]_disconnected
# camera ping
define event ev_pc_daily_report group=tracking fieldset=default
ack=seq label=pcdlyrprt code=54
[email protected]_report
Fieldsets
The states for the passenger counting camera keep counts of the amount of people inside, or outside.
states | description |
---|---|
$people.event | Last people counting event |
$people.adult.enter | Adults entered |
$people.adult.exit | Adults exited |
$people.children.enter | Children entered |
$people.children.exit | Children exited |
$people.adults_inside | Adults inside |
$people.children_inside | Children inside |
$people.global_adult.enter | Total adults entered |
$people.global_adult.exit | Total adults exited |
$people.global_children.enter | Total children entered |
$people.global_children.exit | Total children exited |
To report the values of the people counting camera you can use the raw json field, or if you're using Pegasus use a CV
counter.
# define a fieldset for Pegasus with all possible people counts in CV fields
define fieldset default fields=
CV40:$people.adult.enter,
CV41:$people.adult.exit,
CV42:$people.children.enter,
CV43:$people.children.exit,
CV44:$people.global_adult.enter,
CV45:$people.global_adult.exit,
CV46:$people.global_children.enter,
CV47:$people.global_children.exit
define fieldset json fields=$people.event
Actions
# if the count of people reaches a value generate a voice note
# signal for amount of people
define signal lucky_number $people.global_adult.enter >= 1000
# action to take after it reaches value
define action congrats trigger=lucky_number
speak 'Congratulations on being our one thousand passenger'
Script with time windows
Another example is to use time windows to trigger the start and stop of people counting.
# Timewindow from 08:00 to 17:00 (M-F)
define window working_hours
from=08:00:00 to=17:00:00 days=0,1,1,1,1,1,0
enabled=true state=false tz=America/NewYork
define action start_working [email protected]_hours.start
exec apx-ndm-pc start
define action end_working [email protected]_hours.end
exec apx-ndm-pc stop
exec apx-ndm-pc reset
define event ev_start group=tracking fieldset=default
[email protected]_hours.start
ack=seq label=strtwrk code=10
define event ev_stop group=tracking fieldset=default
[email protected]_hours.end
ack=seq label=endwrk code=11
Power Save Mode
Power save mode is a low power consumption state that the device can enter automatically after it meets specific criterias based on time and GPIO status. This is important for Syrus devices installed in vehicles that need to conserve energy after the vehicle's ignition switch is OFF.
By default the device enters power save mode after 5 minutes of no ignition being detected.
The actual programming of the power save mode can be done locally on the device or remotely in the Syrus Cloud profile page.
This section describes the available signals and actions that you can take for the power saving mode.
Get
To get the current power save mode value use:
get power_save mode
The device will respond with the PSM_string, example: "IGN:0;IGN;300"
Signal
You can use the following signals to trigger events for when the device goes to sleep and wakes up: @power_save.sleep
, @power_save.wakeup
define event sleeping group=default ack=seq label=slp [email protected]_save.sleep
define event awake group=default ack=seq label=wake [email protected]_save.wakeup
as well as individual signals like @power_save.time
or @power_save.motion
define event wake_by_time group=default ack=seq label=wake [email protected]_save.time
define event wake_by_motion group=default ack=seq label=wake [email protected]_save.motion
Action
You can also start the power saving mode as part of an action, in order to trigger the power save mode when you want.
define action gotosleep trigger=inside_geofence,parked,and set power_save immediate
Note that when you do an immediate power save the device will wake up according to the wakeup_condition and use the wait_time again to go back to sleep.
Fieldset
You can configure the following fieldsets to send you relevant information on a payload
$power_save.mode
- appends the current power save mode string
$power_save.status
- true when the power save mode is ON
$power_save.reason
- appends the reason for waking up
{
...
"power_save.mode": "IGN:0;IGN;300",
"power_save.status": true,
"power_save.reason": "ign"
}
RFID
The RFID feature is available through a serial accessory that's capable of reading an RFID card and take actions over it.
Similar to the ibutton the rfid can also be used to identify drivers.
To authorize an rfid in syruslang use the following format:
add rfid --alias=alias_name --id=id
add rfid --alias=driver1 --id=1234567890
Once added, you can use the 'alias or id' signal from the last rfid read to take an action.
# authorized rfid
define signal sg_auth_rfid $rfid.last.whitelisted
# unauthorized rfid
define signal sg_unauth_rfid $rfid.last.whitelisted == false
# action to deactivate output1 if rfid is authorized
define action auth_rfid_deactivate_out trigger=sg_auth_rfid set out1 off
# action to activate output2 if rfid is unauthorized
define action unauth_rfid_activate_out trigger=sg_unauth_rfid set out2 on
Fieldset
In order to append RFID data to your event fields you can use the $rfid
field for JSON protocol.
define fieldset json_rfid fields=$rfid
{
"$rfid": [
{
"alias": "driver1",
"id": "1234567890",
"whitelisted": true,
"conn_epoch": 1608048266,
}
]
}
for TAIP protocol you have two possibilities, either the last value read, or the current value.
define fieldset taip_current_rfid fields=RI:$rfid.last.id
Note that the RFID value persists unless you specify an action to clear it.
# signal for Ignition OFF
define signal sg_ign_off $io.ign == false
# clear rfid once signal is triggered
define action clear_rfid trigger=sg_ign_off clear rfid
Satcom/Sigfox
The Satcom/sigfox feature is available through accessories that communicate via the serial rs232 interface. With these accesories you're able to send events and communicate with Iridium's™ or Sigfox's networks.
The following examples will look at how to use get started using the satcom or sigfox with syruslang, for information on how to connect and configure the satcom/sigfox head to our accessories section.
The typical usecase here is to use the respective networks as data destinations whenever there's no connectivity available, typically as a backup connectivity solution.
So by default when you create the destination you'll want to set them 'disabled', and 'enable' them when a condition like 'no_connectivity' occurs.
To create the destination use:
save on the destinations.syrus.conf file
define destination satcom_destination taip satcom://_:_ ack=disabled disabled=true
Once defined you can control when to enable these destinations with an action
save on the configuration.syrus.conf file
define action enable_satcom trigger=disconnected enable destination satcom_destination
define action disable_satcom trigger=disconnected,not disable destination satcom_destination
Next, you'll want to configure what disconnected
means, so that signal can look like the following:
# defines disconnected as more than 600 seconds with no connection from the modem
define signal disconnected $modem.no_conn_time > 600
Finally you're able to create events that get sent to the satcom_destination when the device detects that it's disconnected
# create a group for the events
define group satmsgs
# create a fieldset to append satcom information to the event messages
define fieldset satcom_fields fields=$satcom
# event when no connection
define event start_satcom group=satmsgs fieldset=satcom_fields ack=disabled label=stcm code=10 trigger=disconnected
# set destination for satmsgs to satcom destination
set destinations group=satmsgs satcom_destination
Fieldset
The Fieldset compatible with the satcom is $satcom
, for both TAIP & JSON protocols.
TAIP protocol appends the Satcom ID to the message.
>REVXX...;II=300234063907660<
JSON protocol appends the satcom payload.
{
"state": "connected",
"type": "satcom",
"id": "300234063907660",
"signal": 5,
"version": 15,
"buff_size": 50,
"buff_count": 1
}
Commands
The available commands to interact with the satcom are:
set buffer size:
set satcom buffer_size [10-500]
example:
set satcom buffer_size 50
Note that the buffer is circular, where the oldest message is deleted after it reaches the buffer_size
get satcom buffer_size
To clear the buffer you can send
clear satcom buffer
Speak
The speak
command converts text to speech over a paired bluetooth audio handset.
Action
define action my_action trigger=my_signal speak "Text to speak"
You can pass an argument called lang
to specify the language. Supported languages are found in the apx-tts tool, use the first two letters of the language you want to use on the argument.
Example to have the action trigger speak in French language.
define action speak_in_french trigger=my_signal speak lang=fr "Texte pour parler"
Speak with no arguments uses the English language.
Temperature Sensor
Temperature can be read via the onewire (1-wire) cable and compatible temperature sensor probes.
Note that a total of 500 onewire devices/sensors can be defined, so this list is shared with ibutton sensors for example.
To add a temperature sensor via syruslang use the following format:
add temperaturesensor _alias_name id
add temperature_sensor mytemp 8D01144D07DBAA28
You can then use the temperature value of mytemp to create signals and actions
# temperature goes above 0°C
define signal temp_above_threshold min_duration=10sec $temp.aliases.mytemp.value > 0
# action to activate output 2 if threshold reached
define action above_temp_output_on trigger=temp_above_threshold set out2 on
Fieldsets
The fieldset definition for the temperature sensor can be done in JSON format by adding $temp
as a field.
define fieldset temperature fields=$temp
{
"$temp": [
{
"alias": "tempsen1",
"id": "8D01144D07DBAA28",
"value": 22.625,
"connected": true,
"epoch": 1608047806
},
{
"alias": null,
"id": "3C12345D07DBAB29",
"value": 22.437,
"connected": true,
"epoch": 1608047807
}
]
}
The TAIP format for Pegasus Gateway is also supported, up to 3 temperature sensor probes can send data in the following fields: EA_A
, EA_B
, and EA_C
.
To reference the data you can use a temperature sensor alias, or the nth position.
define fieldset taip fields=EA_A:$temp.aliases.temp1.value,EA_B:$temp.aliases.temp2.value,EA_C:$temp.aliases.temp3.value
Timers
Timers can be defined to create conditions based on time for your configuration. For example, you may use timers to count how long an input is activated, or perform an action after certain time has passed.
To define a timer:
define timer timer_name duration [delay] [repeat] [enabled]
parameters | type | description |
---|---|---|
timer_name | string | name of the timer, can be referenced with @timers.timer_name as a signal |
duration | string | duration in #A format, where # is a digit and A represents the unit of time, as soon as this duration expires it will transition the signal to true, valid units are sec , min , hr |
delay | string | optional duration in #A format, this is the amount of time the timer will wait to start counting the duration |
repeat | boolean | optional true if you want the timer to repeat and its signal to transition to 'true' every time it reaches the duration value (false by default) |
enabled | boolean | optional true if the timer is enabled (true by default) |
example timer called timer_name
that waits 5 seconds to start a 10second timer and repeats every 10 seconds.
define timer timer_name duration=10sec [delay=5sec] [repeat=true] [enabled=true]
Given the parameters above, we can define timers to be:
- One-shot: these timers fire once they reach the defined value
- Recycled: these timers fire every time they reach the defined value
One-shot
define timer my_one_shot_timer duration=#A
# create a 5 minute counter
define timer one_shot duration=5min
# event one_time will fire after the timer reaches its value
define event one_time group=default fieldset=default ack=seq [email protected]_shot
# define an action that starts a one shot timer after ignitionOff event
define action start_one_time trigger=ignitionOff set timer one_shot duration=5min
Recycled
define timer my_recycle_timer duration=#A repeat=true
# create a 1 minute counter
define timer recycled duration=2min repeat=true
# event every_time will fire every time the timer reaches its value
define event every_time group=default fieldset=default ack=seq [email protected]
Controlling timers
Timers can be controlled via the following commands
start timer timer_name
stop timer timer_name
These commands can be defined as part of an action, to trigger an event after X minutes of input1 ON for example
define timer timer_name duration=1min
define action start_timer trigger=input1_on start timer timer_name
define action stop_timer trigger=input1_off stop timer timer_name
Here's a more elaborate example that you can use to trigger an output activation after the ignition is ON, until a valid ibutton is presented
# create timer for unauthorized
define timer unauthorized duration=15min delay=15sec repeat=true enabled=true
# create signals for ignition, output2 and authorized ibutton
define signal sg_ignition_on $io.ign
define signal sg_output2_on $io.out2
define signal authorized $ibutton.connected.whitelisted
# activate output2 when timer expires and the output is not active
define action output_activate [email protected],authorized,not,sg_output2_on,not,and,and set out2 on
# stop timer and deactivate output2 when an authorized iButton is detected
define action stop_timer trigger=authorized stop timer unauthorized
define action deactivate_output trigger=authorized set out2 off
Time Windows
Time windows allow you to take actions whenever the device is inside a specific time during the day or date within a year.
For example, you can use them to trigger periodic actions at the same time, such as activate an output at midnight every weekend.
To define a new time window you can use
define window CUSTOM_NAME start=DD/MM/YYYY end=DD/MM/YYYY from=HH:MM:SS to=HH:MM:SS days=1,1,1,1,1,1,1 enabled=true
param | description |
---|---|
CUSTOM_NAME | Custom name for the time window (no spaces or special characters allowed) |
start=DD/MM/YYYY | Date to start the time window evaluation, DD/MM/YYYY are 2 digit day, month, and 4 digit year respectively |
end=DD/MM/YYYY | Date to end the time window evaluation, DD/MM/YYYY are 2 digit day, month, and 4 digit year respectively |
from=HH:MM:SS | Time to start the time window evalution, HH:MM:SS are 2 digit hours, minutes and seconds respectively |
to=HH:MM:SS | Time to end the time window evalution, HH:MM:SS are 2 digit hours, minutes and seconds respectively |
days=1,1,1,1,1,1,1 | Day of the week starting on Sunday ending on Saturday, where 0 means inactive and 1 is active |
enabled=true | Enabled by default, but you can set it to false if you want to disable a time-window evaluation |
Signals
Oneshot booleans
- @windows.name.start
- @windows.name.end
States
- $windows.name.in
- $windows.name.out
Example:
# create a time window for weekdays between 00:00 AM and 00:05 AM for the month of Dec 2022
define window start_time
start=01/12/2022 end=31/12/2022
from=00:00:00 to=00:05:00
days=0,1,1,1,1,1,0 enabled=true
# create a signal when the time window starts
define signal sg_started [email protected]_time.start
# fire an event when the time window starts
define event ev_start group=tracking
fieldset=default ack=seq label=started code=10
trigger=sg_started
# fire an event based on the state of the timewindow
# if the timewindow is active it resets a variable that can be used to control the video upload method
# video if harsh braking detected
set variable my_counter 0
# action to reset the counter
define action ac_reset_counter trigger=$windows.start_time.in
set variable my_counter 0
# harsh braking video action
# increments variable by 1
define action ac_hard_braking_video_in
[email protected]_braking.signal,my_counter,not,and
set variable var_hard_braking {{$gnss.timestamp}}-hard_braking
set variable my_counter increment
create video --name={{$variables.var_hard_braking}} --time_win=-7,+3
send event ev_braking_video_auto
# this video is uploaded automatically
define event ev_braking_video_auto group=tracking
ack=seq label=video code=55
fieldset=tracking
video=$variables.var_hard_braking
# harsh braking video action
define action ac_hard_braking_video_out
[email protected]_braking.signal,my_counter,and
set variable var_hard_braking_od {{$gnss.timestamp}}-hard_braking
create video --name={{$variables.var_hard_braking_od}} --time_win=-7,+3
send event ev_braking_video_ondemand
# this video is uploaded ondemand
define event ev_braking_video_ondemand group=tracking
ack=seq label=video code=55
fieldset=tracking
video=$variables.var_hard_braking_od
upload=ondemand
TPMS Sensor
The TPMS feature is available via an accessory that's connected to the vehicle's onboard computer via the Syrus4's ECU module.
To get started make sure your j1939_params file has the PGN FEF4
defined, with the following START_POSITION's: 2, 3-4, 1, 5.1, 5.3, 5.7, 8.1, 8.6.
The list of compatible parameters can be found in the SDK under the ecu directory ECU.d/fef4.json.
PGN+SPN | param_name |
---|---|
fef4_1 | tires_provisioning |
fef4_2 | tires_pressure |
fef4_3-4 | tires_temperature |
fef4_5.1 | tires_sensor_enable_status |
fef4_5.3 | tires_air_leak_status |
fef4_5.7 | tires_temperature_state |
fef4_8.1 | tires_trailer_flag |
fef4_8.6 | tires_pressure_state |
Signals
Signals for the TPMS integration can be defined on a per tire basis, the format is defined as follow:
$ecu.$tires.axle
X
.tireY
.value
Where X
is the axle, Y
is the tire position, and value
is the corresponding value for the previous fields mentioned.
# signals for low pressure and high temperature for front tires
define signal tire_lf_pres $ecu.$tires.axle_1.tire_1.pressure < 80
define signal tire_lf_temp $ecu.$tires.axle_1.tire_2.temperature > 100
define signal tire_rf_pres $ecu.$tires.axle_1.tire_1.pressure < 80
define signal tire_rf_temp $ecu.$tires.axle_1.tire_2.temperature > 100
You can also define signals for particular SPNs related to the tire's condition, for example the sensor_enable_status which uses the following values:
Signal/Sensor Status | Description |
---|---|
0 | Signal missing |
1 | Signal OK |
2 | Not defined |
4 | Not valid, waiting after power-up |
define signal signal_lf_missing $ecu.$tires.axle_1.tire_1.sensor_enable_status == 0
define signal signal_rf_missing $ecu.$tires.axle_1.tire_2.sensor_enable_status == 0
Fixed Signals
A list of fixed signals are predefined that fire whenever a tpms accessory detects a critical condition such as under inflation or air leak in one of the tires.
These signals can be used to fire an immediate action or generate an event:
# action to send an audible alert to a BT speakerphone alerting an air leak detected (rated at 1 fire every 2 hours)
define action air_leak_detected rate=1/2hr [email protected]tpms.tire_leak speak 'Air leak detected on a tire, please pull over'
Refer to the list of possible fixed signals on the ECU components library section
Fieldsets
If you're using taip protocol format you'll just need to add $ecu
as a field to include all the relevant TPMS data.
For json protocol there's 2 general fieldsets to be defined, $ecu
which contains the raw data values and $tpms
which contains the alerts information.
The raw data values format is the following:
"Axle, Tire, Value ; Axle, Tire, Value ; etc.."
Examples:
"tires_provisioning": "2,1,33.00;5,4,84.00;2,3,35.00;1,1,17.00;0,2,2.00;0,1,1.00;1,2,18.00",
"tires_pressure": "2,1,80.00;5,4,276.00;2,3,80.00;1,2,148.00",
"tires_temperature": "2,1,1639.91;5,4,369.41;2,3,-136.38;1,2,21.00",
"tires_sensor_enable_status": "2,1,0.00;5,4,0.00;2,3,0.00",
"tires_air_leak_status": "2,1,3.00;5,4,3.00;2,3,3.00;1,1,3.00;0,2,3.00;0,1,3.00;1,2,3.00",
"tires_temperature_state": "2,1,0.00;5,4,0.00;2,3,0.00;1,1,0.00;0,2,0.00;0,1,0.00;1,2,0.00",
"tires_trailer_flag": "2,1,1.00;5,4,1.00;2,3,1.00;1,1,1.00;0,2,1.00;0,1,1.00;1,2,1.0",
"tires_pressure_state": "2,1,0.00;5,4,0.00;2,3,0.00;1,1,0.00;0,2,0.00;0,1,0.00;1,2,0.00",
💡 Note: The units for pressure and temperature values in the json format are kPa and °C
The data is further broken down into a $tpms object, which introduces structure of an array of objects for each alert reported, that corresponds to the tires that meet that particular alert. For example, if multiple tires report critical under pressure you'll receive a json with the following fields
{
"tpms": {
...
"under_inflation_warning": [],
"under_inflation_critical": [
{
"pressure": 103,
"temperature": 100.91,
"provisioning": 33,
"sensor_enable_status": 0,
"air_leak_status": 3,
"temperature_state": 0,
"pressure_state": 0,
"trailer_flag": 1,
"axle_index": "0",
"axle": "1",
"tire": "1"
},
{
"pressure": 99,
"temperature": 100.38,
"provisioning": 35,
"sensor_enable_status": 0,
"air_leak_status": 3,
"temperature_state": 0,
"pressure_state": 0,
"trailer_flag": 1,
"axle_index": "0",
"axle": "1",
"tire": "3"
},
...
]
}
}
define fieldset pegasus fields=$io,$gnss,$net,$ecu
define fieldset raw_ecu fields=ecu:$ecu
define fieldset tpms_alerts fields=tpms:$tpms
define fieldset tpms_under_pressure fields=under_inflated_tires:$tpms.under_inflation_critical
Tracking Resolution
The tracking resolution is a special reporting criteria that can be configured on the device to provide periodic updates based on time, heading change, or distance.
The conditions use a logical OR operator between them and once ANY condition is met the count of the other criterias is reset.
Start by defining a tracking_resolution
define tracking_resolution custom_name [heading] [time] [distance]
The heading, time, and distance fields are optional as long as there's at least 1 defined.
To define use a number #
followed by the corresponding unit
Possible units:
unit | type | Description |
---|---|---|
deg | heading | degrees from North (0), increasing eastwardly, NorthEast (45), East (90), etc. |
rad | heading | radians |
sec | time | seconds |
min | time | minutes |
hr | time | hours |
mile | distance | miles |
ft | distance | feet |
mts | distance | meters |
km | distance | kilometers |
for example 30sec
, refers to time of 30 seconds, 3km
, refers to 3 kilometers.
examples
# standard tracking resolution of 30 degrees, or 60 seconds, or 500 meters
define tracking_resolution standard 30deg 60sec 500mts
# distance only tracking resolution, every 1km
define tracking_resolution dist_only 1km
Once you define a tracking_resolution
, the following signals transition to true depending on the criteria used for the periodic reporting:
signal | meaning |
---|---|
@trackingresolution._custom_name.signal | True when any metric for trackingresolution _custom_name reaches its periodicity |
@trackingresolution._custom_name.heading | True for trackingresolution _custom_name when heading delta is met |
@trackingresolution._custom_name.distance | True for trackingresolution _custom_name when distance is met |
@trackingresolution._custom_name.time | True for trackingresolution _custom_name when time is met |
just be sure to replace **_custom_name** with the name you used for the trackingresolution
signal | meaning |
---|---|
@trackingresolution._moving.signal | True every 30deg or 60sec or 500 mts |
@trackingresolution._moving.time | True 60 seconds |
All we need to do now is add some actions to set the tracking_resolution to one of the values we defined earlier.
We'll start by creating two signals for when the Ignition is ON and OFF.
define signal ignitionON min_duration=5sec $io.ign == true
define signal ignitionOFF min_duration=5sec $io.ign == false
Now we'll use this on our actions
define action start trigger=ignitionON set tracking_resolution standard 30deg 60sec 500mts
define action end trigger=ignitionOFF set tracking_resolution standard 2hr
Now we have the tracking resolution update every time the ignition is ON and OFF.
Finally we'll create an event to go along with this:
define event track group=tracking ack=seq label=trckpnt code=0 [email protected]_resolution.standard.signal
Variables
Variables can be defined to be later used throughout the configuration.
For example:
define variable my_variable "hello world"
The value of this variable can be accessed with: $variables.my_variable
The value can also be updated with the following instruction:
set variable my_variable "good bye"
Thus it can be used in actions:
define variable person "john smith"
# change the variable person to 'jess johnson'
define action change_person trigger=my_signal set variable person "jess johnson"
# used in a fieldset
define fieldset info fields="driver_name":$variables.person
# as a signal and part of an event
define signal jess $variables.person == 'jess johnson'
define event my_event group=tracking fieldset=info ack=seq label=name trigger=jess,speeding,and
# used in a speak command ('current driver jess johnson')
define action driver_speak trigger=my_signal speak 'current driver {{$variables.person}}'
Video
Whenever a video is captured or generated on Syrus we have to consider 3 essential steps:
A. Generating the video
B. Notifying the server that the video was captured
C. Uploading the video for viewing
A. Video generation
Syrus has 2 main ways to generate video clips:
Video clip generation | Description |
---|---|
1. Syrus instructs camera | Instruction to capture is sent to camera (Ex: network cameras or dashcams) |
2. Camera generates video automatically | Camera auto generates the video (Ex: driver monitoring cameras) |
B. Video notification
Once the video clip is requested we use event definitions for notifying the remote server which video was captured and how to handle the video (whether it needs to be requested, or wait for it to upload automatically).
C. Video upload
Finally, once the video is generated it's stored locally on the device and there are 3 methods we can use to upload it to a remote server:
These methods are defined in the event definition with the upload
param.
Upload methods | Description | Event definition |
---|---|---|
1. Automatically | Video uploaded as soon as it's generated | upload=automatic (default) |
2. Programmed via a trigger | Wait for conditions to meet to upload (Ex: enter a geofence, connects to a specific wifi, etc.) | upload=programmed Under development |
3. On-demand | Remote server / user requests the video manually. | upload=ondemand |
A.1 Syrus instructs camera
In order to instruct a camera to generate a video clip you need to configure an action to create the video clip using the create video
command.
Command | Description | Parameters |
---|---|---|
start recording | starts a video recording | --camera , --resolution |
stop recording | stop recording | --camera , --resolution |
create video | creates a video recording | --name , --camera , --time_win |
Parameters | Description | Example |
---|---|---|
--camera | name of the camera | --camera=driver_cam |
--resolution | video resolution, SD, HD, or FHD | --resolution=HD |
--time_win | time window for video capture, -back,+forward in seconds | --time_win=-10,+5 |
--name | name of the video clip* | --name=my_event_name |
Unique names
It's useful to append a unique value like a timestamp $gnss.timestamp to a video name, that way it's not overwritten
# signal for ignition ON
define signal sg_ignition_on min_duration=5sec $io.ign
# action to capture a video
define action ac_vid_capture
trigger=sg_ignition_on
create video --name={{$gnss.timestamp}}-ign_video --time_win=-3,+3
Note that the start recording
and stop recording
actions are used for generating video clips used for playback generation with Syrus Cloud.
Video recording is ON by default, but can be disabled via an exec
of the apx-video tool:
define action stop_always_recording trigger=ignon exec apx-video always_recording --status=false
A.2 Camera generates video automatically
As mentioned above, this method is for cameras that have the capability of generating video clips on their own. For example, a driver monitoring / fatigue sensing camera that generates video clips automatically when the driver is distracted or fatigued.
Once these clips are generated they can be referenced in the event by using the respective signal:
# Distraction video from driver monitoring / fatigue sensing camera
define event ev_fatigue_driver_distraction group=default
ack=seq label=ftgdistrct code=91 fieldset=tracking
[email protected]_sensor.distraction
video=$fatigue_sensor.media.event
upload=ondemand
For more information see the Fatigue Sensor section.
B. Video notification
Once the video clip is generated you can send an event to the remote server indicating that a video was captured.
This procedure consists of a 2 part definition for cases where Syrus instructs camera (A1)
-
define an action
- add a trigger for firing the action
- create a variable for the video with a unique name based on the trigger fired
- create the video clip with the varilable name from step above and time window backwards and forward
- send an event to the remote server
-
define an event
- set up the event definition fields including acknowledgement, group, fieldset, label, code, etc.
- reference the video variable created in the previous step
- optional define the upload method
# action to capture a video clip 7 seconds before and 3 seconds after a hard braking was detected
define action ac_hard_braking_video
[email protected]_braking.signal
set variable var_hard_braking {{$gnss.timestamp}}-hard_braking
create video --name={{$variables.var_hard_braking}} --time_win=-7,+3
send event ev_braking_video
# this video is uploaded automatically
define event ev_braking_video group=tracking
ack=seq label=video code=55
fieldset=tracking
video=$variables.var_hard_braking
# capture video 7 seconds before and 3 seconds after cornering left is detected
define action ac_cornering_video
[email protected]_left.signal,@accelerometer.cornering_right.signal,or
set variable var_cornering {{$gnss.timestamp}}-cornering
create video --name={{$variables.var_cornering}} --time_win=-7,+3
send event ev_cornering
# this video is uploaded ondemand, meaning it requires an instruction from the remote server
define event ev_cornering group=tracking
ack=seq label=video code=56
fieldset=tracking
upload=ondemand
video=$variables.var_cornering
and a 1 part definition for the cases where Camera generates video automatically (A2)
# Distraction video from driver monitoring / fatigue sensing camera
define event ev_fatigue_driver_distraction group=default
ack=seq label=ftgdistrct code=91 fieldset=tracking
[email protected]_sensor.distraction
video=$fatigue_sensor.media.event
upload=ondemand
Tip: You can use Syruslang commands to enable/disable wifi, ethernet, or hotspot which is required for video cameras
Clips stored on the device can be uploaded to a remote ftp server using LFTP, see the following guide for more information.
C.1 Automatic video upload
By default any event that's created without an upload
method is assumed to be automatic.
# Distraction video from driver monitoring / fatigue sensing camera uploaded automatically
define event ev_fatigue_driver_distraction group=default
ack=seq label=ftgdistrct code=91 fieldset=tracking
[email protected]_sensor.distraction
video=$fatigue_sensor.media.event
C.3 Ondemand video upload
Video clips can be uploaded ondemand whenever you want with upload=ondemand
on an event definition. Note that this feature works only with destination endpoints that communicate with Pegasus IoT Cloud.
# delay upload of a video
define event ev_output group=default
ack=seq label=vidout code=92 fieldset=tracking
video=$variables.sg_out2_video
upload=ondemand
With this flag enabled the server will have to ACK the message by sending a TAIP message back to the Syrus device confirming when it can upload the video.
The sequence of events is as follow:
Camera codes | descriptions |
---|---|
3 | Media upload in progress |
4 | Media upload successfully |
10 | Capture failed |
17 | FTP error in upload |
19 | FTP not configured |
20 | Media available for download |
The TAIP commands that Syrus accepts related to the upload of videos are:
Commands | Description |
---|---|
>SXASCI< | query available media |
>RXASCI AAA,d BBBBBBB, CCCCCCCC< | response available media, where A is an internal number, B is a media ID that's delayed, and C is a normal media ID waiting to be uploaded (does not require ACK) |
>SXASCC< | erase media queue |
>RXASCC< | successfully erased media queue |
>SXASCT A, B< | request to upload video with ID: A , from camera B (V0 is default camera) |
>RXASCT A, B, C< | response to media ID: A , from camera B and C indicates 1 if found |
>>> Commands sent to device
<<< Response from device
# Query list of videos
>>> >SXASCI<
<<< >RXASCI200,d579107701.mp4,d579104702.mp4,579108703.mp4<
# Request to upload video id: 579104702.mp4
>>> >SXASCT579104700,V0<
<<< >RXASCT579001430,V0,1<
# Syrus sends Camera codes indicating the status and the media is uploaded
Recording a Video Clip with the Push of a Button

Press Call Button Twice to Trigger a Video Clip
You can trigger the manual creation of a video clip using a standard push button or a bluetooth speakerphones button.
define action bt_manual_video [email protected]_2x
speak lang=en 'Creating clip'
set variable bt_manual_video {{$gnss.timestamp}}-bt_user
create video --name={{$variables.bt_manual_video}} --time_win=-10,+10
send event ev_bt_manual_video
define event ev_bt_manual_video group=tracking
ack=seq label=btusrvideo code=20
fieldset=tracking
video=$variables.bt_manual_video
Configuration walkthrough
Pegasus Example
For this example we'll be building a basic tracking script that will perform the following:
- Report to Pegasus Destination with TAIP over TCP
- Report the device's inputs/outputs, gnss, network, and counters data
- Event while the ignition is ON with the label:
trckpnt
- Every 45deg, 1min, or 500 meters
- Event while the ignition is OFF with the label:
prdtst
- Every 2hr
- Event with the label
ignon
once the ignition is turned ON - Event with the label
ignoff
once the ignition is turned OFF - Event with the label
panic
once the input 1 is pressed
0. Create a configuration file
- Create a new file on a text editor and save it with name.syrus.conf (for this example we'll use
configuration.syrus.conf
) - The configuration will have all the signals, actions, events, etc. definitions
1. Create the signals for the events
- Once you have the file the first step is to always define the signals we're going to use throughout the script.
define signal sg_ign_on $io.ign == true
define signal sg_ign_off $io.ign == false
define signal sg_in1_on $io.in1 == true
Now we can use sg_ign_on
, sg_ign_off
, sg_in1_on
throughout the configuration to trigger any actions and events.
2. Define tracking resolution
- The next step is to create the tracking resolutions we're going to use for this configuration.
- Since we're going to report two different events based on the ignition state we'll need to define 2 separate tracking_resolutions
define tracking_resolution track_mov 45deg 60sec 500mts
define tracking_resolution track_stop 0deg 120min 0mts
💡 Tip: Notice how the names of the definitions have a reference to the actual definition it's defining in front
3. Create the actions for the tracking resolution
- The tracking resolutions need to be controlled by an action so that we suspend and resume them when the ignition state changes.
- In this case we need the
track_mov
to start whenever the ignition is turned ON, and stop whever it turns OFF, and vice versa: we need thetrack_stop
to start whenever the ignition is turned OFF, and stop whenever the ignition is turned ON. - Actions are controlled by a trigger, which is a combination of the signals we created earlier
- In this case the corresponding actions are:
define action ac_start_ignon trigger=sg_ign_on
set tracking_resolution track_mov 45deg 60sec 500mts
define action ac_stop_ignoff trigger=sg_ign_off
set tracking_resolution track_mov 0deg 0sec 0mts
define action action_start_ignoff trigger=sg_ign_off
set tracking_resolution track_stop 0deg 120min 0mts
define action action_stop_ignoff trigger=sg_ign_on
set tracking_resolution track_stop 0deg 0sec 0mts
4. Create the groups for events and fieldsets
- Before we can define a fieldset and an event, we need to create a group to associate them to.
define group group_default
5. Create the counters for odometer, engine on, idling, etc.
- The counters are required for correct functionality on Pegasus
- You can override the default values for speed threshold, when to begin the idling time, etc.
define counters globals speed_threshold=90
rpm_threshold=3000
begin_idle_time=5
odometer=123456
ignition_time=11043
6. Create the fieldset
- Since we're going to report via TAIP on Pegasus, you're going to want to use the
$io
,$gnss
,$net
, and some specific$counters
fields exclusive for Pegasus so it can work properly.
define fieldset fieldset_default fields=$io,$gnss,$net,VO:$counters.globals.odometer,CE:$counters.globals.ignition_time,CL:$counters.globals.idle_time,CS:$counters.globals.over_speed,CR:$counters.globals.over_rpm
7. Create the events
- We create the events and add a label so that Pegasus can identify them. This step ties the fieldset, group, and signals together. Remember to use the signals we defined in step 1 to create the triggers.
define event event_ignon
group=group_default fieldset=fieldset_default ack=seq
label=ignon trigger=sg_ign_on
define event event_ignoff
group=group_default fieldset=fieldset_default ack=seq
label=ignoff trigger=sg_ign_off
define event event_panic
group=group_default fieldset=fieldset_default ack=seq
label=panic trigger=sg_in1_on
define event event_tracking
group=group_default fieldset=fieldset_default ack=seq
label=trckpnt [email protected]_resolution.track_mov.signal
define event event_parked
group=group_default fieldset=fieldset_default ack=seq
label=prdtst [email protected]_resolution.track_stop.time
8. Create the destination
- Until now, steps 0-7 have all been on the main configuration file, this step requires you to create a new file: destinations.syrus.conf and add the destination definition to that file.
define destination destination_peg1 taip tcp://pegasus1.peginstances.com:5001
- The convention for the url is
pegasus
followed by thepegasus_id
, and the port is 5000 + thepegasus_id
, you can view your pegasus_id in the /api endpoint of your Pegasus Gateway
9. Tie the events generated with the endpoint
- Go back to the main configuration file and set the destination for the group of events we defined earlier.
set destinations group=group_default destination_peg1
- Save that file as configuration.syrus.conf, and the other file (with the single define destination line) as destinations.syrus.conf and it's ready to be uploaded to SyrusJS.
configuration.syrus.conf
with comments:
# signal definitions
define signal sg_ign_on $io.ign == true
define signal sg_ign_off $io.ign == false
define signal sg_in1_on $io.in1 == true
# tracking resolutions
define tracking_resolution track_mov 45deg 60sec 500mts
define tracking_resolution track_stop 0deg 120min 0mts
# actions
define action ac_start_ignon trigger=sg_ign_on
set tracking_resolution track_mov 45deg 60sec 500mts
define action ac_stop_ignoff trigger=sg_ign_off
set tracking_resolution track_mov 0deg 0sec 0mts
define action action_start_ignoff trigger=sg_ign_off
set tracking_resolution track_stop 0deg 120min 0mts
define action action_stop_ignoff trigger=sg_ign_on
set tracking_resolution track_stop 0deg 0sec 0mts
# group
define group group_default
# counters
define counters globals speed_threshold=90
rpm_threshold=3000
begin_idle_time=5
odometer=0
ignition_time=0
# fieldset
define fieldset fieldset_default
fields=$io,$gnss,$net,
VO:$counters.globals.odometer,
CE:$counters.globals.ignition_time,
CL:$counters.globals.idle_time,
CS:$counters.globals.over_speed,
CR:$counters.globals.over_rpm
# events
define event event_ignon
group=group_default fieldset=fieldset_default ack=seq
label=ignon trigger=sg_ign_on
define event event_ignoff
group=group_default fieldset=fieldset_default ack=seq
label=ignoff trigger=sg_ign_off
define event event_panic
group=group_default fieldset=fieldset_default ack=seq
label=panic trigger=sg_in1_on
define event event_tracking
group=group_default fieldset=fieldset_default ack=seq
label=trckpnt [email protected]_resolution.track_mov.signal
define event event_parked
group=group_default fieldset=fieldset_default ack=seq
label=prdtst [email protected]_resolution.track_stop.time
# set destination
set destinations group=group_default destination_peg1
destinations.syrus.conf
with comments:
# pegasus endpoint
define destination destination_peg1 taip tcp://pegasus1.pegasusgateway.com:5001
MQTT Example
For this example we'll send temperature data to an MQTT endpoint:
- Create a temperature sensor (Probe A)
- When temperature of Probe A > 0°C report alert and activate output 2
- When temperature of Probe A <= 0°C report alert and deactivate output 2
- Report temperature data periodically to test.mosquitto.org over mqtt
0. Create a configuration file
- Create a new file on a text editor and save it with name.syrus.conf (for this example we'll use
configuration.syrus.conf
) - The configuration will have all the signals, actions, events, etc. definitions
1. Connect and add the temperature sensor
- Follow the steps on the connect section to read the temperature sensor unique ID
- Add the temperature sensor probe on syruslang
add temperature_sensor probe_a XXXXXXXXXXXXXXXX
2. Create the signals for the actions when the probe reaches a temperature
- It's recommended to use a min_duration to confirm the reading is stable at a certain value
- To reach the temperature sensor we just defined we use $temp.aliases. followed by the name given to the sensor and
.value
to get the temperature value
define signal sg_temp_above_threshold min_duration=10sec $temp.aliases.probe_a.value > 0
define signal sg_temp_below_threshold min_duration=10sec $temp.aliases.probe_a.value <= 0
- We'll need a signal to control the tracking_resolution, which is the periodic report of the temperature sensor
- In this case we can use the power state of the device (remember that the operator and value
== true
is optional when creating the signal)
define signal sg_power_on min_duration=2sec $io.pwr
3. Define the tracking resolution
- The next step is to create the periodic report, for this we create a tracking_resolution
- For this example we'll only use one tracking_resolution at a fixed interval every 20sec
define tracking_resolution tr_periodic 20sec
4. Create the actions for the tracking resolution and temperature output manipulation
- We can use the power state to control the action of the tracking resolution
- In this case if power is detected we can start the tracking resolution, and pause it if power is disconnected
define action ac_start_pwron trigger=sg_power_on set tracking_resolution tr_periodic 20sec
define action ac_stop_pwroff trigger=sg_power_on,not set tracking_resolution tr_periodic 0sec
- For the action of the output 2 control we can use the signals we defined earlier:
sg_temp_above_threshold
&sg_temp_below_threshold
define action ac_out_on_above_temp trigger=sg_temp_above_threshold set out2 on
define action ac_out_off_below_temp trigger=sg_temp_below_threshold set out2 off
5. Create the groups for events and fieldsets
- Before we can define a fieldset and an event, we need to create a group to associate them to.
define group gr_default
6. Create the fieldset
- We're going to want to add temperature, location, and time information to our mqtt payload, to do this we define a field set with those device components
define fieldset fs_default fields=$temp.aliases.probe_a,$gnss.latitude,$gnss.longitude,$timestamp
7. Create the events
- We create the events that trigger when the signals are met
- It's a good idea that we add the power_on signal as an "AND" condition to the temperature threshold
- All events will be tagged with the fields mentioned in the fieldset
fs_default
created earlier
define event ev_pwron group=gr_default fieldset=fs_default ack=seq trigger=sg_power_on
define event ev_pwroff group=gr_default fieldset=fs_default ack=seq trigger=sg_power_on,not
define event ev_temp_above group=gr_default fieldset=fs_default ack=seq trigger=sg_temp_above_threshold,sg_power_on,and
define event ev_temp_below group=gr_default fieldset=fs_default ack=seq trigger=sg_temp_below_threshold,sg_power_on,and
define event ev_periodic group=gr_default fieldset=fs_default ack=seq [email protected]_resolution.tr_periodic.time
8. Create the destination
- Until now, steps 0-7 have all been on the main configuration file, this step requires you to create a new file: destinations.syrus.conf and add the destination definition to that file.
define destination mosquitto json mqtt://test.mosquitto.org:1883 protocol="mqtt" publish="{{$modem.imei}}/pub"
9. Tie the events generated with the endpoint
- Go back to the main configuration file and set the destination for the group of events we defined earlier.
set destinations group=gr_default mosquitto
- Save that file as configuration.syrus.conf, and the other file (with the single define destination line) as destinations.syrus.conf and it's ready to be uploaded to SyrusJS.
configuration.syrus.conf
with comments:
# add temperature sensor probe_a (replace XXXXXXXXXXXXXXXX with sensor id)
add temperature_sensor probe_a XXXXXXXXXXXXXXXX
# create signals for when the temperature is above or less than 0
define signal sg_temp_above_threshold
min_duration=10sec $temp.aliases.probe_a.value > 0
define signal sg_temp_below_threshold
min_duration=10sec $temp.aliases.probe_a.value <= 0
# create a signal for when the power is ON
define signal sg_power_on
min_duration=2sec $io.pwr
# create the periodic resolution every 20 seconds
define tracking_resolution tr_periodic 20sec
# actions to control the periodic report based on the power state
define action ac_start_pwron
trigger=sg_power_on
set tracking_resolution tr_periodic 20sec
define action ac_stop_pwroff
trigger=sg_power_on,not
set tracking_resolution tr_periodic 0sec
# actions to control the output 2 based on the temperature reading
define action ac_out_on_above_temp
trigger=sg_temp_above_threshold set out2 on
define action ac_out_off_below_temp
trigger=sg_temp_below_threshold set out2 off
# create a group to associate multiple events
define group gr_default
# create a list of fields to append to the events generated
define fieldset fs_default fields=$temp.aliases.probe_a,$gnss.latitude,$gnss.longitude,$timestamp
# create the events or alerts that trigger whenever the signals previously defined are met
define event ev_pwron
group=gr_default fieldset=fs_default ack=seq
trigger=sg_power_on
define event ev_pwroff
group=gr_default fieldset=fs_default ack=seq
trigger=sg_power_on,not
define event ev_temp_above
group=gr_default fieldset=fs_default ack=seq
trigger=sg_temp_above_threshold,sg_power_on,and
define event ev_temp_below
group=gr_default fieldset=fs_default ack=seq
trigger=sg_temp_below_threshold,sg_power_on,and
define event ev_periodic
group=gr_default fieldset=fs_default ack=seq
[email protected]_resolution.tr_periodic.time
# set the destination of the group of events gr_default to mosquitto
set destinations group=gr_default mosquitto
destinations.syrus.conf
with comments:
# mqtt endpoint mosquitto where the events from group gr_default will report to
define destination mosquitto json mqtt://test.mosquitto.org:1883 protocol="mqtt" publish="{{$modem.imei}}/pub"
Message broker interaction
SyrusJS uses the redis application message broker to store its signal states and queues.
The possible keys stored are
Message acknowledgments with destinations (type: string)
/data/app_data/<instance_name>_<destination>_ack
Messages in queue waiting to be sent to destination (type: list)
/data/app_data/<instance_name>_peg_queue_<destination>
# current sequential acknowledge number (used with protocol taip and ack=seq), use 'get'
/data/app_data/__cloud_syrusjs_pegasus1_ack
# contains queued events for destinations pegasus1 and mqtt, use 'lrange'
/data/app_data/__cloud_syrusjs_peg_queue_pegasus1
/data/app_data/__cloud_syrusjs_peg_queue_mqtt
# signals and values for all components, use 'hgetall', 'hget'
/data/app_data/__cloud_syrusjs_signals
# boolean state of custom signals, use 'hgetall', 'hget'
/data/app_data/__cloud_syrusjs_signals_states
Examples
# Get the last ACK value
$ redis-cli get /data/app_data/__cloud_syrusjs_pegasus1_ack
# Get the oldest event from a queue
$ redis-cli lrange /data/app_data/__cloud_syrusjs_peg_queue_pegasus1 -1 -1
# Get all signals and values for a syrusjs instance
$ redis-cli hgetall /data/app_data/__cloud_customsignal_signals
# Getting the value of a signal
$ redis-cli hget /data/app_data/__cloud_syrusjs_signals_states isON
"true"
# make sure to escape $ with \ in front when using redis-cli via terminal
$ redis-cli hget /data/app_data/__cloud_syrusjs_signals \$net_wifi.ip_address
"192.168.1.148"
Deleting an event from the queue
Since SyrusJS stores the event data in lists in redis you can use commands like
ltrim
,lrem
, ordel
to remove them. This could be specially useful if there's a Satcom event stuck in queue and the Satcom accessory gets disconnected or stops working for some reason.Note that before executing these commands it's recommended to stop the instance of SyrusJS that you want to apply the changes for.
# amount of events in queue redis-cli llen /data/app_data/__cloud_my_custom_app_peg_queue_satcom_destination # view the last event in queue redis-cli lrange /data/app_data/__cloud_my_custom_app_peg_queue_satcom_destination -1 -1 # delete last syrus event in queue (note it's the first in list but last one to be processed by syrusjs) redis-cli ltrim /data/app_data/__cloud_my_custom_app_peg_queue_satcom_destination 1 -1 # delete all events in queue redis-cli del /data/app_data/__cloud_my_custom_app_peg_queue_satcom_destination # delete a specific event from the list redis-cli lrem /data/app_data/__cloud_my_custom_app_peg_queue_satcom_destination ">REV852195268644-1480847-0714289000118632;ID=867698041094254<" 1 # restart syrusjs to take the changes syrus-apps-manager restart __cloud_my_custom_app
Debugging
Here are some helpful tips that can help you debug your SyrusJS script.
- use
send event
to generate an event and send it to the destinations
send event event_definition
- use
fire signal
to simulate the activation of a signal
fire signal signal_name
- SyrusJS uses the SDK which means it's redis in the background, thus you can monitor the communication of all the device components and debug data this way
redis-cli monitor | grep 'ecu'
- it may be useful to do some logging internally first before you send any payload to a destination
define destination logger file:///data/app_data/syrusjs/output.log
- if you're stuck on a trigger boolean logic, use the device's outputs as signals as these are user manipulated
define event my_event trigger=out1,out2,and,out3,out4,and,or
-
you can view older output & error logs for each instance of syrusjs in the
/data/logs/
directory -
if your application is consuming a lot of data check the
allow_
commands on the destination definition in order to limit which interface each destination is supposed to work at.
Updated 26 days ago