Skip to content

Loading Settings

This tutorial shows how to load device configuration from YAML, TOML, or JSON files and apply it to a Senxor device. Use this to apply the same settings across many devices (e.g. in production).

1. Connect to the device

See the Connect Device tutorial for how to connect to the device.

from senxor import connect, list_senxor

devices = list_senxor("serial")
if not devices:
    raise ValueError("No devices found")

dev = connect(devices[0])

2. Configuration file structure

A settings file has a profiles list. Each profile has:

  • name: profile name (required)
  • desc: short description (optional)
  • when: condition expression (optional); the profile is applied only when it evaluates to true
  • settings: dict of field names or register addresses to values (required)
    • Field names: e.g. EMISSIVITY, FRAME_RATE_DIVIDER
    • Register addresses: e.g. REG_0xB1, REG_23

Example (YAML):

profiles:
  - name: "default"
    desc: "Default settings for general use"
    settings:
      EMISSIVITY: 83
      FRAME_RATE_DIVIDER: 4

  - name: "panther"
    desc: "Settings for Panther modules"
    when: "module_name == 'Panther'"
    settings:
      STARK_ENABLE: false
      EMISSIVITY: 95
      REG_0xD0: 0

Example (TOML):

[[profiles]]
name = "default"
desc = "Default settings for general use"

[profiles.settings]
EMISSIVITY = 83
FRAME_RATE_DIVIDER = 4

[[profiles]]
name = "panther"
desc = "Settings for Panther modules"
when = "module_name == 'Panther'"

[profiles.settings]
STARK_ENABLE = false
EMISSIVITY = 95
REG_0xD0 = 0

Example (JSON):

{
  "profiles": [
    {
      "name": "default",
      "desc": "Default settings for general use",
      "settings": {
        "EMISSIVITY": 83,
        "FRAME_RATE_DIVIDER": 4
      }
    },
    {
      "name": "panther",
      "desc": "Settings for Panther modules",
      "when": "module_name == 'Panther'",
      "settings": {
        "STARK_ENABLE": false,
        "EMISSIVITY": 95,
        "REG_0xD0": 0
      }
    }
  ]
}

TOML and JSON use the same structure; the file type is inferred from the file extension (.yaml, .toml, .json).

3. Load and apply

Use load(path) to read a file and get a dict of profiles by name. Use apply(dev, ...) to apply settings to the device. You can pass a file path, a dict of profiles, or a single profile.

from senxor.settings import load, apply

settings = load("my_settings.yaml")
apply(dev, settings)

Apply directly from a file path:

apply(dev, "my_settings.yaml")

When you apply a dict of profiles, each profile’s when is evaluated with the current device state. Every profile whose when is true is applied, in order (later profiles override earlier ones for the same fields). A profile without when always matches.

4. Condition expressions (when)

The when field is a Python expression. You can use comparison (==, !=, <, >, etc.) and logical operators (and, or, not). Available names:

Name Type Description
frame_shape tuple Frame size, e.g. (120, 160)
mcu_type str MCU type, e.g. "MI48D4"
senxor_type str Senxor type, e.g. "MI0801"
module_type str Module type, e.g. "MI0802-M5S"
module_name "Panther" | "Cougar" | "Cheetah" Module name returned by get_module_name()
fw_version str Firmware version, e.g. "4.5.12"
name str Device name, e.g. "COM3"
field name int Current value of that field

Example: apply different settings by module name and firmware version:

profiles:
  - name: "panther"
    when: "module_name == 'Panther'"
    settings:
      STARK_ENABLE: false
      EMISSIVITY: 85

  - name: "fw_4_5_12"
    when: "fw_version == '4.5.12'"
    settings:
      STARK_ENABLE: true
      EMISSIVITY: 90

  - name: "fw_4_5_newer"
    when: "FW_VERSION_MAJOR > 4 or (FW_VERSION_MAJOR == 4 and FW_VERSION_MINOR > 5)"
    settings:
      STARK_ENABLE: false

5. Load from string, bytes, or file object

Use loads(fp, filetype="yaml") when the config is not from a path: e.g. from a string, bytes, or an open file. Set filetype to "yaml", "toml", or "json".

from senxor.settings import loads, apply

with open("config.yaml", "r") as f:
    settings = loads(f, filetype="yaml")
apply(dev, settings)
config_bytes = b"""
profiles:
  - name: "default"
    settings:
      EMISSIVITY: 83
"""
settings = loads(config_bytes, filetype="yaml")
apply(dev, settings)

6. Apply a single profile

You can apply one profile from the loaded dict:

settings = load("my_settings.yaml")
apply(dev, settings["default"])

Field names and allowed values are the same as when using dev.fields; see the Device Control tutorial and the field definitions in the API reference.