thinkpad-led (#329)
* thinkpad-led * Update en.json * Update README with widget information * PR fixes * fix PR
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# ThinkPad Logo LED
|
||||
|
||||
A simple Noctalia bar widget to toggle the ThinkPad lid logo LED on and off.
|
||||
|
||||
## Plugin
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| **ID** | `zeti1223/thinkpad-led` |
|
||||
| **Widget** | `led` |
|
||||
| **Version** | `1.1.0` |
|
||||
| **Author** | zeti1223 |
|
||||
| **License** | MIT |
|
||||
|
||||
## Usage
|
||||
|
||||
Add the `led` widget to your Noctalia bar layout. Clicking the widget toggles the ThinkPad logo LED state.
|
||||
|
||||
* **Left Click**: Toggle LED (ON / OFF).
|
||||
|
||||
## Requirements
|
||||
|
||||
* `sh`
|
||||
|
||||
## Notes
|
||||
|
||||
* **Hardware & Permissions**: This plugin writes directly to `/sys/class/leds/tpacpi::lid_logo_dot/brightness`. Ensure your user account has write permissions to this path (for example, via a `udev` rule), otherwise command execution will fail.
|
||||
@@ -0,0 +1,14 @@
|
||||
id = "zeti1223/thinkpad-led"
|
||||
name = "ThinkPad Logo LED"
|
||||
version = "1.1.0"
|
||||
plugin_api = 3
|
||||
author = "zeti1223"
|
||||
license = "MIT"
|
||||
dependencies = ["sh"]
|
||||
tags = ["bar", "hardware"]
|
||||
icon = "bulb"
|
||||
description = "Turn the ThinkPad lid logo LED on or off."
|
||||
|
||||
[[widget]]
|
||||
id = "led"
|
||||
entry = "widget.luau"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1,101 @@
|
||||
--!nonstrict
|
||||
-- ThinkPad lid logo LED — bar widget
|
||||
-- A red dot in the bar that directly controls the /sys/class/leds/tpacpi::lid_logo_dot LED.
|
||||
-- Left click : toggle on / off
|
||||
|
||||
local LED_PATH = "/sys/class/leds/tpacpi::lid_logo_dot/brightness"
|
||||
|
||||
-- Tri-state: true = on, false = off, nil = unknown (path missing, unreadable, etc).
|
||||
local ledOn = nil
|
||||
local pending = false -- true while a toggle write is in flight
|
||||
local writeFailed = false -- true if the last write attempt did not succeed
|
||||
|
||||
-- Reads the LED brightness straight from sysfs instead of trusting any cached
|
||||
-- guess. Returns nil when the file can't be read (missing device, no
|
||||
-- permissions, etc), which the UI renders as an "unavailable" state.
|
||||
local function readLedState()
|
||||
local contents = noctalia.readFile(LED_PATH)
|
||||
if not contents then
|
||||
return nil
|
||||
end
|
||||
local value = tonumber((contents:gsub("%s+", "")))
|
||||
if not value then
|
||||
return nil
|
||||
end
|
||||
return value > 0
|
||||
end
|
||||
|
||||
local function statusColor()
|
||||
if ledOn then
|
||||
return "error"
|
||||
else
|
||||
return "outline"
|
||||
end
|
||||
end
|
||||
|
||||
local function render()
|
||||
barWidget.render(ui.box({
|
||||
width = 10,
|
||||
height = 10,
|
||||
radius = 5,
|
||||
fill = statusColor(),
|
||||
border = "outline",
|
||||
borderWidth = 1,
|
||||
}))
|
||||
|
||||
if ledOn == nil then
|
||||
barWidget.setTooltip("ThinkPad LED: unavailable (check permissions on " .. LED_PATH .. ")")
|
||||
elseif pending then
|
||||
barWidget.setTooltip("ThinkPad LED: updating…")
|
||||
elseif writeFailed then
|
||||
barWidget.setTooltip("ThinkPad LED: last toggle failed (permission denied?)")
|
||||
elseif ledOn then
|
||||
barWidget.setTooltip("ThinkPad LED: ON (Left click: turn off)")
|
||||
else
|
||||
barWidget.setTooltip("ThinkPad LED: OFF (Left click: turn on)")
|
||||
end
|
||||
end
|
||||
|
||||
function update()
|
||||
if not pending then
|
||||
ledOn = readLedState()
|
||||
end
|
||||
render()
|
||||
end
|
||||
|
||||
function onClick()
|
||||
if pending then
|
||||
return
|
||||
end
|
||||
|
||||
-- Toggle off the actual hardware state, not a guessed one.
|
||||
local current = readLedState()
|
||||
if current == nil then
|
||||
ledOn = nil
|
||||
render()
|
||||
return
|
||||
end
|
||||
|
||||
local target = not current
|
||||
local val = target and "255" or "0"
|
||||
|
||||
pending = true
|
||||
writeFailed = false
|
||||
render()
|
||||
|
||||
local started = noctalia.runAsync(`sh -c "echo {val} > {LED_PATH}"`, function(result)
|
||||
pending = false
|
||||
writeFailed = result.exitCode ~= 0
|
||||
-- Trust the hardware over the write result: read the brightness back
|
||||
-- rather than assuming the echo did what we asked.
|
||||
ledOn = readLedState()
|
||||
render()
|
||||
end)
|
||||
|
||||
if not started then
|
||||
pending = false
|
||||
writeFailed = true
|
||||
ledOn = readLedState()
|
||||
render()
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user