No description
Find a file
2025-10-08 18:56:06 +02:00
.forgejo/workflows Fix GITEA_TOKEN assignment in workflow 2025-10-08 01:54:45 +02:00
cmd Make conservation threshold configurable 2025-10-08 18:34:31 +02:00
packaging Initial commit 2025-10-07 12:23:16 +02:00
vendor add vendor 2025-10-07 14:06:56 +02:00
.gitignore add vendor 2025-10-07 14:06:56 +02:00
.goreleaser.yaml update release workflow and GoReleaser configuration 2025-10-08 01:48:12 +02:00
go.mod Initial commit 2025-10-07 12:23:16 +02:00
go.sum Initial commit 2025-10-07 12:23:16 +02:00
LICENSE Add README and LICENSE 2025-10-08 18:56:06 +02:00
README.md Add README and LICENSE 2025-10-08 18:56:06 +02:00

Conservation Daemon

A simple smart charge controller for Lenovo Yoga/IdeaPad laptops on Linux that handles battery conservation mode to extend battery lifespan, which allows to configure the time to reach a specific battery level (e.g., "charge to 95% by 9:00 AM") using a non-root CLI.

Requirements

  • Linux system with UPower daemon
  • Lenovo laptop with ideapad_laptop kernel module loaded
  • Conservation mode support in /sys/bus/platform/drivers/ideapad_acpi/*/conservation_mode

Installation

Pre-built Releases

Download the latest release from: https://git.marcorealacci.me/marcorealacci/conservation-daemon/releases

Arch Linux (AUR)

# Using your favorite AUR helper
paru -S conservation-daemon-bin
# or
yay -S conservation-daemon-bin

Important

Make sure a group called conservationd exists and add your user to it to allow non-root CLI access.

Build from Source

Prerequisites:

  • Go 1.25 or later

Build:

git clone <repository-url>
cd conservationDaemon
go build -o conservationd ./cmd/daemon   # Builds daemon executable
go build -o conservationctl ./cmd/cli    # Builds cli executable

Usage

Basic Commands

Start the daemon (as root):

sudo systemctl enable --now conservationd

Check current status:

conservationctl
# Output: pct=85.0 state=charging cons=0 max=80.0 time=now

Set immediate charging target:

conservationctl -set -max 90
# Charges to 90%, then enables conservation mode immediately afterwards

Schedule charging for specific time:

conservationctl -set -max 95 -time 9:00
# Will charge to 95% by 9:00 AM tomorrow
# if the specified time is in the past, it assumes the next day

Daemon Options

./conservationd [options]
  -max float
        target maximum percentage (default 80)
  -conservation-threshold float
        battery percentage at which conservation mode activates (default 80)
  -interval duration
        poll interval (default 45s)
  -dry-run
        do not write sysfs, only log actions
  -once
        perform a single control step and exit
  -sysfs string
        explicit conservation_mode path (auto-discovered if empty)
  -sock string
        UNIX control socket path (default "/run/conservationd/conservationd.sock")
  -sock-group string
        group name to own the socket (default "conservationd")
  -version
        print version and exit

CLI Options

./conservationctl [options]
  -set
        set new thresholds and/or time
  -max float
        target maximum percentage (default 80)
  -time string
        target time in HH:MM format (default "now")
  -status
        show detailed status (same as default behavior)
  -sock string
        control socket path (default "/run/conservationd/conservationd.sock")
  -version
        print version and exit

Troubleshooting

Conservation mode file not found:

# Check if ideapad_laptop module is loaded
lsmod | grep ideapad
# Load if missing
sudo modprobe ideapad_laptop

# Find conservation mode file
find /sys -name "conservation_mode" 2>/dev/null

Permission denied on socket:

# Check if user is in conservationd group
groups
# Add user to group if missing
sudo usermod -a -G conservationd $USER
# Log out and back in

Daemon not responding:

# Check daemon status
sudo systemctl status conservationd
# Check logs
journalctl -u conservationd -f

License

MIT License - see LICENSE file for details.

Contributing

Issues and pull requests welcome!