<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Anarch157a's Blog (Posts about Linux)</title><link>https://www.anarch157a.com/</link><description></description><atom:link href="https://www.anarch157a.com/categories/linux.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2026 &lt;a href="mailto:anarch+nospam@replace_this_by_the_blog_domain.com"&gt;Anarch157a&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-NC-SA"
style="border-width:0; margin-bottom:12px;"
src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Wed, 04 Nov 2026 20:27:21 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Listing non-root users with shell</title><link>https://www.anarch157a.com/posts/shell_list_users/</link><dc:creator>Anarch157a</dc:creator><description>&lt;h4&gt;Listing non-root users&lt;/h4&gt;
&lt;p&gt;This is a simple Bash script to list all non-root and non-system users in Linux. Those users
are determined by two settings, &lt;code&gt;UID_MIN&lt;/code&gt; and &lt;code&gt;UID_MAX&lt;/code&gt;, found on the &lt;code&gt;/etc/login.defs&lt;/code&gt;
file.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash -&lt;/span&gt;
&lt;span class="c1"&gt;#===============================================================================&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#          FILE: lista-users.sh&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   DESCRIPTION:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#        AUTHOR: Nerdeiro da Silva &amp;lt;a n a r c h 1 5 7 a  at  n i n j a z u m b i . c o m&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#       CREATED: 01/08/2023 14:14:18&lt;/span&gt;
&lt;span class="c1"&gt;#      REVISION:  0.01&lt;/span&gt;
&lt;span class="c1"&gt;#       LICENSE: GNU GPL 2.X (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html)&lt;/span&gt;
&lt;span class="c1"&gt;#===============================================================================&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;nounset&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="c1"&gt;# Treat unset variables as an error&lt;/span&gt;

