Skip to content

Instantly share code, notes, and snippets.

@c5e3
Last active April 11, 2024 21:06
Show Gist options
  • Save c5e3/e0264a546b249b635349f2ee6c302f36 to your computer and use it in GitHub Desktop.
Save c5e3/e0264a546b249b635349f2ee6c302f36 to your computer and use it in GitHub Desktop.
#!/bin/bash
modprobe -r ec_sys
modprobe ec_sys write_support=1
on="\x8a"
off="\x0a"
led(){
echo -n -e $1 | dd of="/sys/kernel/debug/ec/ec0/io" bs=1 seek=12 count=1 conv=notrunc 2> /dev/null
# thx to u/vali20
# https://www.reddit.com/r/thinkpad/comments/7n8eyu/thinkpad_led_control_under_gnulinux/
}
dit(){
led $on
sleep 0.1
led $off
sleep 0.1
}
dah(){
led $on
sleep 0.3
led $off
sleep 0.1
}
morse(){
case $1 in
"0") dah; dah; dah; dah; dah;;
"1") dit; dah; dah; dah; dah;;
"2") dit; dit; dah; dah; dah;;
"3") dit; dit; dit; dah; dah;;
"4") dit; dit; dit; dit; dah;;
"5") dit; dit; dit; dit; dit;;
"6") dah; dit; dit; dit; dit;;
"7") dah; dah; dit; dit; dit;;
"8") dah; dah; dah; dit; dit;;
"9") dah; dah; dah; dah; dit;;
"a") dit; dah;;
"b") dah; dit; dit; dit;;
"c") dah; dit; dah; dit;;
"d") dah; dit; dit;;
"e") dit;;
"f") dit; dit; dah; dit;;
"g") dah; dah; dit;;
"h") dit; dit; dit; dit;;
"i") dit; dit;;
"j") dit; dah; dah; dah;;
"k") dah; dit; dah;;
"l") dit; dah; dit; dit;;
"m") dah; dah;;
"n") dah; dit;;
"o") dah; dah; dah;;
"p") dit; dah; dah; dit;;
"q") dah; dah; dit; dah;;
"r") dit; dah; dit;;
"s") dit; dit; dit;;
"t") dah;;
"u") dit; dit; dah;;
"v") dit; dit; dit; dah;;
"w") dit; dah; dah;;
"x") dah; dit; dit; dah;;
"y") dah; dit; dah; dah;;
"z") dah; dah; dit; dit;;
" ") sleep 0.6;;
#*) echo "done";;
esac
sleep 0.2;
}
parse(){
tmp=$1
for i in $(seq 0 ${#tmp})
do
echo "current letter: ${tmp:$i:1}"
morse ${tmp:$i:1}
done
}
led $off
read -p "enter a word: " input
echo "blinking \"$input\""
parse "$input"
sleep 1
led $on
modprobe -r ec_sys
Copy link

ghost commented May 7, 2018

Cool idea. And this ec_sys kernel module is available where?

@kachini
Copy link

kachini commented May 8, 2018

doesn't work on Fedora27/ Thinkpad L460

@RoelAdriaans
Copy link

https://gist.github.com/c5e3/e0264a546b249b635349f2ee6c302f36#file-thinkmorse-sh-L82 Should be
led $off

ec_sys is a stock kernel module: https://github.com/torvalds/linux/blob/master/drivers/acpi/ec_sys.c
Script has to run as root, input must be lower case.
Tested on T580, works.

@c5e3
Copy link
Author

c5e3 commented May 17, 2018

@hirschnase: it is included in ubuntu, not sure about other distros
@kachini: your os might lack ec_sys too. let me know, if you figure out, how to write raw data to your laptop's gpio without ec_sys

@c5e3
Copy link
Author

c5e3 commented May 17, 2018

@hirschnase: what distro?

@Taki-B
Copy link

Taki-B commented May 19, 2018

Cool! Works fine with opensuse 42.3

@k0nsl
Copy link

k0nsl commented Oct 7, 2019

I cannot get this to work. It runs, sure, but there is no action,

Specifics of this X131e:

k0nsl01@laptop01:~/Documents/scripts$ uname -a
Linux laptop01 5.3.0 #1.linuxlite SMP Mon Sep 16 18:45:00 NZST 2019 x86_64 x86_64 x86_64 GNU/Linux
k0nsl01@laptop01:~/Documents/scripts$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Linux Lite 4.6
Release:	18.04
Codename:	bionic

@c5e3
Copy link
Author

c5e3 commented Oct 7, 2019

not my project, but does this work? https://github.com/RichusX/thinkmorse

@zebreus
Copy link

zebreus commented Apr 11, 2024

If you are using nixos you can have your LEDs permanently blink messages using the following module:

{ pkgs, lib, config, ... }:
{
  options = {
    services.thinkmorse = {
      enable = lib.mkEnableOption "Enable morse on the thinkpad led";
      message = lib.mkOption {
        type = lib.types.str;
        default = "Hello, World!";
        description = "The message to display in morse code";
      };
      devices = lib.mkOption {
        type = lib.types.listOf lib.types.str;
        default = [ "tpacpi::lid_logo_dot" ];
        description = "The devices to use for morse code";
      };
      speed = lib.mkOption {
        type = lib.types.str;
        default = "0.1";
        description = "Duration of a dit in seconds";
      };
    };
  };
  config = lib.mkIf config.services.thinkmorse.enable (
    let
      ditDelay = config.services.thinkmorse.speed;
      thinkmorse = pkgs.writeShellScriptBin "thinkmorse" ''
        #!${pkgs.bash}/bin/bash

        modprobe -r ec_sys
        modprobe ec_sys write_support=1

        led(){
          ${lib.concatStringsSep "\n" (builtins.map (device: ''echo $1 | ${pkgs.coreutils}/bin/tee /sys/class/leds/${device}/brightness'' ) config.services.thinkmorse.devices )}
        }

        dit(){
                led 1
                sleep ${ditDelay}
                led 0
                sleep ${ditDelay}
        }

        dah(){
                led 1
                sleep ${ditDelay}
                sleep ${ditDelay}
                sleep ${ditDelay}
                led 0
                sleep ${ditDelay}
        }

        morse(){
                case $1 in
                        "0") dah; dah; dah; dah; dah;;
                        "1") dit; dah; dah; dah; dah;;
                        "2") dit; dit; dah; dah; dah;;
                        "3") dit; dit; dit; dah; dah;;
                        "4") dit; dit; dit; dit; dah;;
                        "5") dit; dit; dit; dit; dit;;
                        "6") dah; dit; dit; dit; dit;;
                        "7") dah; dah; dit; dit; dit;;
                        "8") dah; dah; dah; dit; dit;;
                        "9") dah; dah; dah; dah; dit;;
                        "a") dit; dah;;
                        "b") dah; dit; dit; dit;;
                        "c") dah; dit; dah; dit;;
                        "d") dah; dit; dit;;
                        "e") dit;;
                        "f") dit; dit; dah; dit;;
                        "g") dah; dah; dit;;
                        "h") dit; dit; dit; dit;;
                        "i") dit; dit;;
                        "j") dit; dah; dah; dah;;
                        "k") dah; dit; dah;;
                        "l") dit; dah; dit; dit;;
                        "m") dah; dah;;
                        "n") dah; dit;;
                        "o") dah; dah; dah;;
                        "p") dit; dah; dah; dit;;
                        "q") dah; dah; dit; dah;;
                        "r") dit; dah; dit;;
                        "s") dit; dit; dit;;
                        "t") dah;;
                        "u") dit; dit; dah;;
                        "v") dit; dit; dit; dah;;
                        "w") dit; dah; dah;;
                        "x") dah; dit; dit; dah;;
                        "y") dah; dit; dah; dah;;
                        "z") dah; dah; dit; dit;;
                        " ") sleep ${ditDelay}; sleep ${ditDelay}; sleep ${ditDelay}; sleep ${ditDelay}; sleep ${ditDelay}; sleep ${ditDelay} ;;
                        #*) echo "done";;
                esac
                sleep 0.2;
        }

        parse(){
                tmp=$1
                for i in $(seq 0 ''${#tmp})
                do
                        echo "current letter: ''${tmp:$i:1}"
                        morse ''${tmp:$i:1}
                done
        }
        led 0
        parse "${config.services.thinkmorse.message}"
        led 0
        sleep 1
      '';
    in
    {
      systemd.services.thinkmorse = {
        enable = true;
        description = "Morse a message on the thinkpad led";
        after = [ "systemd-modules-load.service" ];
        wantedBy = [ "multi-user.target" ];
        serviceConfig = {
          Restart = "always";
          Type = "simple";
          ExecStart = "${lib.getExe thinkmorse}";
        };
      };

    }
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment