Change battery watcher to Haskell
This commit is contained in:
parent
0c0fb335b8
commit
5a8cd6624c
|
@ -1,32 +1,70 @@
|
|||
{ lib, pkgs, config, ... }:
|
||||
let
|
||||
battery-watch = pkgs.writeScript "battery-watch" ''
|
||||
#!${pkgs.stdenv.shell}
|
||||
inherit (import ../lib/default.nix) writeHaskellScript;
|
||||
battery-watch = writeHaskellScript {
|
||||
name = "battery-watch";
|
||||
libraries = [
|
||||
pkgs.haskellPackages.fdo-notify
|
||||
pkgs.haskellPackages.megaparsec
|
||||
pkgs.haskellPackages.replace-megaparsec
|
||||
];
|
||||
bins = [ pkgs.acpi ];
|
||||
imports = [
|
||||
"DBus.Notify"
|
||||
"Control.Concurrent"
|
||||
"Text.Megaparsec"
|
||||
"Text.Megaparsec.Char"
|
||||
"Text.Megaparsec.Char.Lexer"
|
||||
"Replace.Megaparsec"
|
||||
"Data.Maybe"
|
||||
];
|
||||
} ''
|
||||
criticalLevel = 20 -- percent
|
||||
minutes = 60 * 1000 * 1000 -- threadDelay takes microseconds
|
||||
|
||||
critical_level=20 #percent
|
||||
main = do
|
||||
client <- connectSession
|
||||
let loop = \handleMay -> do
|
||||
batteryStateText <- decodeUtf8 <$> (acpi "-a" |> captureTrim)
|
||||
batteryLevelText <- decodeUtf8 <$> (acpi "-b" |> captureTrim)
|
||||
chargerOnline <- maybe (fail "Couldn‘t get charging state") pure $ parseMaybe onlineParser batteryStateText
|
||||
batteryLevel <- maybe (fail "Couldn‘t get battery level") pure $ parseMaybe levelParser batteryLevelText
|
||||
let NextAction { note = noteMay , delay = delay } = chooseAction chargerOnline batteryLevel
|
||||
handle <- if | Just note <- noteMay -> Just <$> maybe (notify client note) (flip (replace client) note) handleMay
|
||||
| otherwise -> pure handleMay
|
||||
echo ([i|Waiting for #{delay} minutes until next message.|] :: String)
|
||||
threadDelay $ delay * minutes
|
||||
loop handle
|
||||
loop Nothing
|
||||
|
||||
export PATH=$PATH:${pkgs.coreutils}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin
|
||||
data NextAction = NextAction { note :: Maybe Note, delay :: Int }
|
||||
|
||||
while true
|
||||
do
|
||||
if [ "$(${pkgs.acpi}/bin/acpi -a | grep -o off)" == "off" ]; then
|
||||
battery_level=`${pkgs.acpi}/bin/acpi -b | sed 's/.*[dg], //g;s/\%,.*//g'`
|
||||
if [ $battery_level -le $critical_level ]; then
|
||||
${pkgs.libnotify}/bin/notify-send 'Battery level is low!' "Only $battery_level% of the charge remains."
|
||||
else
|
||||
${pkgs.libnotify}/bin/notify-send 'Battery level is discharging!' "Only $battery_level% of the charge remains."
|
||||
sleep 18m
|
||||
fi
|
||||
fi
|
||||
sleep 2m
|
||||
done
|
||||
type Parser = Parsec Text LT.Text
|
||||
|
||||
onlineParser :: Parser Bool
|
||||
onlineParser = not . null . rights <$> sepCap (string "on-line")
|
||||
|
||||
levelParser :: Parser Int
|
||||
levelParser = (maybe (fail "No Number found") pure . listToMaybe . rights) =<< sepCap (decimal <* "%")
|
||||
|
||||
chooseAction :: Bool -> Int -> NextAction
|
||||
chooseAction chargerOnline batteryLevel
|
||||
| chargerOnline = NextAction Nothing 1
|
||||
| batteryLevel <= criticalLevel = mkMsg $ myNote {summary = "Battery is low!"}
|
||||
| otherwise = mkMsg $ myNote {summary = "Battery is discharging!"}
|
||||
where
|
||||
mkMsg = flip NextAction (max 1 (batteryLevel `div` 5)) . Just
|
||||
myNote = blankNote { body = Just $ Text [i|Only #{batteryLevel}% remaining.|]}
|
||||
'';
|
||||
in {
|
||||
|
||||
systemd.user = {
|
||||
services.battery = {
|
||||
Unit = { Description = "Watch battery state and warn user"; };
|
||||
Service = { ExecStart = toString battery-watch; };
|
||||
Service = {
|
||||
ExecStart = "${battery-watch}/bin/battery-watch";
|
||||
Restart = "always";
|
||||
};
|
||||
Install = { WantedBy = [ "graphical-session.target" ]; };
|
||||
};
|
||||
};
|
||||
|
|
|
@ -55,6 +55,7 @@ rec {
|
|||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE ExtendedDefaultRules #-}
|
||||
{-# LANGUAGE MultiWayIf #-}
|
||||
|
||||
import Shh
|
||||
import qualified Prelude
|
||||
|
|
Loading…
Reference in a new issue