&lt;span class="c1"&gt;# Get lowest and highest UID from login.defs&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;min_uid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'/^UID_MIN/{print $2}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/login.defs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;max_uid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'/^UID_MAX/{print $2}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/login.defs&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Use Awk expresisons to list only users between those limits&lt;/span&gt;
&lt;span class="nv"&gt;USERS&lt;/span&gt;&lt;span class="o"&gt;=(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;min_uid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;max_uid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-F:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'$3 &amp;gt;= min &amp;amp;&amp;amp; $3 &amp;lt;= max { print $1}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/passwd&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Users :: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USERS&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt;
&lt;span class="c1"&gt;# Example for loop to do something for each user&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;U&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USERS&lt;/span&gt;&lt;span class="p"&gt;[@]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;USR_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;-F:&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;U&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'$1 == usr {print $6}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/passwd&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USR_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"User: &lt;/span&gt;&lt;span class="nv"&gt;$U&lt;/span&gt;&lt;span class="s2"&gt;; Directory: &lt;/span&gt;&lt;span class="nv"&gt;$USR_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</description><category>Bash</category><category>Linux</category><category>Shell</category><guid>https://www.anarch157a.com/posts/shell_list_users/</guid><pubDate>Tue, 01 Aug 2023 19:00:00 GMT</pubDate></item><item><title>Syncing game saves with almost any cloud service</title><link>https://www.anarch157a.com/posts/game-cloud-saves/</link><dc:creator>Anarch157a</dc:creator><description>&lt;h4&gt;Edit: New version of the script&lt;/h4&gt;
&lt;p&gt;Check the repository on &lt;a href="https://gitlab.com/Nerdeiro/game-cloud-sync"&gt;https://gitlab.com/Nerdeiro/game-cloud-sync&lt;/a&gt; and follow the 
README.md there.&lt;/p&gt;
&lt;h4&gt;Sync your games to (almost) any cloud service&lt;/h4&gt;
&lt;p&gt;This is a simple Bash script to sync your game-saves with pretty much any cloud storage service out there.
It uses &lt;a href="https://rclone.org/"&gt;Rclone&lt;/a&gt;, which supports dozens (&lt;a href="https://rclone.org/#providers"&gt;not hyperbole&lt;/a&gt;) of providers.&lt;/p&gt;
&lt;p&gt;The motivation to create this script was to sync my copy of Stardew Valley between my desktop
and my Steam Deck. But wait, doesn't Steam do this ? Yes, it does, for copies bought on Steam.
But my copy is from GOG...  It runs just fine on the Deck, regardless if it was installed from
a manual download, with Lutris or Heroic, it only lacks cloud saves.&lt;/p&gt;
&lt;p&gt;This is where this script and &lt;a href="https://lutris.net/"&gt;Lutris&lt;/a&gt; come in. The role Lutris will play
here, is to allow us to run a script both before and after running the game, all without having
to change the default &lt;code&gt;start.sh&lt;/code&gt; lancher script that the GOG installer creates.&lt;/p&gt;
&lt;h4&gt;What you need to use this script&lt;/h4&gt;
&lt;p&gt;In no particular order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lutris (optional but recommended)&lt;/li&gt;
&lt;li&gt;Rclone&lt;/li&gt;
&lt;li&gt;A cloud service supported by Rclone&lt;/li&gt;
&lt;li&gt;A working remote configuration in Rclone&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you're syncing between two computers, getting Lutris and Rcloneis as easy as installing them
using your distro's package manager. On the Steam Deck, Lutris have to be installed using
Flatpack, after changing to Desktop mode. Rclone is a little bit more challenging, since it's
not on Flathub and the Deck ships with a read-only Root (/) file-system, so using Pacman
to get it is not an option.&lt;/p&gt;
&lt;p&gt;Thankfully, the creators of Rclone have a statically compiled binary on the official website,
which means you can run it on the Deck without any issues, only you'll have to put it
somewhere on the &lt;code&gt;$HOME&lt;/code&gt; directory. To avoid having to fiddle with the &lt;code&gt;$PATH&lt;/code&gt;, I recommend
that after unziping the downloaded file, you move the &lt;code&gt;rclone&lt;/code&gt; executable to a convenient
place, then edit the script to point the variable &lt;code&gt;RC&lt;/code&gt; to the &lt;strong&gt;full, absolute path&lt;/strong&gt; of the
binary.&lt;/p&gt;
&lt;p&gt;After installing Rclone, follow the official documentation to create a configuration for your
remote cloud service. It's important that you can successfuly run a copy or sync between the
two sides. Lets say that you run &lt;code&gt;rclone copy mycloud:somedir/ ~/tmp/someotherdir&lt;/code&gt;, if the 
command finishes and the files show up in &lt;code&gt;~/tmp/someotherdir&lt;/code&gt;, then you're good to go.&lt;/p&gt;
&lt;h4&gt;Getting the script&lt;/h4&gt;
&lt;p&gt;Just clone it from my Gitlab Repo at &lt;a href="https://gitlab.com/Nerdeiro/game-cloud-sync"&gt;https://gitlab.com/Nerdeiro/game-cloud-sync&lt;/a&gt;. You can do it
with the command&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;git clone https://gitlab.com/Nerdeiro/game-cloud-sync.git
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once it's cloned, you can use it right away, &lt;strong&gt;on a normal Linux distro&lt;/strong&gt;. To put use it on
a Steam Deck, before transfering a copy to the console, open it in your favorite flavor
of Vim and find the line:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;RC=$(which rclone)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and change everything after the equals sign for the full path to the Rclone binary that you
downloaded before. It should look like:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;RC=/home/deck/bin/rclone
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or something like that.&lt;/p&gt;
&lt;h4&gt;Using the script on the command line&lt;/h4&gt;
&lt;p&gt;Just run it with the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;-s : Source. It can be a local directory or an Rclone remote&lt;/li&gt;
&lt;li&gt;-d : Destination. It can be a local directory or an Rclone remote&lt;/li&gt;
&lt;li&gt;-v : Verbose. Shows the copy progress on the terminal&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One of the parameters should be the local directory where your save games are, eg. &lt;code&gt;$HOME/.config/StardewValley&lt;/code&gt;, the other
should be a remote configuration and path, like &lt;code&gt;mycloud:/StardewValley&lt;/code&gt;. Which one you'll use with &lt;code&gt;-s&lt;/code&gt; or &lt;code&gt;-d&lt;/code&gt; will
depend on which direction you want to sync, to or from the cloud.&lt;/p&gt;
&lt;h4&gt;Using the script with Lutris&lt;/h4&gt;
&lt;p&gt;Open Lutris and click with the right mouse button on your game, selecting "Configure" to show the screen bellow:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.anarch157a.com/images/create_button.png" target="_blank"&gt;&lt;img alt="screenshot of Lutris game settings" height="70%" src="https://www.anarch157a.com/images/Lutris.png" width="70%"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If your screen is not like that, tick the option "Advanced" on the top of the dialog, then scroll all the way to the botton of the "System Options" tab. There you'll the boxes to configure a &lt;em&gt;Pre-launch&lt;/em&gt; and a &lt;em&gt;Post-exit&lt;/em&gt; scripts.&lt;/p&gt;
&lt;p&gt;To &lt;strong&gt;download&lt;/strong&gt; the save files from the cloud to your computer (or Deck) fill the "Pre-launch" line with:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;sync-game.sh -s my_cloud:saved_games/ -d $HOME/game_dir/
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To &lt;strong&gt;upload&lt;/strong&gt; the save files from the computer to the cloud, fill the "Post-exit" line with:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;sync-game.sh -s $HOME/game_dir/ -d my_cloud:saved_games/
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If everything works as they should, your game should be saved on your cloud storage, ready to sync to other devices.
Do the same on the Steam Deck if necessary.&lt;/p&gt;
&lt;p&gt;And happy gaming.&lt;/p&gt;</description><category>Cloud</category><category>Games</category><category>Linux</category><category>Steam Deck</category><guid>https://www.anarch157a.com/posts/game-cloud-saves/</guid><pubDate>Fri, 07 Apr 2023 14:47:00 GMT</pubDate></item><item><title>Using Home Assist to sleep/resume a Linux PC</title><link>https://www.anarch157a.com/posts/ha-power-mgmt/</link><dc:creator>Anarch157a</dc:creator><description>&lt;h4&gt;Intro&lt;/h4&gt;
&lt;p&gt;All right, you automated lots of stuff arround your place with &lt;a href="https://www.home-assistant.io/"&gt;Home Assistant&lt;/a&gt;, but what about your PC ?&lt;/p&gt;
&lt;p&gt;Wouldn't it be cool if you could turn it on or off from anywhere, just tapping on a button in your phone screen ?&lt;/p&gt;
&lt;p&gt;Well, if your PC supports Sleep/Resume, you can do it with a couple of scripts. I'll demonstate here how to do it for a Linux desktop/notebook. You can addapt this to MacOS, maybe even Windows. You you do it, let me know on Mastodon, just Toot me at &lt;a href="https://fosstodon.org/@nerdeiro"&gt;@nerdeiro@fosstodon.org&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Checking system&lt;/h4&gt;
&lt;p&gt;First of all, let's check if your system supports Sleep/Resume. On a laptop, this is pretty much a given, but on a desktop, it may not be enable on the BIOS settings. Run the command bellow to check it:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;/sys/power/state

freeze&lt;span class="w"&gt; &lt;/span&gt;mem&lt;span class="w"&gt; &lt;/span&gt;disk
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you get this response, your system supports S3 sleep. Good. If not, check your BIOS settings. Since each mother board maker have different menus, I can't help you that, sorry.&lt;/p&gt;
&lt;p&gt;Second, to wake up the system, it'll be necessary to enable Wake on Lan (WoL) too. This is another BIOS setting the you need to check, keep in mind that some board makers (Like Asus), might not have an explicit "Wol" or "Wake on Lan" setting, in Asus boards you need to activate a setting that says "Power On By PCI-E".&lt;/p&gt;
&lt;p&gt;Now, to make WoL work, you're have to find what is your &lt;em&gt;actual&lt;/em&gt; MAC Address. It is possible to use a custom MAC when the system is up and running, but the system is on S3 (Sleep) state, it's the BIOS that will answer to the "Magic Packets", using the factory assigned MAC. Fortunatelly, using the &lt;code&gt;ip&lt;/code&gt; command in Linux, we can figure this easily:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;ip&lt;span class="w"&gt; &lt;/span&gt;link&lt;span class="w"&gt; &lt;/span&gt;show

&lt;span class="m"&gt;2&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;eth0:&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;mtu&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1420&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;qdisc&lt;span class="w"&gt; &lt;/span&gt;mq&lt;span class="w"&gt; &lt;/span&gt;state&lt;span class="w"&gt; &lt;/span&gt;UP&lt;span class="w"&gt; &lt;/span&gt;mode&lt;span class="w"&gt; &lt;/span&gt;DEFAULT&lt;span class="w"&gt; &lt;/span&gt;group&lt;span class="w"&gt; &lt;/span&gt;default&lt;span class="w"&gt; &lt;/span&gt;qlen&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;link/ether&lt;span class="w"&gt; &lt;/span&gt;xx:yy:de:ad:be:ef&lt;span class="w"&gt; &lt;/span&gt;brd&lt;span class="w"&gt; &lt;/span&gt;ff:ff:ff:ff:ff:ff&lt;span class="w"&gt; &lt;/span&gt;permaddr&lt;span class="w"&gt; &lt;/span&gt;xx:yy:zz:aa:bb:cc
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The address after 'permaddr' is your factory assigned MAC. Write it for later.&lt;/p&gt;
&lt;h4&gt;Remote scripts&lt;/h4&gt;
&lt;p&gt;Now, let's prepare the scripts that will do the magic. SSH to your Home Assistant box, if HA is running on a container instead of a as stand-alone OS, make sure you're comfortable with Docker's or Podman's commands, because you're gonna need to do some restarts.&lt;/p&gt;
&lt;p&gt;Now, let's see what  our scripts look like, before deploying them to HA.&lt;/p&gt;
&lt;h5&gt;The suspend script&lt;/h5&gt;
&lt;p&gt;This is the script that should put the machine to sleep:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash - &lt;/span&gt;

ssh&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;UserKnownHostsFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;/config/keypair&lt;span class="w"&gt; &lt;/span&gt;nerdeiro@192.168.1.2&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="s1"&gt;'logger "Sent to sleep by Home Assistant"&lt;/span&gt;
&lt;span class="s1"&gt;        sudo systemctl start suspend.target'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A little bit of explanation about the script. Since it's supposed to run a command using sudo (see bellow why), we need to run SSH with &lt;code&gt;-t&lt;/code&gt; option, so it creates a pseudo-TTY on the other side, or it will fail, then since we don't want to deal with SSH known hosts stuff, We tell it to ignore strict host checking and use /dev/null instead of $HOME/.ssh/known_hosts.&lt;/p&gt;
&lt;p&gt;After that, we have the private key used to authenticate in the target box, the user and host and the script itself. This is where you should be asking "Hey, but what if the IP address changes ?". Well, make sure it doesn't. Either configure a static IP on your machine, or set up your DHCP server/WiFi router/whatever to always assign the same IP to you, based on the MAC Address. In my case, the DHCP server that distributes addresses on my LAN is a &lt;a href="https://pi-hole.net/"&gt;Pi-hole&lt;/a&gt;, which you should be using anyway to block ads and trackers.&lt;/p&gt;
&lt;p&gt;Then the script that will run on the other side. In this example, it's a two-liner because I added a line to generate a syslog message with &lt;code&gt;logger&lt;/code&gt;. If you just want the suspend command, there's no need to put it between single quotes. For multi-line scripts, that's necessary.&lt;/p&gt;
&lt;p&gt;Now, you might be wondering, why use &lt;code&gt;sudo&lt;/code&gt; with systemctl to start the suspend target ? I don't need it locally ! The answer for that is &lt;a href="https://en.wikipedia.org/wiki/Polkit"&gt;polkit&lt;/a&gt;, which has a local agent that authenticates you and lets you suspend the machine without explicitly using &lt;code&gt;pkexec&lt;/code&gt; or &lt;code&gt;sudo&lt;/code&gt;, but since polkit agents don't work over SSH (maybe they do, but my DuckDuckGo skills failed me this time), we'll have to use good old &lt;code&gt;sudo&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;Now, let's deal with authentication on the machine we want to suspend. Putting your password on a script is a bad idea and it's cumbersome to use, so a key-pair is the way to go. So, SSH to the machine running Home Assistant and create a new pair of keys there. If you're running HA on a container, you should have a directory somewhere that is mounted as a volume under &lt;code&gt;/config&lt;/code&gt; inside the container. You can even do this from inside the container itself. Run &lt;code&gt;docker ps&lt;/code&gt;, get the name of the container (let's say it's called "homeassistant") and run &lt;code&gt;docker exec -ti homeassistant bash&lt;/code&gt;. This should put you right at the &lt;code&gt;/config&lt;/code&gt; directory inside the container. If your HA is a stand-alone OS, once logged into it, change to the root user with &lt;code&gt;sudo su -&lt;/code&gt; and &lt;code&gt;cd /config&lt;/code&gt;. Creating a key-pair is as simple as running &lt;code&gt;ssh-keygen -t ed25519 -f /config/keypair&lt;/code&gt; and pressing &lt;em&gt;Return&lt;/em&gt; a couple of time to leave the password empty. If you prefer RSA keys, intead of ED25519, just remove the &lt;code&gt;-t ed25519&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once you have the key-pair, copy the contents of the file ending in &lt;em&gt;.pub&lt;/em&gt; to the target machine and add it as a line in &lt;code&gt;$HOME/.ssh/authorized_keys&lt;/code&gt;. Try SSHing to your PC from inside HA-OS or container using this key, just to confirm everything is OK before proceeding.&lt;/p&gt;
&lt;h5&gt;The resume script&lt;/h5&gt;
&lt;p&gt;This is the one that wakes uo your machine:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash - &lt;/span&gt;

wakeonlan&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.1.255&lt;span class="w"&gt; &lt;/span&gt;xx:yy:zz:aa:bb:cc
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is a very simple one. We don't even need to worry about installing the &lt;code&gt;wakeonlan&lt;/code&gt; command, as it's already provided on the Home Assistant container/OS. The only thing you should change here is the network broadcast address and the MAC Address your your PC. To find what the broadcast address is, run the command:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;ip&lt;span class="w"&gt; &lt;/span&gt;address&lt;span class="w"&gt; &lt;/span&gt;show

&lt;span class="m"&gt;2&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;eth0:&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;mtu&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1420&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;qdisc&lt;span class="w"&gt; &lt;/span&gt;mq&lt;span class="w"&gt; &lt;/span&gt;state&lt;span class="w"&gt; &lt;/span&gt;UP&lt;span class="w"&gt; &lt;/span&gt;group&lt;span class="w"&gt; &lt;/span&gt;default&lt;span class="w"&gt; &lt;/span&gt;qlen&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;link/ether&lt;span class="w"&gt; &lt;/span&gt;xx:xx:de:ad:be:ef&lt;span class="w"&gt; &lt;/span&gt;brd&lt;span class="w"&gt; &lt;/span&gt;ff:ff:ff:ff:ff:ff
&lt;span class="w"&gt;    &lt;/span&gt;inet&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.1.2/24&lt;span class="w"&gt; &lt;/span&gt;brd&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.1.255&lt;span class="w"&gt; &lt;/span&gt;scope&lt;span class="w"&gt; &lt;/span&gt;global&lt;span class="w"&gt; &lt;/span&gt;enp4s0
&lt;span class="w"&gt;       &lt;/span&gt;valid_lft&lt;span class="w"&gt; &lt;/span&gt;forever&lt;span class="w"&gt; &lt;/span&gt;preferred_lft&lt;span class="w"&gt; &lt;/span&gt;forever
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The broadcast address is the one right after &lt;em&gt;brd&lt;/em&gt; on the 3rd line.&lt;/p&gt;
&lt;p&gt;You can test if its working, as long as you have some other device that can SSH to Home Assistant. Put your PC to sleep, then from HA, run the &lt;code&gt;wakeonlan&lt;/code&gt; command like in the script. If the PC turns on, we're set. If not, make sure that the machine supports this feature, same for the network card, if it's an add-on, and your BIOS is properly configured.&lt;/p&gt;
&lt;h4&gt;Home Assistant setup&lt;/h4&gt;
&lt;p&gt;All right, lets get to the good part. Setting up Home Assistant itself.&lt;/p&gt;
&lt;p&gt;Before we start pushing the mouse on the GUI, there are a few configurations we need to do, to tell Home Assistant the scripts exist. Locate whre the file &lt;code&gt;configuration.yaml&lt;/code&gt; is. If you're &lt;em&gt;docker exec&lt;/em&gt;ing into the container or SSHd to the HA-OS, it'll be located in &lt;code&gt;/config&lt;/code&gt;, if you're outside the container, check in docker which directory is used as the &lt;em&gt;/config&lt;/em&gt; volume. &lt;/p&gt;
&lt;p&gt;Create both scripts on the &lt;code&gt;/config&lt;/code&gt; directory, making sure they're executable, run &lt;code&gt;chmod 755 script&lt;/code&gt; if neccessary. Run each of them from the CLI, just to be sure they work.&lt;/p&gt;
&lt;p&gt;Now, open up &lt;code&gt;configuration.yaml&lt;/code&gt; on your favorite editor, such as Vim or Nano, and add this lines:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nt"&gt;shell_command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;sleep_script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/config/sleep.sh&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;wake_script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/config/wake.sh&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Listing them as shell commands in &lt;code&gt;configuration.yaml&lt;/code&gt; will create the services that can be run, but to add them as buttons on a dashboard we need to create them as script entities. If you look at the configuration, you should see a line like:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nv"&gt;script&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;scripts&lt;/span&gt;.&lt;span class="nv"&gt;yaml&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, save the configuration file and open &lt;code&gt;scripts.yaml&lt;/code&gt; on your editor. Don't worry if it's empty, just add the following lines to it:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nt"&gt;pc_sleep&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;pc_sleep&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;shell_command.sleep_script&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;{}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;single&lt;/span&gt;
&lt;span class="nt"&gt;pc_wake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;pc_wake&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;shell_command.wake_script&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;{}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;single&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Those will tell Home Assistant that they exist, so we can set them up on the GUI, which is the next step. So, save the files and restart Home Assistant, either by rebooting the server if it's an OS install or by restarting the container. After that, log on to the GUI and lets create some buttons.&lt;/p&gt;
&lt;h4&gt;Creating buttons&lt;/h4&gt;
&lt;p&gt;On the Home Assistant GUI, chose the dashboard where you want the suspend and resume buttons to be and click on the "hamburger" menu, it should be on the top-right of the page, and chose &lt;em&gt;Edit Dashboard&lt;/em&gt;. Then click &lt;em&gt;Add Card&lt;/em&gt; and chose "Button". Fill in the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Entity: Select one of the scripts we created (e.g. script.pc_sleep)&lt;/li&gt;
&lt;li&gt;Name, Icon, etc.: It's up to you how it would look like.&lt;/li&gt;
&lt;li&gt;Tap Action: Select &lt;em&gt;Call Service&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Service: Again, select the script you want to run.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It should look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.anarch157a.com/images/create_button.png" target="_blank"&gt;&lt;img alt="screenshot of Home Assist button settings" height="70%" src="https://www.anarch157a.com/images/create_button.png" width="70%"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Testing the setup&lt;/h4&gt;
&lt;p&gt;I made a small video showing it working:&lt;/p&gt;
&lt;video controls width="320" height="180" poster="/images/video_still.png" src="https://www.anarch157a.com/video/Homeassistant_liga_desliga.mp4" type="video/mp4"&gt;
&lt;/video&gt;

&lt;p&gt;By now, you too should have the capability to sleep/resume your PC from anywhere, even your bed, so no more worries if the computer was left on or not. Just reach to your phone and turn it off.&lt;/p&gt;
&lt;p&gt;Well, this was a long one, so happy automations and see you on the next one.&lt;/p&gt;</description><category>Automation</category><category>Home Assistant</category><category>Linux</category><category>Power</category><guid>https://www.anarch157a.com/posts/ha-power-mgmt/</guid><pubDate>Fri, 16 Dec 2022 14:47:00 GMT</pubDate></item></channel></rss>