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 ... or Required packages installed: syrus-segmentsX
  • (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

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": "interface",
      	"key": "in1"
    	    }
  	  ],
  	  "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

Breakdown of Each Field

Please note that there are no spaces or special characters allowed in any of the strings.

  1. 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.
  2. trigger (object):
    • This defines the conditions under which the segment starts and stops.
    1. 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.
    2. 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
    3. 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
    4. threshold (integer):
      • Minimum value needed to start the segment if the signal chosen is custom or rpm, by default is 0. e.g.:
        • "threshold": 400
  3. 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.
  4. key (string):
    • "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).
  5. ranges(integer):
    • "ranges": [[0,600],...]: Defines intervals for analyzing time-based histogram data, these ranges must be set as pairs array.

    How This Configuration Works

  6. The segment "trip" listens to the Redis channel "ecumonitor/notification" for updates on the "f004_4-5" key (likely RPM).
  7. When RPM exceeds 400, the segment is triggered immediately (on_duration: 0).
  8. If RPM drops below 400, the system waits 5 seconds before stopping the segment.

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
    }
}