Syrus 4: Generating Segments
This guide explains how to generate, configure, and monitor segments on the Syrus 4 device.
In the Syrus 4G ecosystem, segments refer to logical divisions or functional components of the system. Each segment is a group of related functionalities that work together to achieve a specific goal.
Prerequisites
Before starting, ensure you have:
- Apex version 25.09.1
- (optional) this guide is best followed with both terminal and syrus cloud for the purpose of monitoring output changes
CONFIG FILE
Segments are configured using a JSON file located in /data/users/syrus4g/segments/
Check if the folder exists:
ls -l /data/users/syrus4g/segments/
If missing, create it:
mkdir -p /data/users/syrus4g/segments/
Create/Edit segments.conf.json
segments.conf.json
nano /data/users/syrus4g/segments/segments.conf.json
Paste this example JSON:
[
{
"label": "test",
"trigger": {
"signal": "ign_mot",
"on_duration": 10,
"off_duration": 50
}
},
{
"label": "outactseg",
"trigger": {
"signal": "custom",
"channel": "interface/output/*",
"key": "OUT2",
"on_duration": 0,
"off_duration": 0
}
},
{
"label": "trip",
"trigger": {
"signal": "rpm",
"channel": "ecumonitor/notification",
"key": "fe04_2-2",
"threshold": 400,
"off_duration": 60
},
"custom_variables": {
"deltas": [
{
"channel": "counters/update/counter_segments",
"key": "OVER_RPM"
}
],
"histograms": [
{
"channel": "ecumonitor/notification",
"key": "fe04_1-2",
"ranges": [
[0, 2000],
[3000, 4000]
]
}
]
}
}
]
Save and exit (CTRL + X
, Y
, Enter
).
Dissecting the Segment Configuration JSON
The Segments configuration JSON consists of an array, where each object within the array represents an individual segment. A maximum of 10 segments are allowed.
Please note that there are no spaces or special characters allowed in any of the strings.
Breakdown of Each Field
label
(string):"trip"
: This custom label specifies the name of the segment. It serves as an identifier that can be used to start, stop, or query this segment.
trigger
(object):- This defines the conditions under which the segment starts and stops.
signal
(string):- Specifies the source signal to initiate or terminate the segment. e.g.:
"rpm"
: The segment starts based on engine RPM (Revolutions Per Minute).
- Other possible signal values include:
"ign"
→ based on ignition status."mot"
→ based on motion detection."ign_mot"
→ based on both ignition and motion."by_demand"
→ awaits a tool command to initiate, e.g.,apx-segments start --segment=trip
"custom"
→ you can use any signal whose value is numeric and is transmitted in a JSON string via Redis from its source application.- NOTE: if this signal is selected, a Redis channel, key and a threshold must be included.
- Specifies the source signal to initiate or terminate the segment. e.g.:
on_duration
(integer):- Indicate the persistence time in seconds of the chosen signal in the trigger for the segment to start, by default is 0 secs. e.g.:
"on_duration": 0
which means that it starts immediately
- Indicate the persistence time in seconds of the chosen signal in the trigger for the segment to start, by default is 0 secs. e.g.:
off_duration
(integer):- Indicate the persistence time in seconds of the chosen signal in the trigger for the segment to stop, by default is 0 secs. e.g.:
"off_duration": 5
- Indicate the persistence time in seconds of the chosen signal in the trigger for the segment to stop, by default is 0 secs. e.g.:
threshold
(integer) (mandatory for rpm or custom signal):- Minimum value needed to start the segment if the signal chosen is custom or rpm, by default is 0. e.g.:
"threshold": 400
- Minimum value needed to start the segment if the signal chosen is custom or rpm, by default is 0. e.g.:
channel
(string) (mandatory for rpm or custom signal):"ecumonitor/notification"
: This specifies the Redis channel from which the data will be sourced. In this case, it is monitoring ECU (Engine Control Unit) notifications.
key
(string) (mandatory for rpm or custom signal):"f004_4-5"
: This identifies the specific variable being monitored. The key corresponds to a specific parameter in the ECU data stream (e.g., RPM data).
custom_variables
(object) (optional)
This object is used when you want to include more information in the segment, and it can be of two types: "deltas," whose result will be the difference between the final and initial values of the parameters included in this object, or "histograms," whose result will be a collection of data such as the average, maximum point, and time ranges of the parameters included in this object.deltas
(array) (optional):key
(string):"OVER_RPM"
: This identifies the specific variable being monitored. The key corresponds to a specific parameter in the counters module.
channel
(string):"counters/update/counter_segments"
: This specifies the Redis channel from which the data will be sourced. In this case, it is monitoring the counters associated to the segments module.
histograms
(array) (optional):ranges
(integer array):"ranges": [[0,600],...]
: Defines intervals for analyzing time-based histogram data, these ranges must be set as pairs array.
channel
(string):"ecumonitor/notification"
: This specifies the Redis channel from which the data will be sourced. In this case, it is monitoring ECU (Engine Control Unit) notifications.
key
(string):"fe04_1-2"
: This identifies the specific variable being monitored.
How This Configuration Works
- The segment
"trip"
listens to the Redis channel"ecumonitor/notification"
for updates on the"f004_4-5"
key (likely RPM). - When RPM exceeds 400, the segment is triggered immediately (
on_duration: 0
). - If RPM drops below 400, the system waits 5 seconds before stopping the segment.
APEX TOOL
- To see all options:
apx-segments help
- To list the available segments:
apx-segments list
- To get the current configuration:
apx-segments get_config
- To get the current counters status:
apx-segments get_counters
- To set a custom counters speed (kmph) threshold:
apx-segments set --counters_speed_thr=80
- To set a custom counters RPM threshold:
apx-segments set --counters_rpm_thr=2500
- To enable periodic updates (freq in seconds):
apx-segments set --segment=trip --updates=true --updates_freq=60
- To get the current segment status:
apx-segments status --segment=trip
- To start a segment with by_demand signal:
apx-segments start --segment=trip
- To stop a segment with by_demand signal:
apx-segments stop --segment=trip
MONITORING SEGMENT UPDATES
from main terminal do:
redis-cli -p 7480 psubscribe segments/*
perform the rest of the guide via syrus cloud
SEGMENTS
Check available segments:
apx-segments list
You should see output like:
["test","outactseg","trip"]
Start the segment:
apx-segments start --segment=outactseg
Check segment status:
apx-segments status --segment=outactseg
Expected output if running:
{"state":"active","last_id":123,"last_start_time":1737072014,"updates":true,"updates_freq":30}
If inactive, verify the trigger conditions (e.g., RPM value must exceed 400).
Else, if not running expect:
{"state":"inactive","last_id":null,"last_start_time":null,"updates":false,"updates_freq":0}
Now we are ready to turn on the output...
Do:
apx-io set out2 false
and immediately do
apx-io set out2 true
and once more
apx-io set out2 false
At which point you may pull out the output from the terminal running monitor:
Expected Output
"{\"id\":4,\"label\":\"outactseg\",\"event\":\"stop\",\"time_synced\":true,\"current_gps_qlty\":\"good\",\"timestamps\":{\"start\":1739297729,\"stop\":1739297772},\"coords\":{\"start\":{\"lat\":25.783758,\"lon\":-80.293579,\"alt\":34.13,\"heading\":351.12},\"stop\":{\"lat\":25.783758,\"lon\":-80.293578,\"alt\":34.10,\"heading\":351.10}},\"summary\":{\"distance\":0,\"duration\":43,\"ign_time\":0,\"idle_time\":0,\"over_speed\":0,\"over_rpm\":0},\"speed\":{\"average\":0.10,\"max\":{\"value\":0.10,\"speed\":0.1,\"hdop\":0.8,\"time\":1739297730,\"coord\":{\"lat\":25.783758,\"lon\":-80.293578}}},\"elevation\":{\"uphill\":0,\"downhill\":0,\"constant\":41,\"unavailable\":0},\"accel\":{\"positive\":{\"max\":{\"value\":0.00,\"speed\":0.0,\"hdop\":0.0,\"time\":0,\"coord\":{\"lat\":0.000000,\"lon\":0.000000}}},\"negative\":{\"max\":{\"value\":0.00,\"speed\":0.0,\"hdop\":0.0,\"time\":0,\"coord\":{\"lat\":0.000000,\"lon\":0.000000}}}},\"gps_qlty\":{\"unavailable\":0,\"good\":41,\"bad\":0},\"comm\":{\"no_gprs\":0,\"no_gsm\":0,\"tx\":18161619,\"rx\":48022501}}"
and put it in a python script such as the following:
import json
# Original incorrect JSON string
json_string = '"{\\"id\\":2,\\"label\\":\\"outactseg\\",...}"'
# Remove the outer quotes
clean_json_string = json_string.strip('"')
# Convert to actual JSON
parsed_json = json.loads(clean_json_string)
# Pretty print the JSON
print(json.dumps(parsed_json, indent=4))
which should finally leave us with a properly formatted segment:
{
"id": 4,
"label": "outactseg",
"event": "stop",
"time_synced": true,
"current_gps_qlty": "good",
"timestamps": {
"start": 1739297729,
"stop": 1739297772
},
"coords": {
"start": {
"lat": 25.783758,
"lon": -80.293579,
"alt": 34.13,
"heading": 351.12
},
"stop": {
"lat": 25.783758,
"lon": -80.293578,
"alt": 34.1,
"heading": 351.1
}
},
"summary": {
"distance": 0,
"duration": 43,
"ign_time": 0,
"idle_time": 0,
"over_speed": 0,
"over_rpm": 0
},
"speed": {
"average": 0.1,
"max": {
"value": 0.1,
"speed": 0.1,
"hdop": 0.8,
"time": 1739297730,
"coord": {
"lat": 25.783758,
"lon": -80.293578
}
}
},
"elevation": {
"uphill": 0,
"downhill": 0,
"constant": 41,
"unavailable": 0
},
"accel": {
"positive": {
"max": {
"value": 0.0,
"speed": 0.0,
"hdop": 0.0,
"time": 0,
"coord": {
"lat": 0.0,
"lon": 0.0
}
}
},
"negative": {
"max": {
"value": 0.0,
"speed": 0.0,
"hdop": 0.0,
"time": 0,
"coord": {
"lat": 0.0,
"lon": 0.0
}
}
}
},
"gps_qlty": {
"unavailable": 0,
"good": 41,
"bad": 0
},
"comm": {
"no_gprs": 0,
"no_gsm": 0,
"tx": 18161619,
"rx": 48022501
}
}
Updated 26 days ago