use busctl set-property in led group start/stop services

This change replaces `busctl call` with `busctl set-property`
in LED group start and stop service units, aligning with its
intended use.

Tested:

Loaded the image with the changes into qemu:

```
root@bmc:~# busctl get-property xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/fan0_ok xyz.openbmc_project.Led.Group Asserted
b true
root@bmc:~# systemctl status obmc-led-group-start@fan0_ok.service
* obmc-led-group-start@fan0_ok.service - Assert fan0_ok LED
     Loaded: loaded (/usr/lib/systemd/system/obmc-led-group-start@.service; static)
     Active: active (exited) since Thu 2025-08-07 08:27:53 PDT; 47min ago
 Invocation: 3f0768ed25bb4056806304548f2e6759
    Process: 1306 ExecStart=/bin/sh -c busctl set-property xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/fan0_ok xyz.openbmc_project.Led.Group Asserted b true (code=exited, status=0/SUCCESS)
   Main PID: 1306 (code=exited, status=0/SUCCESS)
   Mem peak: 804K
        CPU: 444ms
Aug 07 08:27:51 bmc systemd[1]: Starting Assert fan0_ok LED...
Aug 07 08:27:53 bmc systemd[1]: Finished Assert fan0_ok LED.
root@bmc:~# systemctl stop obmc-led-group-start@fan0_ok.service
root@bmc:~# busctl get-property xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/fan0_ok xyz.openbmc_project.Led.Group Asserted
b true
root@bmc:~# systemctl status obmc-led-group-start@fan0_ok.service
* obmc-led-group-start@fan0_ok.service - Assert fan0_ok LED
     Loaded: loaded (/usr/lib/systemd/system/obmc-led-group-start@.service; static)
     Active: inactive (dead)
Aug 07 08:27:51 bmc systemd[1]: Starting Assert fan0_ok LED...
Aug 07 08:27:53 bmc systemd[1]: Finished Assert fan0_ok LED.
Aug 07 09:15:16 bmc systemd[1]: obmc-led-group-start@fan0_ok.service: Deactivated successfully.
Aug 07 09:15:16 bmc systemd[1]: Stopped Assert fan0_ok LED.
root@bmc:~# systemctl start obmc-led-group-stop@fan0_ok.service
root@bmc:~# busctl get-property xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/fan0_ok xyz.openbmc_project.Led.Group Asserted
b false
```

This shows that the property was successfully modified
via D-Bus using set-property.

Change-Id: I0033c892a3c227aa3c14a013f162f1b00f5ee542
Signed-off-by: William de Abreu Pinho <williamdapinho@gmail.com>
2 files changed
tree: aab4bdb452df74bd55377517e131d9e14c9ce48a
  1. configs/
  2. example/
  3. fault-monitor/
  4. manager/
  5. scripts/
  6. service_files/
  7. subprojects/
  8. test/
  9. .clang-format
  10. .clang-tidy
  11. .gitignore
  12. .linter-ignore
  13. .prettierrc.yaml
  14. .shellcheck
  15. led.yaml
  16. LICENSE
  17. meson.build
  18. meson.options
  19. OWNERS
  20. pyproject.toml
  21. README.md
  22. utils.cpp
  23. utils.hpp
README.md

phosphor-led-manager

This project manages LED groups on dbus. Sometimes many LEDs must be driven together to indicate some system state.

For example, there can be multiple identify LEDs. When the user wants to identify the system, they should all light up together.

Configuration

The configuration can happen via json or yaml.

Configuration: LED Priority

Each LED can have "Priority" as "Blink", "Off" or "On". If this property is defined, it should be defined on each instance of the LED in the config.

When multiple LED groups are asserted and contain the same LED, "Priority" determines the state of the LED.

For example, Group 1 says LED1 should be "Blink", and Group 2 says it should be "On". LED1 will then have the state declared in "Priority".

Configuration: LED Group Priority

Using LED Priority is fine for simple configurations, but when group state needs to always be consistent, Group Priority can be used to enforce the consistent representation.

The Group Priority is optional and a higher priority means that when 2 groups are asserted, the one with highest Priority will be represented consistently. Meaning all its LEDs will have the state as per the configuration.

Configuration Example with Group Priorities (JSON)

Here we prioritize the locating group above the fault group since locating may be required to fix the fault.

So independent of the order that these groups are asserted, if both are asserted, "sys_id" should be in "Blink" state.

The "unrelated" group will have the default group priority of 0.

{
  "leds": [
    {
      "group": "enclosure_identify",
      "Priority": 2,
      "members": [
        {
          "Name": "sys_id",
          "Action": "Blink"
        },
        {
          "Name": "rear_id",
          "Action": "Blink"
        }
      ]
    },
    {
      "group": "fault",
      "Priority": 1,
      "members": [
        {
          "Name": "sys_id",
          "Action": "On"
        },
        {
          "Name": "fault",
          "Action": "On"
        }
      ]
    },
    {
      "group": "unrelated",
      "members": [
        {
          "Name": "rear_id",
          "Action": "On"
        }
      ]
    }
  ]
}

Configuration Example (JSON)

This is our configuration file. It describes 2 LEDs for the 'enclosure_identify' group, with their respective states and duty cycles.

{
  "leds": [
    {
      "group": "enclosure_identify",
      "members": [
        {
          "Name": "pca955x_front_sys_id0",
          "Action": "On",
          "DutyOn": 50,
          "Period": 0,
          "Priority": "Blink"
        },
        {
          "Name": "led_rear_enc_id0",
          "Action": "On",
          "DutyOn": 50,
          "Period": 0,
          "Priority": "Blink"
        }
      ]
    }
  ]
}

Then start the program with

~# ./phosphor-led-manager --config example.json

Dbus interface

When starting the program, our LED group shows up on dbus. Usually there will be many more groups.

$ busctl tree xyz.openbmc_project.LED.GroupManager
`- /xyz
  `- /xyz/openbmc_project
    `- /xyz/openbmc_project/led
      `- /xyz/openbmc_project/led/groups
        `- /xyz/openbmc_project/led/groups/enclosure_identify


$ busctl introspect xyz.openbmc_project.LED.GroupManager /xyz/openbmc_project/led/groups/enclosure_identify
NAME                                TYPE      SIGNATURE RESULT/VALUE FLAGS
...
xyz.openbmc_project.Led.Group       interface -         -            -
.Asserted                           property  b         false        emits-change writable

In the above output, the usual org.freedesktop.* interfaces have been removed to keep it readable.

We can now drive the entire group by setting it's 'Asserted' property on dbus.

$ busctl set-property \
xyz.openbmc_project.LED.GroupManager \
/xyz/openbmc_project/led/groups/enclosure_identify \
xyz.openbmc_project.Led.Group Asserted b true

The program can then use the xyz.openbmc_project.Led.Physical dbus interface exposed by phosphor-led-sysfs to set each LED state.

How to Build

meson setup build
cd build
ninja