dotfiles
It’s not “just dotfiles” - it's extreme modularity that looks and feels like a NixOS flake. It's Voice-driven DevOps, i…
git clone https://github.com/QuackHack-McBlindy/dotfiles.gitQuackHack-McBlindy/dotfiles❄️🦆 QuackHack-McBLindy NixOS dotfiles
This is a automagiduckically updated README.md
Caution
Do not blindly run this flake.
That's my job. 🧑🦯
Here lives all home machines/phone config files,
and home automations, fully reproducible,
crafted as a tiny Nix flake
Glued together by a Nix-flavoured command line utility,
easiy expanded and used to deploy, doc, and duck around
What Makes This Configuration Unique?
Nix declarative configuration style, custom modules evaluated dynamically for each host.
Home Manager - No ducking way! I just auto symlink ./home to /home
Home Assistant - Quack no! No assistance needed!
Zigbee and smart home tightly integrated with Nix. For not just a declarative house but also deployable apartments.
Not only that - my voice assistant is LIGHTNING FAST! (ms) ⚡🏆
- 90 qwacktastic scripts in /bin - 57 scripts have voice commands.
- 2503 dynamically generated regex patterns - makes 272684913 phrases available as commands.
- Smart Home Nix Fu - Managing 3 TV's, 48 devices & 11 scenes.
- Natural Language DevOps support with complete voice pipeline
- Mobile Frontend with Chatbot (no LLM) - Less thinking, more doing!
- Infra as everyday accessibility
- Yubikey encrypted deployment system
- Version controlled ESP32 firmware management
- Self Documenting
List would get long, very quackly.
perhaps a more suitable question would be:
"What makes this configuration common?"
🦆 Follow My Adventures
This repository is complex, and it's not a typical NixOS dotfiles setup.
Since NixOS probably never have been used in such a unique way, understanding how everything is working solely from massive source code will be tricky for newcomers as well as advanced users.
I try to simplify that process in my blog.
Duck Challenge
I have hidden some ducks in the .nix files in this repository.
Let's see if you can find all 4646 ducks?
❄️ Flake
Define yourself at `config.this.user.me`.
{
discord = "https://discordapp.com/users/675530282849533952";
dotfilesDir = "/home/pungkula/dotfiles";
email = "isthisrandomenough@protonmail.com";
extraGroups = [ "networkmanager" "wheel" "dialout" "docker" "dockeruser" "users" "pungkula" "adbusers" "audio" "2000" "i2c" "mqtt" ];
hashedPassword = "$y$j9T$m8hPD36i1VMaO5rurbZ4j0$KpzQyat.F6NoWFKpisEj77TvpN2wBGB8ezd26QoKDj6";
matrix = "https://matrix.to/#/@quackhack-mcblindy:matrix.org";
mobileDevices = {
iphone = {
pubkey = "UFB0T1Y/uLZi3UBtEaVhCi+QYldYGcOZiF9KKurC5Hw=";
wgip = "10.0.0.7"
};
tablet = {
pubkey = "ETRh93SQaY+Tz/F2rLAZcW7RFd83eofNcBtfyHCBWE4=";
wgip = "10.0.0.8"
}
};
name = "pungkula";
repo = "git@github.com:QuackHack-McBlindy/dotfiles.git"
}
Define each hosts data at `config.this.host`.
{
hostname = "desktop";
interface = [ "enp119s0" ];
ip = "192.168.1.111";
keys = {
privateKeys = {
};
publicKeys = {
adb = "QAAAACEJNfsfRV4PQ9Ah87MbTVbMkbXC6CAMDOR+0K6mIpv/4TSzYMkc2qit3Kryc55IVOjwR3fJRjj/uL549gZ7nEemWtcd3AsYQBp0iIEor8nu1L/V6jfsTY6Xe/pl06xoroy6OwZRWuDbZ4wD2xQRRQjfPd+JtYnMAWneM6r1V15uR67w4ITvjk3ckyfgNeLZMUwahMRjC3wSjaU9sAdKNmg8yPd8uHZ+mK6mstxJFAGEpnnm1lE7Z2r0DF6h6MKY1++dwhU+WM5BRDNiBg+D4i6fDW4+Z1I9ENuFnjT17zAxZXch04SNlG3O94BANYP7jmKp60OvtDL6msfphntuIUzMCkndF9De0Kv4lJdQxe1d+wf+AFpmtd/xtrk45YdMV+eWCJf2OkidaHmSj4ffkAobpun0VrkZN2Z1JymmdsvUbyMjAsby3Zun0xr3EocUS8Jy5TcsK/dcpD6CB5dqzlHhsHSAWt2TDwPzZYXgV1xc+q+PqM09OVN1xActJu75UMkg5b84U15hwQvYdwB8UaopMWWk6p064c7gxYSfH7fSxwkW2Jy1CElgJa55Pp4SZG9b/3B+VcNL1WSf6v/lvJqPbrRvBqvS0+e9wcFMNZtQKTX3n5X0wW1/czZPCQX+hmM8Uu1qrtaz4rKViIEGf4YR0/9eUGYQVfuAxAh8ZmsroJlnAAEAAQA= pungkula@desktop";
age = "age16utg7mmk73cn3glrwthtm0p7mf6g3vrd48h3ucpn6wnf28pgxvcsh4rjjp";
borg = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMVYczAOBSeS7WfSvzYDOS4Q9Ss+yxCf2G5MVfAALOx/";
builder = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINQ7c/AeIpmJS6cWQkHOe4ZEq3DXVRnjtTWuWfx6L46n";
cache = "cache:/pbj1Agw2OoSSDZcClS69RHa1aNcwwTOX3GIEGKYwPc=";
host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILdwPkRQxlbrbRGwEO5zMJ4m+7QqUQPZg1iqbd5HRP34";
iPhone = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMcmr+z7k/yCbrFg+JDgo8JCuWqNVYn10ajRbNTp8fq";
ssh = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPwZL27kGTQDIlSe03abT9F24nSAizORyjo5cI3BD92s";
wireguard = "Oq0ZaYAnOo5sLpV//OEFwLgjVCxPyeQqf8cZBASluWk="
}
};
modules = {
hardware = [ "cpu/intel" "audio" ];
networking = [ "default" "pool" ];
programs = [ "default" "thunar" "firefox" "vesktop" ];
services = [ "ssh" "default" "adb" "openrgb" "backup" "cache" "keyd" "jelly" "yo-rs" "yo-client" ];
system = [ "nix" "pkgs" "gnome" "crossEnv" "gtk" ];
virtualisation = [ "docker" "vm" ]
};
system = "x86_64-linux";
wgip = "10.0.0.2"
}
Define any optional theme configuration at `config.this.theme`.
{
cursorTheme = {
name = "Bibata-Modern-Classic";
package = "/nix/store/f1hbsrnl35k5fxk9ny1ikc22q38dmhbm-bibata-cursors-2.0.7";
size = 32
};
enable = false;
fonts = {
monospace = "Fira Code";
packages = [ "/nix/store/xq0rmhyr8qxw9dyz64if6d7cq5gxfyqh-fira-code-6.2" ];
system = "Fira Sans"
};
gtkSettings = {
gtk-application-prefer-dark-theme = "1";
gtk-cursor-theme-name = "Bibata-Modern-Classic";
gtk-icon-theme-name = "elementary-xfce-icon-theme"
};
iconTheme = {
name = "Papirus-Dark";
package = "/nix/store/n03f6g8flrp8p5nlm45qadssjf3klhs0-papirus-icon-theme-20250501"
};
name = "gtk3.css";
styles = "/nix/store/5yb5i296sijga5k65cdw2ib3hhwwq6iq-gtk3.css"
}
Define Zigbee-devices, scenes, automations, tv's, channels etc at `config.house`.
dotfiles/modules/myHouse.nix ⮞ https://github.com/quackhack-mcblindy/dotfiles
# dotfiles/modules/myHouse.nix ⮞ https://github.com/quackhack-mcblindy/dotfiles
{ # 🦆 says ⮞ my house - qwack
config, # 🦆 says ⮞ more info ⮞ https://quackhack-mcblindy.github.io/blog/house/index.html
lib,
self,
pkgs,
...
} : let # 🦆 say ⮞ load dash pages css files
strip = text:
builtins.replaceStrings [ "/*" "*/" ] [ "" "" ] text;
# 🦆 says ⮞ load custom pages 4 dashboard
customPages = import ./dashboard/customPages.nix { inherit lib config pkgs; };
pages = customPages.pages;
# 🦆 says ⮞ load css files
css = {
tv = builtins.readFile ./themes/css/duckdash/tv.css;
health = builtins.readFile ./themes/css/duckdash/health.css;
chat = builtins.readFile ./themes/css/duckdash/chat.css;
};
# 🦆 says ⮞ get house.tv configuration with debug info
tvConfig = builtins.trace "TV config: ${builtins.toJSON config.house.tv}" config.house.tv;
# 🦆 says ⮞ generate TV selector options with debug
tvOptions = let
tvNames = lib.attrNames tvConfig;
options = lib.concatMapStrings (tvName:
let tv = tvConfig.${tvName};
in if tv.enable then ''<option value="${tv.ip}">${tvName}</option>'' else ""
) tvNames;
in builtins.trace "TV options: ${options}" options;
# 🦆 says ⮞ dis fetch what host has Mosquitto
sysHosts = lib.attrNames self.nixosConfigurations;
mqttAuth = "-u ${config.house.zigbee.mosquitto.username} -P $(cat ${config.house.zigbee.mosquitto.passwordFile})";
# 🦆 says ⮞ icon map
icons = {
light = {
ceiling = "mdi:ceiling-light";
strip = "mdi:light-strip";
spotlight = "mdi:spotlight";
bulb = "mdi:lightbulb";
bulb_color = "mdi:lightbulb-multiple";
desk = "mdi:desk-lamp";
floor = "mdi:floor-lamp";
wall = "mdi:wall-sconce-round";
chandelier = "mdi:chandelier";
pendant = "mdi:vanity-light";
nightlight = "mdi:lightbulb-night";
strip_rgb = "mdi:led-strip-variant";
reading = "mdi:book-open-variant";
candle = "mdi:candle";
ambient = "mdi:weather-night";
};
sensor = {
motion = "mdi:motion-sensor";
smoke = "mdi:smoke-detector";
water = "mdi:water";
contact = "mdi:door";
temperature = "mdi:thermometer";
humidity = "mdi:water-percent";
};
remote = "mdi:remote";
outlet = "mdi:power-socket-eu";
dimmer = "mdi:toggle-switch";
pusher = "mdi:gesture-tap-button";
blinds = "mdi:blinds";
};
Mqtt2jsonHistory = field: file: ''
FILE="/var/lib/zigduck/${file}"
VALUE=$(echo "$MQTT_PAYLOAD" | jq '.${field}')
mkdir -p "$(dirname "$FILE")"
# 🦆 says ⮞ check current value
if [ -s "$FILE" ]; then
CURRENT=$(jq ".${field}" "$FILE")
if [ "$CURRENT" = "$VALUE" ]; then
exit 0 # 🦆 says ⮞ skip write – value unchanged
fi
fi
# 🦆 says ⮞ otherwise, update
if [ ! -s "$FILE" ]; then
jq -n --argjson v "$VALUE" \
'{ ${field}: $v, history: [$v] }' > "$FILE"
else
jq --argjson v "$VALUE" '
.${field} = $v
| .history += [$v]
| .history = (.history[-200:])
' "$FILE" > "$FILE.tmp" && mv "$FILE.tmp" "$FILE"
fi
'';
health = lib.mapAttrs (hostName: _: {
enable = true;
description = "Health Check: ${hostName}";
topic = "zigbee2mqtt/health/${hostName}";
actions = [
{
type = "shell";
command = ''
mkdir -p /var/lib/zigduck/health
touch /var/lib/zigduck/health/${hostName}.json
echo "$MQTT_PAYLOAD" > /var/lib/zigduck/health/${hostName}.json
'';
}
];
}) self.nixosConfigurations;
in { # 🦆 duck say ⮞ voice assistant config
# yo.legacy = false;
yo.SplitWords = [ "samt" ];
yo.sorryPhrases = [
"I didn't catch that, try again."
"Sorry, what was that?"
"Could you repeat?"
];
# 🦆 duck say ⮞ house config
house = {
media.root = "/Pool";
media = {
movies = "/Pool/Movies";
tv = "/Pool/TV";
music = "/Pool/Music";
musicVideos = "/Pool/Music_Videos";
otherVideos = "/Pool/Other_Videos";
podcasts = "/Pool/Podcasts";
};
# 🦆says⮞ what machine should output sound
soundHost = "desktop";
# 🦆 says ⮞ ROOM CONFIGURATION
rooms = {
bedroom.icon = "mdi:bed";
hallway.icon = "mdi:door";
kitchen.icon = "mdi:food-fork-drink";
livingroom.icon = "mdi:sofa";
wc.icon = "mdi:toilet";
tv-area.icon = "mdi:television";
other.icon = "mdi:misc";
};
# 🦆 says ⮞ DASHBOARD CONFIOGURATION
dashboard = {
passwordFile = config.sops.secrets.api.path; # 🦆 says ⮞ safety firzt!
# 🦆 says ⮞ home page information cards
statusCards = {
calendar = {
enable = true;
title = "𝑪𝑨𝑳𝑬𝑵𝑫𝑨𝑹";
group = "1";
icon = "fas fa-calendar";
color = "#ff0000";
theme = "glass";
filePath = "/var/lib/zigduck/calendar.json";
jsonField = "today_date";
format = "{value}";
detailsJsonField = "today_events";
detailsFormat = "{value}";
chart = false;
on_click_action = [
{
type = "shell";
command = "yo say \"detta är ett ank test - testar ankor ankor anka naka naka ojojojjoj vad många ankor detta blev oj oj\" --host desktop";
}
];
};
# 🦆 says ⮞ Monero USD price ticker
xmr = {
enable = true;
title = "𝑿𝑴𝑹";
group = "tickers";
icon = "fab fa-monero";
color = "#a78bfa";
theme = "colorful";
filePath = "/var/lib/zigduck/xmr.json";
jsonField = "current_price";
format = "{value}";
detailsJsonField = "7d_change";
detailsFormat = "7d: {value}%";
chart = true;
};
# 🦆 says ⮞ Bitcoin USD price ticker
btc = {
enable = true;
title = "𝑩𝑻𝑪";
group = "tickers";
icon = "fab fa-bitcoin";
color = "#ff6600";
filePath = "/var/lib/zigduck/btc.json";
jsonField = "current_price";
format = "{value}";
detailsJsonField = "7d_change";
detailsFormat = "7d: {value}%";
chart = true;
historyField = "history";
};
# 🦆 says ⮞ kWh/price chart card
energyPrice = {
enable = true;
title = "𝑷𝑹𝑰𝑪𝑬";
group = "energy";
icon = "fas fa-bolt";
color = "#ffff00";
filePath = "/var/lib/zigduck/energy_price.json";
jsonField = "current_price";
format = "{value} SEK/kWh";
chart = true;
historyField = "history";
};
# 🦆 says ⮞ energy usage card
energyUsage = {
enable = true;
title = "USAGE";
group = "energy";
icon = "fas fa-bolt";
color = "#ffff00";
filePath = "/var/lib/zigduck/energy_usage.json";
jsonField = "monthly_usage";
format = "{value} kWh";
chart = true;
historyField = "history";
};
# 🦆 says ⮞ show indoor temperature
temperature = {
enable = true;
title = "TEMPERATURE C";
group = "sensors";
icon = "fas fa-thermometer-half";
color = "#e74c3c";
theme = "glass";
filePath = "/var/lib/zigduck/temperature.json";
jsonField = "temperature";
format = "{value} °C";
detailsFormat = "Temperature in Hallway";
chart = true;
historyField = "history";
};
};
# 🦆 says ⮞ DASHBOARD PAGES (extra tabs)
pages = {
# 🦆 says ⮞ (TV) remote page
"3" = {
icon = "fas fa-television";
title = "remote";
# 🦆 says ⮞ symlink epg to webserver
files = { tv = "/var/lib/zigduck/tv"; };
css = css.tv;
code = pages.remote;
};
# 🦆 says ⮞ system-wide health monitoring page
"4" = {
icon = "fas fa-notes-medical";
title = "health";
# 🦆 says ⮞ symlink directory to webserver
files = { health = "/var/lib/zigduck/health"; };
css = css.health;
code = pages.health;
};
# 🦆says⮞ ChatBot (no LLM) - Less thinkin', more doin'!
"5" = {
icon = "fas fa-comments";
title = "chat";
css = css.chat;
# 🦆 says ⮞ symlink TTS audio to frontend webserver
files = { tts = "/var/lib/zigduck/tts"; };
code = pages.chat;
};
};
};
# 🦆 ⮞ ZIGBEE ⮜ 🐝
zigbee = {
# 🦆 says ⮞ encrypted zigbee network key
networkKeyFile = config.sops.secrets.z2m_network_key.path;
# 🦆 says ⮞ mosquitto authentication
mosquitto = {
host = "192.168.1.211";
username = "mqtt";
passwordFile = config.sops.secrets.mosquitto.path;
};
# 🦆 says ⮞ TV light syncin'
hueSyncBox = {
enable = true;
# 🦆 says ⮞ sadly needed (i disable itz internet access - u should too)
bridge = {
ip = "192.168.1.33";
# 🦆 says ⮞ run the following to get api token:
# curl -X POST http://192.168.1.33/api -d '{"devicetype":"house#nixos"}'
passwordFile = config.sops.secrets.hueBridgeAPI.path;
};
syncBox = { # C42996020AAE
ip = "192.168.1.34";
passwordFile = config.sops.secrets.hueBridgeAPI.path;
tv = "shield";
};
};
# 🦆says⮞ coordinator configuration
coordinator = {
vendorId = "10c4";
productId = "ea60";
symlink = "zigbee"; # 🦆 says ⮞ diz symlinkz da serial port to /dev/zigbee
};
# 🦆 says ⮞ optional dimmer config
dimmer = {
message = "action";
doubleClickTimeout = 500;
#actions = {
# onPress = "on_press_release";
# onHold = "on_hold_release";
#};
};
# 🦆 says ⮞ when motion triggers lights
motion = {
enable = true;
trigger.lights = {
after = 14;
before = 9;
duration = 900;
};
};
# 🦆 ⮞ AUTOMATIONS ⮜
automations = {
# 🦆 says ⮞ there are 6 different automation types
# 🦆 says ⮞ + a greeting automation
greeting = {
enable = true;
awayDuration = 7200;
delay = 10;
actions = [
{
type = "shell";
command = ''
yo say "Borta bra, hemma bäst. Välkommen idiot!"
'';
}
];
};
# 🦆 says ⮞ 1. MQTT triggered automations
mqtt_triggered = {
# 🦆say⮞ crypto tickers
xmr = {
enable = true;
description = "Updating XMR price data on dashboard";
topic = "zigbee2mqtt/crypto/xmr/price";
actions = [{ type = "shell"; command = Mqtt2jsonHistory "current_price" "xmr.json"; }];
};
btc = {
enable = true;
description = "Updating BTC price data on dashboard";
topic = "zigbee2mqtt/crypto/btc/price";
actions = [{ type = "shell"; command = Mqtt2jsonHistory "current_price" "btc.json"; }];
};
# 🦆say⮞ energy tracking
energyPrice = {
enable = true;
description = "Updating energy data on dashboard";
topic = "zigbee2mqtt/tibber/energy";
actions = [{ type = "shell"; command = Mqtt2jsonHistory "current_price" "energy_price.json"; }];
};
energyUsage = {
enable = true;
description = "Updating energy data on dashboard";
topic = "zigbee2mqtt/tibber/energy";
actions = [{ type = "shell"; command = Mqtt2jsonHistory "monthly_usage" "energy_usage.json"; }];
};
# 🦆say⮞ hallway temperature
temperature = {
enable = true;
description = "Updating temperature data on dashboard";
topic = "zigbee2mqtt/Motion Sensor Hall";
actions = [{ type = "shell"; command = Mqtt2jsonHistory "temperature" "temperature.json"; }];
};
# 🦆say⮞ calendar
calendar = {
enable = true;
description = "Updated calendar events";
topic = "zigbee2mqtt/calendar";
actions = [
{
type = "shell";
command = ''
iso_date=$(echo "$MQTT_PAYLOAD" | jq -r '.today_date')
formatted_date=$(date -d "$iso_date" +"%b %d")
MQTT_PAYLOAD=$(echo "$MQTT_PAYLOAD" | jq --arg d "$formatted_date" '.today_date = $d')
echo "$MQTT_PAYLOAD" > /var/lib/zigduck/calendar.json
'';
}
];
};
# 🦆say⮞ tv control
tv_command = {
enable = true;
description = "TV command sent";
topic = "zigbee2mqtt/tvCommand";
actions = [
{
type = "shell";
command = ''
tv_command=$(echo "$MQTT_PAYLOAD" | jq -r '.tvCommand')
ip=$(echo "$MQTT_PAYLOAD" | jq -r '.ip // "192.168.1.223"')
yo tv --typ "$tv_command" --device "$ip"
echo "TV command received! Command: $tv_command. IP: $ip"
'';
}
];
};
tv_channel_change = {
enable = true;
description = "Change TV channel via yo command";
topic = "zigbee2mqtt/tvChannelCommand";
actions = [
{
type = "shell";
command = ''
channel=$(echo "$MQTT_PAYLOAD" | jq -r '.tvChannel')
ip=$(echo "$MQTT_PAYLOAD" | jq -r '.ip // "192.168.1.223"')
yo tv --typ livetv --device "$ip" --search "$channel"
'';
}
];
}; # 🦆says⮞health checks (from let block)
} // health;
# 🦆 says ⮞ 2. room action automations
room_actions = {
hallway = {
door_opened = [];
door_closed = [];
};
kitchen = {
motion_not_detected = [
{
type = "shell";
command = ''
power=$(jq -r '."Fläkt".power' /var/lib/zigduck/state.json)
# 🦆 says ⮞ no need 2 turn off if it'z not on
if (( power > 20 )); then
yo mqtt_pub --topic "zigbee2mqtt/Fläkt/set" --message '{"countdown": 120}'
fi
'';
}
{ # 🦆 says ⮞ slow go light go bye bye
type = "scene";
scene = "kitchenFadeOff";
}
];
motion_detected = [
{
type = "shell";
command = ''
# 🦆 says ⮞ cancel any pending countdown
yo mqtt_pub --topic "zigbee2mqtt/Fläkt/set" --message '{"countdown": 0}'
# 🦆 says ⮞ if fan is off - start it
STATE=$(jq -r '."Fläkt".state' /var/lib/zigduck/state.json)
if [ "$STATE" = "OFF" ]; then
zigduck-cli --device "Fläkt" --state on
fi
'';
}
{ # 🦆 SCREAM ⮞ INSTANT LIGHT QWACK
type = "scene";
scene = "kitchenInstant";
}
];
};
};
# 🦆 says ⮞ 3. global actions automations
global_actions = {
leak_detected = [
{
type = "shell";
command = "yo notify '🚨 WATER LEAK DETECTED!'";
}
];
smoke_detected = [
{
type = "shell";
command = "yo notify '🔥 SMOKE DETECTED!'";
}
];
};
# 🦆 says ⮞ 4. dimmer actions automations
dimmer_actions = {
bedroom = {
off_hold_release = {
enable = true;
description = "Turn off all configured light devices";
extra_actions = [];
override_actions = [
{
type = "scene";
scene = "dark";
}
{
type = "mqtt";
topic = "zigbee2mqtt/Fläkt/set";
message = ''{"state":"OFF"}'';
}
];
};
};
};
# 🦆 says ⮞ 5. time based automations
time_based = {};
# 🦆 says ⮞ 6. presence based automations
presence_based = {};
};
# 🦆 ⮞ DEVICES ⮜
devices = {
# 🦆 says ⮞ Kitchen
"0x0017880103ca6e95" = { # 🦆 says ⮞ 64bit IEEE adress (this is the unique device ID)
friendly_name = "Dimmer Switch Kök"; # 🦆 says ⮞ simple human readable friendly name
room = "kitchen"; # 🦆 says ⮞ bind to group
type = "dimmer"; # 🦆 says ⮞ set a custom device type
icon = icons.dimmer;
endpoint = 1; # 🦆 says ⮞ endpoint to call the device on
batteryType = "CR2450"; # 🦆 says ⮞ optional yo
};
"0x0017880102f0848a" = {
friendly_name = "Spotlight kök 1";
room = "kitchen";
type = "light";
icon = icons.light.spotlight;
endpoint = 11;
};
"0x0017880102f08526" = { friendly_name = "Spotlight Kök 2"; room = "kitchen"; type = "light"; icon = icons.light.spotlight; endpoint = 11; };
"0x0017880103a0d280" = { friendly_name = "Uppe"; room = "kitchen"; type = "light"; icon = icons.light.strip; endpoint = 11; supports_color = true; };
"0x0017880103e0add1" = { friendly_name = "Golvet"; room = "kitchen"; type = "light"; icon = icons.light.strip; endpoint = 11; supports_color = true; };
"0xa4c13873044cb7ea" = { friendly_name = "Kök Bänk Slinga"; room = "kitchen"; type = "light"; icon = icons.light.strip; endpoint = 11; };
"0x70ac08fffe9fa3d1" = { friendly_name = "Motion Sensor Kök"; room = "kitchen"; type = "motion"; icon = icons.sensor.motion; endpoint = 1; batteryType = "CR2032"; };
"0xa4c1380afa9f7f3e" = { friendly_name = "Smoke Alarm Kitchen"; room = "kitchen"; type = "sensor"; icon = icons.sensor.smoke; endpoint = 1; };
"0xa4c138b9aab1cf3f" = { friendly_name = "Fläkt"; room = "kitchen"; type = "outlet"; icon = icons.outlet; endpoint = 1; };
# 🦆 says ⮞ LIVING ROOM
"0x0c4314fffe179b05" = { friendly_name = "Larm"; room = "livingroom"; type = "outlet"; icon = icons.outlet; endpoint = 1; };
"0x0017880104f78065" = { friendly_name = "Dimmer Switch Vardagsrum"; room = "livingroom"; type = "dimmer"; icon = icons.dimmer; endpoint = 1; batteryType = "CR2450"; };
"0x00178801037e754e" = { friendly_name = "Takkrona 1"; room = "livingroom"; type = "light"; icon = icons.light.chandelier; endpoint = 1; supports_color = true; };
"0x0017880103c73f85" = { friendly_name = "Takkrona 2"; room = "livingroom"; type = "light"; icon = icons.light.chandelier; endpoint = 1; supports_color = true; };
"0x0017880103f94041" = { friendly_name = "Takkrona 3"; room = "livingroom"; type = "light"; icon = icons.light.chandelier; endpoint = 1; supports_color = true; };
"0x0017880103c753b8" = { friendly_name = "Takkrona 4"; room = "livingroom"; type = "light"; icon = icons.light.chandelier; endpoint = 1; supports_color = true; };
"0x54ef4410003e58e2" = { friendly_name = "Roller Shade"; room = "livingroom"; type = "blind"; icon = icons.blinds; endpoint = 1; };
"0x0017880104540411" = { friendly_name = "PC"; room = "livingroom"; type = "light"; icon = icons.light.spotlight; endpoint = 11; supports_color = true; };
"0x0017880102de8570" = { friendly_name = "Rustning"; room = "livingroom"; type = "light"; icon = icons.light.spotlight; endpoint = 11; supports_color = true; };
"0x540f57fffe85c9c3" = { friendly_name = "Water Sensor"; room = "livingroom"; type = "sensor"; icon = icons.sensor.water; endpoint = 1; };
# 🦆 says ⮞ HALLWAY
"0x00178801021311c4" = { friendly_name = "Motion Sensor Hall"; room = "hallway"; type = "motion"; icon = icons.sensor.motion; endpoint = 1; batteryType = "AAA"; };#⮜ AAA-AWESOME 🦆
"0x00158d00053ec9b1" = { friendly_name = "Door Sensor Hall"; room = "hallway"; type = "sensor"; icon = icons.sensor.contact; endpoint = 1; };
"0x0017880103eafdd6" = { friendly_name = "Tak Hall"; room = "hallway"; type = "light"; icon = icons.light.ceiling; supports_color = true; endpoint = 11; };
"0x000b57fffe0e2a04" = { friendly_name = "Vägg"; room = "hallway"; type = "light"; icon = icons.light.wall; supports_temperature = true; endpoint = 1; };
# 🦆 says ⮞ WC
more like this
dotfiles
Poom's Neovim, Tmux, Fish and other configurations for macOS & Linux. Literally my entire world.
