Compare commits
No commits in common. "cbde498ae8588b40727689eed1195f9ec8768b65" and "6f9b384caae89417a70099f3b1b978e29e3bc063" have entirely different histories.
cbde498ae8
...
6f9b384caa
26 changed files with 271 additions and 1003 deletions
|
|
@ -3,7 +3,7 @@
|
||||||
- get age key from SSH
|
- get age key from SSH
|
||||||
```console
|
```console
|
||||||
curl https://raw.githubusercontent.com/elitak/nixos-infect/master/nixos-infect | PROVIDER=hetznercloud NIX_CHANNEL=nixos-24.05 bash 2>&1 | tee /tmp/infect.log
|
curl https://raw.githubusercontent.com/elitak/nixos-infect/master/nixos-infect | PROVIDER=hetznercloud NIX_CHANNEL=nixos-24.05 bash 2>&1 | tee /tmp/infect.log
|
||||||
nix-shell -p ssh-to-age --run 'ssh-keyscan install.cloonar.com | ssh-to-age'
|
nix-shell -p ssh-to-age --run 'ssh-keyscan example.com | ssh-to-age'
|
||||||
```
|
```
|
||||||
- fix secrets files
|
- fix secrets files
|
||||||
```console
|
```console
|
||||||
|
|
|
||||||
|
|
@ -1,340 +0,0 @@
|
||||||
substitutions:
|
|
||||||
# Default name
|
|
||||||
name: "hallway-light-switch"
|
|
||||||
# Default friendly name
|
|
||||||
friendly_name: "Hallway Light Switch"
|
|
||||||
# Allows ESP device to be automatically linked to an 'Area' in Home Assistant. Typically used for areas such as 'Lounge Room', 'Kitchen' etc
|
|
||||||
room: "Hallway"
|
|
||||||
# Description as appears in ESPHome & top of webserver page
|
|
||||||
device_description: "Hallway Light Switch"
|
|
||||||
# Project Name
|
|
||||||
project_name: "Athom Technology.Mini Relay V2"
|
|
||||||
# Projection version denotes the release version of the yaml file, allowing checking of deployed vs latest version
|
|
||||||
project_version: "v2.0.4"
|
|
||||||
# Restore the relay (GPO switch) upon reboot to state:
|
|
||||||
light_restore_mode: RESTORE_DEFAULT_OFF
|
|
||||||
# Set the update interval for sensors
|
|
||||||
sensor_update_interval: 10s
|
|
||||||
# Current Limit in Amps.
|
|
||||||
current_limit : "10"
|
|
||||||
# Define a domain for this device to use. i.e. iot.home.lan (so device will appear as athom-smart-plug-v2.iot.home.lan in DNS/DHCP logs)
|
|
||||||
dns_domain: ".cloonar.smart"
|
|
||||||
# Set timezone of the smart plug. Useful if the plug is in a location different to the HA server. Can be entered in unix Country/Area format (i.e. "Australia/Sydney")
|
|
||||||
timezone: ""
|
|
||||||
# Set the duration between the sntp service polling ntp.org servers for an update
|
|
||||||
sntp_update_interval: 6h
|
|
||||||
# Network time servers for your region, enter from lowest to highest priority. To use local servers update as per zones or countries at: https://www.ntppool.org/zone/@
|
|
||||||
sntp_server_1: "0.pool.ntp.org"
|
|
||||||
sntp_server_2: "1.pool.ntp.org"
|
|
||||||
sntp_server_3: "2.pool.ntp.org"
|
|
||||||
# Enables faster network connections, with last connected SSID being connected to and no full scan for SSID being undertaken
|
|
||||||
wifi_fast_connect: "false"
|
|
||||||
# Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
|
||||||
log_level: "WARN"
|
|
||||||
# Hide the ENERGY sensor that shows kWh consumed, but with no time period associated with it. Resets when device restarted and reflashed.
|
|
||||||
hide_energy_sensor: "true"
|
|
||||||
# Enable or disable the use of IPv6 networking on the device
|
|
||||||
ipv6_enable: "false"
|
|
||||||
|
|
||||||
esphome:
|
|
||||||
name: "${name}"
|
|
||||||
friendly_name: "${friendly_name}"
|
|
||||||
comment: "${device_description}"
|
|
||||||
area: "${room}"
|
|
||||||
name_add_mac_suffix: false
|
|
||||||
min_version: 2024.5.0
|
|
||||||
project:
|
|
||||||
name: "${project_name}"
|
|
||||||
version: "${project_version}"
|
|
||||||
platformio_options:
|
|
||||||
board_build.mcu: esp32c3
|
|
||||||
board_build.variant: esp32c3
|
|
||||||
board_build.flash_mode: dio
|
|
||||||
|
|
||||||
esp32:
|
|
||||||
board: esp32-c3-devkitm-1
|
|
||||||
flash_size: 4MB
|
|
||||||
variant: ESP32C3
|
|
||||||
framework:
|
|
||||||
type: arduino
|
|
||||||
version: recommended
|
|
||||||
|
|
||||||
preferences:
|
|
||||||
flash_write_interval: 5min
|
|
||||||
|
|
||||||
api:
|
|
||||||
|
|
||||||
ota:
|
|
||||||
- platform: esphome
|
|
||||||
|
|
||||||
mdns:
|
|
||||||
disabled: false
|
|
||||||
|
|
||||||
web_server:
|
|
||||||
port: 80
|
|
||||||
|
|
||||||
network:
|
|
||||||
enable_ipv6: ${ipv6_enable}
|
|
||||||
|
|
||||||
wifi:
|
|
||||||
ssid: !secret wifi_ssid
|
|
||||||
password: !secret wifi_password
|
|
||||||
fast_connect: True
|
|
||||||
domain: ${dns_domain}
|
|
||||||
|
|
||||||
esp32_improv:
|
|
||||||
authorizer: none
|
|
||||||
|
|
||||||
uart:
|
|
||||||
rx_pin: GPIO20
|
|
||||||
baud_rate: 4800
|
|
||||||
data_bits: 8
|
|
||||||
stop_bits: 1
|
|
||||||
parity: EVEN
|
|
||||||
|
|
||||||
globals:
|
|
||||||
- id: total_energy
|
|
||||||
type: float
|
|
||||||
restore_value: yes
|
|
||||||
initial_value: '0.0'
|
|
||||||
|
|
||||||
binary_sensor:
|
|
||||||
- platform: status
|
|
||||||
name: "Status"
|
|
||||||
entity_category: diagnostic
|
|
||||||
|
|
||||||
- platform: gpio
|
|
||||||
pin:
|
|
||||||
number: GPIO3
|
|
||||||
mode: INPUT_PULLUP
|
|
||||||
inverted: true
|
|
||||||
name: "Power Button"
|
|
||||||
disabled_by_default: true
|
|
||||||
on_multi_click:
|
|
||||||
- timing:
|
|
||||||
- ON for at most 1s
|
|
||||||
- OFF for at least 0.2s
|
|
||||||
then:
|
|
||||||
- light.toggle: mini_relay
|
|
||||||
- timing:
|
|
||||||
- ON for at least 4s
|
|
||||||
then:
|
|
||||||
- button.press: Reset
|
|
||||||
|
|
||||||
- platform: gpio
|
|
||||||
id: the_switch
|
|
||||||
name: "Power Switch"
|
|
||||||
pin:
|
|
||||||
number: GPIO4
|
|
||||||
mode: INPUT_PULLUP
|
|
||||||
inverted: true
|
|
||||||
on_multi_click:
|
|
||||||
- timing:
|
|
||||||
- ON for at most 1s
|
|
||||||
then:
|
|
||||||
- light.toggle: mini_relay
|
|
||||||
|
|
||||||
sensor:
|
|
||||||
- platform: uptime
|
|
||||||
name: "Uptime Sensor"
|
|
||||||
id: uptime_sensor
|
|
||||||
entity_category: diagnostic
|
|
||||||
internal: true
|
|
||||||
|
|
||||||
- platform: wifi_signal
|
|
||||||
name: "WiFi Signal dB"
|
|
||||||
id: wifi_signal_db
|
|
||||||
update_interval: 60s
|
|
||||||
entity_category: "diagnostic"
|
|
||||||
|
|
||||||
- platform: copy
|
|
||||||
source_id: wifi_signal_db
|
|
||||||
name: "WiFi Signal Percent"
|
|
||||||
filters:
|
|
||||||
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
|
|
||||||
unit_of_measurement: "Signal %"
|
|
||||||
entity_category: "diagnostic"
|
|
||||||
device_class: ""
|
|
||||||
|
|
||||||
- platform: cse7766
|
|
||||||
id: athom_cse7766
|
|
||||||
current:
|
|
||||||
name: "Current"
|
|
||||||
filters:
|
|
||||||
- throttle_average: ${sensor_update_interval}
|
|
||||||
- lambda: if (x < 0.060) return 0.0; else return x; #For the chip will report less than 3w power when no load is connected
|
|
||||||
on_value_range:
|
|
||||||
- above: ${current_limit}
|
|
||||||
then:
|
|
||||||
- light.turn_off: mini_relay
|
|
||||||
|
|
||||||
voltage:
|
|
||||||
name: "Voltage"
|
|
||||||
filters:
|
|
||||||
- throttle_average: ${sensor_update_interval}
|
|
||||||
|
|
||||||
power:
|
|
||||||
name: "Power"
|
|
||||||
id: power_sensor
|
|
||||||
filters:
|
|
||||||
- throttle_average: ${sensor_update_interval}
|
|
||||||
- lambda: if (x < 3.0) return 0.0; else return x; #For the chip will report less than 3w power when no load is connected
|
|
||||||
|
|
||||||
energy:
|
|
||||||
name: "Energy"
|
|
||||||
id: energy
|
|
||||||
unit_of_measurement: kWh
|
|
||||||
filters:
|
|
||||||
- throttle: ${sensor_update_interval}
|
|
||||||
# Multiplication factor from W to kW is 0.001
|
|
||||||
- multiply: 0.001
|
|
||||||
on_value:
|
|
||||||
then:
|
|
||||||
- lambda: |-
|
|
||||||
static float previous_energy_value = 0.0;
|
|
||||||
float current_energy_value = id(energy).state;
|
|
||||||
id(total_energy) += current_energy_value - previous_energy_value;
|
|
||||||
previous_energy_value = current_energy_value;
|
|
||||||
id(total_energy_sensor).update();
|
|
||||||
|
|
||||||
apparent_power:
|
|
||||||
name: "Apparent Power"
|
|
||||||
filters:
|
|
||||||
- throttle_average: ${sensor_update_interval}
|
|
||||||
reactive_power:
|
|
||||||
name: "Reactive Power"
|
|
||||||
filters:
|
|
||||||
- throttle_average: ${sensor_update_interval}
|
|
||||||
power_factor:
|
|
||||||
name: "Power Factor"
|
|
||||||
filters:
|
|
||||||
- throttle_average: ${sensor_update_interval}
|
|
||||||
|
|
||||||
- platform: template
|
|
||||||
name: "Total Energy"
|
|
||||||
id: total_energy_sensor
|
|
||||||
unit_of_measurement: kWh
|
|
||||||
device_class: "energy"
|
|
||||||
state_class: "total_increasing"
|
|
||||||
icon: "mdi:lightning-bolt"
|
|
||||||
accuracy_decimals: 3
|
|
||||||
lambda: |-
|
|
||||||
return id(total_energy);
|
|
||||||
update_interval: ${sensor_update_interval}
|
|
||||||
|
|
||||||
- platform: total_daily_energy
|
|
||||||
name: "Total Energy Today"
|
|
||||||
restore: true
|
|
||||||
power_id: power_sensor
|
|
||||||
unit_of_measurement: kWh
|
|
||||||
accuracy_decimals: 3
|
|
||||||
filters:
|
|
||||||
- multiply: 0.001
|
|
||||||
|
|
||||||
button:
|
|
||||||
- platform: restart
|
|
||||||
name: "Restart"
|
|
||||||
entity_category: config
|
|
||||||
|
|
||||||
- platform: factory_reset
|
|
||||||
name: "Factory Reset"
|
|
||||||
id: Reset
|
|
||||||
entity_category: config
|
|
||||||
|
|
||||||
- platform: safe_mode
|
|
||||||
name: "Safe Mode"
|
|
||||||
internal: false
|
|
||||||
entity_category: config
|
|
||||||
|
|
||||||
output:
|
|
||||||
- platform: gpio
|
|
||||||
id: relay_output
|
|
||||||
pin: GPIO6
|
|
||||||
|
|
||||||
light:
|
|
||||||
- platform: status_led
|
|
||||||
id: led
|
|
||||||
name: "Blue LED"
|
|
||||||
disabled_by_default: true
|
|
||||||
pin:
|
|
||||||
number: GPIO7
|
|
||||||
inverted: true
|
|
||||||
|
|
||||||
- platform: binary
|
|
||||||
id: mini_relay
|
|
||||||
output: relay_output
|
|
||||||
name: "Mini Switch"
|
|
||||||
restore_mode: ${light_restore_mode}
|
|
||||||
on_turn_on:
|
|
||||||
- light.turn_on: led
|
|
||||||
on_turn_off:
|
|
||||||
- light.turn_off: led
|
|
||||||
|
|
||||||
text_sensor:
|
|
||||||
- platform: wifi_info
|
|
||||||
ip_address:
|
|
||||||
name: "IP Address"
|
|
||||||
entity_category: diagnostic
|
|
||||||
ssid:
|
|
||||||
name: "Connected SSID"
|
|
||||||
entity_category: diagnostic
|
|
||||||
mac_address:
|
|
||||||
name: "Mac Address"
|
|
||||||
entity_category: diagnostic
|
|
||||||
|
|
||||||
# Creates a sensor showing when the device was last restarted
|
|
||||||
- platform: template
|
|
||||||
name: 'Last Restart'
|
|
||||||
id: device_last_restart
|
|
||||||
icon: mdi:clock
|
|
||||||
entity_category: diagnostic
|
|
||||||
# device_class: timestamp
|
|
||||||
|
|
||||||
# Creates a sensor of the uptime of the device, in formatted days, hours, minutes and seconds
|
|
||||||
- platform: template
|
|
||||||
name: "Uptime"
|
|
||||||
entity_category: diagnostic
|
|
||||||
lambda: |-
|
|
||||||
int seconds = (id(uptime_sensor).state);
|
|
||||||
int days = seconds / (24 * 3600);
|
|
||||||
seconds = seconds % (24 * 3600);
|
|
||||||
int hours = seconds / 3600;
|
|
||||||
seconds = seconds % 3600;
|
|
||||||
int minutes = seconds / 60;
|
|
||||||
seconds = seconds % 60;
|
|
||||||
if ( days > 3650 ) {
|
|
||||||
return { "Starting up" };
|
|
||||||
} else if ( days ) {
|
|
||||||
return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
|
|
||||||
} else if ( hours ) {
|
|
||||||
return { (String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
|
|
||||||
} else if ( minutes ) {
|
|
||||||
return { (String(minutes) +"m "+ String(seconds) +"s").c_str() };
|
|
||||||
} else {
|
|
||||||
return { (String(seconds) +"s").c_str() };
|
|
||||||
}
|
|
||||||
icon: mdi:clock-start
|
|
||||||
|
|
||||||
time:
|
|
||||||
- platform: sntp
|
|
||||||
id: sntp_time
|
|
||||||
# Define the timezone of the device
|
|
||||||
timezone: "${timezone}"
|
|
||||||
# Change sync interval from default 5min to 6 hours (or as set in substitutions)
|
|
||||||
update_interval: ${sntp_update_interval}
|
|
||||||
# Set specific sntp servers to use
|
|
||||||
servers:
|
|
||||||
- "${sntp_server_1}"
|
|
||||||
- "${sntp_server_2}"
|
|
||||||
- "${sntp_server_3}"
|
|
||||||
# Publish the time the device was last restarted
|
|
||||||
on_time_sync:
|
|
||||||
then:
|
|
||||||
# Update last restart time, but only once.
|
|
||||||
- if:
|
|
||||||
condition:
|
|
||||||
lambda: 'return id(device_last_restart).state == "";'
|
|
||||||
then:
|
|
||||||
- text_sensor.template.publish:
|
|
||||||
id: device_last_restart
|
|
||||||
state: !lambda 'return id(sntp_time).now().strftime("%a %d %b %Y - %I:%M:%S %p");'
|
|
||||||
|
|
@ -10,6 +10,7 @@ substitutions:
|
||||||
sntp_server_1: "0.pool.ntp.org"
|
sntp_server_1: "0.pool.ntp.org"
|
||||||
sntp_server_2: "1.pool.ntp.org"
|
sntp_server_2: "1.pool.ntp.org"
|
||||||
sntp_server_3: "2.pool.ntp.org"
|
sntp_server_3: "2.pool.ntp.org"
|
||||||
|
log_level: "WARN"
|
||||||
|
|
||||||
esphome:
|
esphome:
|
||||||
name: "${name}"
|
name: "${name}"
|
||||||
|
|
@ -22,27 +23,27 @@ esphome:
|
||||||
name: "${project_name}"
|
name: "${project_name}"
|
||||||
version: "${project_version}"
|
version: "${project_version}"
|
||||||
on_boot:
|
on_boot:
|
||||||
then:
|
then:
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: rgbww_light
|
id: rgbww_light
|
||||||
- delay: 100ms
|
- delay: 100ms
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: rgbww_light
|
id: rgbww_light
|
||||||
brightness: 20%
|
brightness: 20%
|
||||||
- delay: 100ms
|
- delay: 100ms
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: rgbww_light
|
id: rgbww_light
|
||||||
red: 100%
|
red: 100%
|
||||||
green: 50%
|
green: 50%
|
||||||
blue: 0%
|
blue: 0%
|
||||||
white: 100%
|
white: 100%
|
||||||
|
|
||||||
interval:
|
interval:
|
||||||
- interval: 15s
|
- interval: 15s
|
||||||
then:
|
then:
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
api.connected:
|
api.connected: # check if api connected
|
||||||
else:
|
else:
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
id: rgbww_light
|
id: rgbww_light
|
||||||
|
|
@ -60,31 +61,21 @@ api:
|
||||||
ota:
|
ota:
|
||||||
- platform: esphome
|
- platform: esphome
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
mdns:
|
||||||
|
disabled: false
|
||||||
|
|
||||||
wifi:
|
wifi:
|
||||||
# Disable fast_connect so we do a full scan (required for hidden SSIDs)
|
ssid: !secret wifi_ssid
|
||||||
fast_connect: false
|
password: !secret wifi_password
|
||||||
domain: "${dns_domain}"
|
fast_connect: True
|
||||||
|
domain: .cloonar.smart
|
||||||
|
|
||||||
# Your hidden network
|
captive_portal:
|
||||||
networks:
|
|
||||||
- ssid: !secret wifi_ssid
|
|
||||||
password: !secret wifi_password
|
|
||||||
channel: 1
|
|
||||||
hidden: true
|
|
||||||
|
|
||||||
manual_ip:
|
dashboard_import:
|
||||||
static_ip: 10.42.100.11
|
package_import_url: github://athom-tech/athom-configs/athom-rgbww-light.yaml
|
||||||
gateway: 10.42.100.1
|
|
||||||
subnet: 255.255.255.0
|
|
||||||
dns1: 8.8.8.8
|
|
||||||
dns2: 1.1.1.1
|
|
||||||
|
|
||||||
# Fallback access point if Wi-Fi fails
|
|
||||||
ap:
|
|
||||||
ssid: "${name}_AP"
|
|
||||||
password: "bulb_fallback_pw"
|
|
||||||
ap_timeout: 2min # after 2 min of failed join, enable AP
|
|
||||||
reboot_timeout: 5min # if still not joined after 5 min, reboot and retry
|
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: status
|
- platform: status
|
||||||
|
|
@ -102,7 +93,7 @@ sensor:
|
||||||
name: "WiFi Signal dB"
|
name: "WiFi Signal dB"
|
||||||
id: wifi_signal_db
|
id: wifi_signal_db
|
||||||
update_interval: 60s
|
update_interval: 60s
|
||||||
entity_category: diagnostic
|
entity_category: "diagnostic"
|
||||||
|
|
||||||
- platform: copy
|
- platform: copy
|
||||||
source_id: wifi_signal_db
|
source_id: wifi_signal_db
|
||||||
|
|
@ -110,7 +101,23 @@ sensor:
|
||||||
filters:
|
filters:
|
||||||
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
|
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
|
||||||
unit_of_measurement: "Signal %"
|
unit_of_measurement: "Signal %"
|
||||||
entity_category: diagnostic
|
entity_category: "diagnostic"
|
||||||
|
device_class: ""
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: restart
|
||||||
|
name: "Restart"
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: factory_reset
|
||||||
|
name: "Factory Reset"
|
||||||
|
id: Reset
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: safe_mode
|
||||||
|
name: "Safe Mode"
|
||||||
|
internal: false
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
|
|
@ -164,51 +171,59 @@ text_sensor:
|
||||||
name: "Mac Address"
|
name: "Mac Address"
|
||||||
entity_category: diagnostic
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
# Creates a sensor showing when the device was last restarted
|
||||||
- platform: template
|
- platform: template
|
||||||
name: 'Last Restart'
|
name: 'Last Restart'
|
||||||
id: device_last_restart
|
id: device_last_restart
|
||||||
icon: mdi:clock
|
icon: mdi:clock
|
||||||
entity_category: diagnostic
|
entity_category: diagnostic
|
||||||
|
# device_class: timestamp
|
||||||
|
|
||||||
|
# Creates a sensor of the uptime of the device, in formatted days, hours, minutes and seconds
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "Uptime"
|
name: "Uptime"
|
||||||
entity_category: diagnostic
|
entity_category: diagnostic
|
||||||
lambda: |-
|
lambda: |-
|
||||||
int seconds = (id(uptime_sensor).state);
|
int seconds = (id(uptime_sensor).state);
|
||||||
int days = seconds / (24 * 3600);
|
int days = seconds / (24 * 3600);
|
||||||
seconds %= (24 * 3600);
|
seconds = seconds % (24 * 3600);
|
||||||
int hours = seconds / 3600;
|
int hours = seconds / 3600;
|
||||||
seconds %= 3600;
|
seconds = seconds % 3600;
|
||||||
int minutes = seconds / 60;
|
int minutes = seconds / 60;
|
||||||
seconds %= 60;
|
seconds = seconds % 60;
|
||||||
if (days > 3650) {
|
if ( days > 3650 ) {
|
||||||
return { "Starting up" };
|
return { "Starting up" };
|
||||||
} else if (days) {
|
} else if ( days ) {
|
||||||
return { (String(days) + "d " + String(hours) + "h " + String(minutes) + "m " + String(seconds) + "s").c_str() };
|
return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
|
||||||
} else if (hours) {
|
} else if ( hours ) {
|
||||||
return { (String(hours) + "h " + String(minutes) + "m " + String(seconds) + "s").c_str() };
|
return { (String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
|
||||||
} else if (minutes) {
|
} else if ( minutes ) {
|
||||||
return { (String(minutes) + "m " + String(seconds) + "s").c_str() };
|
return { (String(minutes) +"m "+ String(seconds) +"s").c_str() };
|
||||||
} else {
|
} else {
|
||||||
return { (String(seconds) + "s").c_str() };
|
return { (String(seconds) +"s").c_str() };
|
||||||
}
|
}
|
||||||
icon: mdi:clock-start
|
icon: mdi:clock-start
|
||||||
|
|
||||||
time:
|
time:
|
||||||
- platform: sntp
|
- platform: sntp
|
||||||
id: sntp_time
|
id: sntp_time
|
||||||
|
# Define the timezone of the device
|
||||||
timezone: "${timezone}"
|
timezone: "${timezone}"
|
||||||
|
# Change sync interval from default 5min to 6 hours (or as set in substitutions)
|
||||||
update_interval: ${sntp_update_interval}
|
update_interval: ${sntp_update_interval}
|
||||||
|
# Set specific sntp servers to use
|
||||||
servers:
|
servers:
|
||||||
- "${sntp_server_1}"
|
- "${sntp_server_1}"
|
||||||
- "${sntp_server_2}"
|
- "${sntp_server_2}"
|
||||||
- "${sntp_server_3}"
|
- "${sntp_server_3}"
|
||||||
|
# Publish the time the device was last restarted
|
||||||
on_time_sync:
|
on_time_sync:
|
||||||
then:
|
then:
|
||||||
|
# Update last restart time, but only once.
|
||||||
- if:
|
- if:
|
||||||
condition:
|
condition:
|
||||||
lambda: 'return id(device_last_restart).state == "";'
|
lambda: 'return id(device_last_restart).state == "";'
|
||||||
then:
|
then:
|
||||||
- text_sensor.template.publish:
|
- text_sensor.template.publish:
|
||||||
id: device_last_restart
|
id: device_last_restart
|
||||||
state: !lambda 'return id(sntp_time).now().strftime("%a %d %b %Y - %I:%M:%S %p");'
|
state: !lambda 'return id(sntp_time).now().strftime("%a %d %b %Y - %I:%M:%S %p");'
|
||||||
|
|
@ -61,18 +61,21 @@ api:
|
||||||
ota:
|
ota:
|
||||||
- platform: esphome
|
- platform: esphome
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
mdns:
|
||||||
|
disabled: false
|
||||||
|
|
||||||
wifi:
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
fast_connect: True
|
||||||
domain: .cloonar.smart
|
domain: .cloonar.smart
|
||||||
fast_connect: False
|
|
||||||
networks:
|
captive_portal:
|
||||||
- ssid: !secret wifi_ssid
|
|
||||||
password: !secret wifi_password
|
dashboard_import:
|
||||||
channel: 1
|
package_import_url: github://athom-tech/athom-configs/athom-rgbww-light.yaml
|
||||||
hidden: True
|
|
||||||
manual_ip:
|
|
||||||
static_ip: 10.42.100.12
|
|
||||||
gateway: 10.42.100.1
|
|
||||||
subnet: 255.255.255.0
|
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: status
|
- platform: status
|
||||||
|
|
@ -101,6 +104,21 @@ sensor:
|
||||||
entity_category: "diagnostic"
|
entity_category: "diagnostic"
|
||||||
device_class: ""
|
device_class: ""
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: restart
|
||||||
|
name: "Restart"
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: factory_reset
|
||||||
|
name: "Factory Reset"
|
||||||
|
id: Reset
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: safe_mode
|
||||||
|
name: "Safe Mode"
|
||||||
|
internal: false
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: red_output
|
id: red_output
|
||||||
|
|
|
||||||
|
|
@ -72,18 +72,21 @@ api:
|
||||||
ota:
|
ota:
|
||||||
- platform: esphome
|
- platform: esphome
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
mdns:
|
||||||
|
disabled: false
|
||||||
|
|
||||||
wifi:
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
fast_connect: True
|
||||||
domain: .cloonar.smart
|
domain: .cloonar.smart
|
||||||
fast_connect: False
|
|
||||||
networks:
|
captive_portal:
|
||||||
- ssid: !secret wifi_ssid
|
|
||||||
password: !secret wifi_password
|
dashboard_import:
|
||||||
hidden: True
|
package_import_url: github://athom-tech/athom-configs/athom-rgbww-light.yaml
|
||||||
channel: 1
|
|
||||||
manual_ip:
|
|
||||||
static_ip: 10.42.100.13
|
|
||||||
gateway: 10.42.100.1
|
|
||||||
subnet: 255.255.255.0
|
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: status
|
- platform: status
|
||||||
|
|
@ -112,6 +115,21 @@ sensor:
|
||||||
entity_category: "diagnostic"
|
entity_category: "diagnostic"
|
||||||
device_class: ""
|
device_class: ""
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: restart
|
||||||
|
name: "Restart"
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: factory_reset
|
||||||
|
name: "Factory Reset"
|
||||||
|
id: Reset
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: safe_mode
|
||||||
|
name: "Safe Mode"
|
||||||
|
internal: false
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: red_output
|
id: red_output
|
||||||
|
|
|
||||||
|
|
@ -72,17 +72,21 @@ api:
|
||||||
ota:
|
ota:
|
||||||
- platform: esphome
|
- platform: esphome
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
mdns:
|
||||||
|
disabled: false
|
||||||
|
|
||||||
wifi:
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
fast_connect: True
|
||||||
domain: .cloonar.smart
|
domain: .cloonar.smart
|
||||||
fast_connect: False
|
|
||||||
networks:
|
captive_portal:
|
||||||
- ssid: !secret wifi_ssid
|
|
||||||
password: !secret wifi_password
|
dashboard_import:
|
||||||
hidden: True
|
package_import_url: github://athom-tech/athom-configs/athom-rgbww-light.yaml
|
||||||
manual_ip:
|
|
||||||
static_ip: 10.42.100.14
|
|
||||||
gateway: 10.42.100.1
|
|
||||||
subnet: 255.255.255.0
|
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: status
|
- platform: status
|
||||||
|
|
@ -111,6 +115,21 @@ sensor:
|
||||||
entity_category: "diagnostic"
|
entity_category: "diagnostic"
|
||||||
device_class: ""
|
device_class: ""
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: restart
|
||||||
|
name: "Restart"
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: factory_reset
|
||||||
|
name: "Factory Reset"
|
||||||
|
id: Reset
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: safe_mode
|
||||||
|
name: "Safe Mode"
|
||||||
|
internal: false
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: red_output
|
id: red_output
|
||||||
|
|
|
||||||
|
|
@ -72,17 +72,21 @@ api:
|
||||||
ota:
|
ota:
|
||||||
- platform: esphome
|
- platform: esphome
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
mdns:
|
||||||
|
disabled: false
|
||||||
|
|
||||||
wifi:
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
fast_connect: True
|
||||||
domain: .cloonar.smart
|
domain: .cloonar.smart
|
||||||
fast_connect: False
|
|
||||||
networks:
|
captive_portal:
|
||||||
- ssid: !secret wifi_ssid
|
|
||||||
password: !secret wifi_password
|
dashboard_import:
|
||||||
hidden: True
|
package_import_url: github://athom-tech/athom-configs/athom-rgbww-light.yaml
|
||||||
manual_ip:
|
|
||||||
static_ip: 10.42.100.15
|
|
||||||
gateway: 10.42.100.1
|
|
||||||
subnet: 255.255.255.0
|
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: status
|
- platform: status
|
||||||
|
|
@ -111,6 +115,21 @@ sensor:
|
||||||
entity_category: "diagnostic"
|
entity_category: "diagnostic"
|
||||||
device_class: ""
|
device_class: ""
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: restart
|
||||||
|
name: "Restart"
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: factory_reset
|
||||||
|
name: "Factory Reset"
|
||||||
|
id: Reset
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: safe_mode
|
||||||
|
name: "Safe Mode"
|
||||||
|
internal: false
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: red_output
|
id: red_output
|
||||||
|
|
|
||||||
|
|
@ -72,18 +72,21 @@ api:
|
||||||
ota:
|
ota:
|
||||||
- platform: esphome
|
- platform: esphome
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
mdns:
|
||||||
|
disabled: false
|
||||||
|
|
||||||
wifi:
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
fast_connect: True
|
||||||
domain: .cloonar.smart
|
domain: .cloonar.smart
|
||||||
fast_connect: False
|
|
||||||
networks:
|
captive_portal:
|
||||||
- ssid: !secret wifi_ssid
|
|
||||||
password: !secret wifi_password
|
dashboard_import:
|
||||||
hidden: True
|
package_import_url: github://athom-tech/athom-configs/athom-rgbww-light.yaml
|
||||||
channel: 1
|
|
||||||
manual_ip:
|
|
||||||
static_ip: 10.42.100.16
|
|
||||||
gateway: 10.42.100.1
|
|
||||||
subnet: 255.255.255.0
|
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: status
|
- platform: status
|
||||||
|
|
@ -112,6 +115,21 @@ sensor:
|
||||||
entity_category: "diagnostic"
|
entity_category: "diagnostic"
|
||||||
device_class: ""
|
device_class: ""
|
||||||
|
|
||||||
|
button:
|
||||||
|
- platform: restart
|
||||||
|
name: "Restart"
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: factory_reset
|
||||||
|
name: "Factory Reset"
|
||||||
|
id: Reset
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
- platform: safe_mode
|
||||||
|
name: "Safe Mode"
|
||||||
|
internal: false
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
output:
|
output:
|
||||||
- platform: esp8266_pwm
|
- platform: esp8266_pwm
|
||||||
id: red_output
|
id: red_output
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,8 @@
|
||||||
./modules/networking.nix
|
./modules/networking.nix
|
||||||
./modules/setupnetwork.nix
|
./modules/setupnetwork.nix
|
||||||
./modules/firewall.nix
|
./modules/firewall.nix
|
||||||
# ./modules/dhcp4.nix
|
./modules/dhcp4.nix
|
||||||
# ./modules/unbound.nix
|
./modules/unbound.nix
|
||||||
|
|
||||||
./modules/dnsmasq.nix
|
|
||||||
./modules/avahi.nix
|
./modules/avahi.nix
|
||||||
./modules/openconnect.nix
|
./modules/openconnect.nix
|
||||||
./modules/wireguard.nix
|
./modules/wireguard.nix
|
||||||
|
|
@ -35,7 +33,7 @@
|
||||||
# ./modules/vscode-server.nix # Add VS Code Server microvm
|
# ./modules/vscode-server.nix # Add VS Code Server microvm
|
||||||
|
|
||||||
./modules/ai-mailer.nix
|
./modules/ai-mailer.nix
|
||||||
# ./modules/wazuh.nix
|
./modules/wazuh.nix
|
||||||
|
|
||||||
# web
|
# web
|
||||||
./modules/web
|
./modules/web
|
||||||
|
|
@ -54,8 +52,7 @@
|
||||||
./modules/deconz.nix
|
./modules/deconz.nix
|
||||||
# ./modules/mopidy.nix
|
# ./modules/mopidy.nix
|
||||||
# ./modules/mosquitto.nix
|
# ./modules/mosquitto.nix
|
||||||
# ./modules/snapserver.nix
|
./modules/snapserver.nix
|
||||||
./modules/lms.nix
|
|
||||||
|
|
||||||
# gaming
|
# gaming
|
||||||
# ./modules/palworld.nix
|
# ./modules/palworld.nix
|
||||||
|
|
|
||||||
|
|
@ -1,160 +0,0 @@
|
||||||
{ config, ... }: {
|
|
||||||
services.resolved.enable = false;
|
|
||||||
|
|
||||||
services.dnsmasq = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
port = "53";
|
|
||||||
bind-interfaces = true; # force dnsmasq to bind immediately
|
|
||||||
expand-hosts = true;
|
|
||||||
|
|
||||||
log-dhcp = true;
|
|
||||||
|
|
||||||
server = [
|
|
||||||
"/epicenter.works/10.50.60.1"
|
|
||||||
"/akvorrat.at/10.50.60.1"
|
|
||||||
"9.9.9.9"
|
|
||||||
"149.112.112.11"
|
|
||||||
];
|
|
||||||
|
|
||||||
interface = [
|
|
||||||
"lan"
|
|
||||||
"server"
|
|
||||||
"infrastructure"
|
|
||||||
"multimedia"
|
|
||||||
"guest"
|
|
||||||
"smart"
|
|
||||||
];
|
|
||||||
|
|
||||||
domain = [
|
|
||||||
"cloonar.com,lan"
|
|
||||||
"cloonar.com,server"
|
|
||||||
"cloonar.com,infrastructure"
|
|
||||||
"cloonar.multimedia,multimedia"
|
|
||||||
"cloonar.smart,smart"
|
|
||||||
"cloonar.guest,guest"
|
|
||||||
];
|
|
||||||
|
|
||||||
dhcp-option = [
|
|
||||||
"lan,15,cloonar.com" # domain name
|
|
||||||
"lan,3,${config.networkPrefix}.96.1" # Gateway
|
|
||||||
"lan,6,${config.networkPrefix}.96.1" # DNS
|
|
||||||
"server,15,cloonar.com"
|
|
||||||
"server,3,${config.networkPrefix}.97.1"
|
|
||||||
"server,6,${config.networkPrefix}.97.1"
|
|
||||||
"infrastructure,15,cloonar.com"
|
|
||||||
"infrastructure,3,${config.networkPrefix}.101.1"
|
|
||||||
"infrastructure,6,${config.networkPrefix}.101.1"
|
|
||||||
"multimedia,15,cloonar.multimedia"
|
|
||||||
"multimedia,3,${config.networkPrefix}.99.1"
|
|
||||||
"multimedia,6,${config.networkPrefix}.99.1"
|
|
||||||
"smart,15,cloonar.smart"
|
|
||||||
"smart,3,${config.networkPrefix}.100.1"
|
|
||||||
"smart,6,${config.networkPrefix}.100.1"
|
|
||||||
"guest,15,cloonar.guest"
|
|
||||||
"guest,3,${config.networkPrefix}.254.1"
|
|
||||||
"guest,6,9.9.9.9"
|
|
||||||
];
|
|
||||||
|
|
||||||
dhcp-range = [
|
|
||||||
"lan,${config.networkPrefix}.96.100,${config.networkPrefix}.96.200,24h"
|
|
||||||
"server,${config.networkPrefix}.97.100,${config.networkPrefix}.97.200,24h"
|
|
||||||
"infrastructure,${config.networkPrefix}.101.100,${config.networkPrefix}.101.200,24h"
|
|
||||||
"multimedia,${config.networkPrefix}.99.100,${config.networkPrefix}.99.200,24h"
|
|
||||||
"smart,${config.networkPrefix}.100.100,${config.networkPrefix}.100.200,24h"
|
|
||||||
"guest,${config.networkPrefix}.254.100,${config.networkPrefix}.254.200,24h"
|
|
||||||
];
|
|
||||||
|
|
||||||
dhcp-host = [
|
|
||||||
"30:05:5c:56:62:37,${config.networkPrefix}.96.100,brn30055c566237"
|
|
||||||
"24:df:a7:b1:1b:74,${config.networkPrefix}.96.101,rmproplus-b1-1b-74"
|
|
||||||
|
|
||||||
"1a:c4:04:6e:29:bd,${config.networkPrefix}.97.2,omada"
|
|
||||||
"02:00:00:00:00:03,${config.networkPrefix}.97.5,web-02"
|
|
||||||
"02:00:00:00:00:04,${config.networkPrefix}.97.6,matrix"
|
|
||||||
"ea:db:d4:c1:18:ba,${config.networkPrefix}.97.50,git"
|
|
||||||
"c2:4f:64:dd:13:0c,${config.networkPrefix}.97.20,home-assistant"
|
|
||||||
"1a:c4:04:6e:29:02,${config.networkPrefix}.101.25,deconz"
|
|
||||||
|
|
||||||
"c4:a7:2b:c7:ea:30,${config.networkPrefix}.99.10,metz"
|
|
||||||
"f0:2f:9e:d4:3b:21,${config.networkPrefix}.99.11,firetv-living"
|
|
||||||
"e4:2a:ac:32:3f:79,${config.networkPrefix}.99.13,xbox"
|
|
||||||
"f0:2f:9e:c1:74:72,${config.networkPrefix}.99.21,firetv-bedroom"
|
|
||||||
"30:05:5c:56:62:37,${config.networkPrefix}.99.100,brn30055c566237"
|
|
||||||
|
|
||||||
"fc:ee:28:03:63:e9,${config.networkPrefix}.100.148,k1c"
|
|
||||||
"cc:50:e3:bc:27:64,${config.networkPrefix}.100.112,Nuki_Bridge_1A753F72"
|
|
||||||
"34:6f:24:f3:af:ad,${config.networkPrefix}.100.137,daikin86604"
|
|
||||||
"34:6f:24:c1:f8:54,${config.networkPrefix}.100.139,daikin53800"
|
|
||||||
];
|
|
||||||
|
|
||||||
address = [
|
|
||||||
"/fw.cloonar.com/${config.networkPrefix}.97.1"
|
|
||||||
"/omada.cloonar.com/${config.networkPrefix}.97.2"
|
|
||||||
"/pc.cloonar.com/${config.networkPrefix}.96.5"
|
|
||||||
"/home-assistant.cloonar.com/${config.networkPrefix}.97.20"
|
|
||||||
"/mopidy.cloonar.com/${config.networkPrefix}.97.21"
|
|
||||||
"/snapcast.cloonar.com/${config.networkPrefix}.97.21"
|
|
||||||
"/git.cloonar.com/${config.networkPrefix}.97.50"
|
|
||||||
"/feeds.cloonar.com/188.34.191.144"
|
|
||||||
|
|
||||||
"/stage.wsw.at/10.254.235.22"
|
|
||||||
"/prod.wsw.at/10.254.217.23"
|
|
||||||
"/piwik.wohnservice-wien.at/10.254.240.109"
|
|
||||||
"/wohnberatung-wien.at/10.254.240.109"
|
|
||||||
"/wohnpartner-wien.at/10.254.240.109"
|
|
||||||
"/wohnservice-wien.at/10.254.240.109"
|
|
||||||
"/mieterhilfe.at/10.254.240.109"
|
|
||||||
"/wienbautvor.at/10.254.240.109"
|
|
||||||
"/wienwohntbesser.at/10.254.240.109"
|
|
||||||
"/a.stage.wohnberatung-wien.at/10.254.240.110"
|
|
||||||
"/a.stage.wohnpartner-wien.at/10.254.240.110"
|
|
||||||
"/a.stage.wohnservice-wien.at/10.254.240.110"
|
|
||||||
"/a.stage.mieterhilfe.at/10.254.240.110"
|
|
||||||
"/a.stage.wienbautvor.at/10.254.240.110"
|
|
||||||
"/a.stage.wienwohntbesser.at/10.254.240.110"
|
|
||||||
"/b.stage.wohnberatung-wien.at/10.254.240.110"
|
|
||||||
"/b.stage.wohnpartner-wien.at/10.254.240.110"
|
|
||||||
"/b.stage.wohnservice-wien.at/10.254.240.110"
|
|
||||||
"/b.stage.mieterhilfe.at/10.254.240.110"
|
|
||||||
"/b.stage.wienbautvor.at/10.254.240.110"
|
|
||||||
"/b.stage.wienwohntbesser.at/10.254.240.110"
|
|
||||||
|
|
||||||
"/web.hilgenberg-gmbh.de/91.107.197.169"
|
|
||||||
# gaming
|
|
||||||
"/foundry-vtt.cloonar.com/${config.networkPrefix}.97.5"
|
|
||||||
|
|
||||||
"/deconz.cloonar.multimedia/${config.networkPrefix}.97.22"
|
|
||||||
|
|
||||||
"/ddl-warez.to/172.67.184.30"
|
|
||||||
"/cdnjs.cloudflare.com/104.17.24.14"
|
|
||||||
|
|
||||||
# esphome devices
|
|
||||||
"/livingroom-bulb-1.cloonar.smart/${config.networkPrefix}.100.11"
|
|
||||||
"/livingroom-bulb-2.cloonar.smart/${config.networkPrefix}.100.12"
|
|
||||||
"/livingroom-bulb-3.cloonar.smart/${config.networkPrefix}.100.13"
|
|
||||||
"/livingroom-bulb-4.cloonar.smart/${config.networkPrefix}.100.14"
|
|
||||||
"/livingroom-bulb-5.cloonar.smart/${config.networkPrefix}.100.15"
|
|
||||||
"/livingroom-bulb-6.cloonar.smart/${config.networkPrefix}.100.16"
|
|
||||||
|
|
||||||
"/bedroom-bulb-0.cloonar.smart/${config.networkPrefix}.100.21"
|
|
||||||
"/bedroom-bulb-0.cloonar.smart/${config.networkPrefix}.100.22"
|
|
||||||
"/bedroom-bulb-0.cloonar.smart/${config.networkPrefix}.100.23"
|
|
||||||
"/bedroom-bulb-0.cloonar.smart/${config.networkPrefix}.100.24"
|
|
||||||
|
|
||||||
"/hallway-bulb-0.cloonar.smart/${config.networkPrefix}.100.31"
|
|
||||||
"/hallway-bulb-0.cloonar.smart/${config.networkPrefix}.100.32"
|
|
||||||
|
|
||||||
"/bath-bulb-0.cloonar.smart/${config.networkPrefix}.100.41"
|
|
||||||
"/bath-bulb-0.cloonar.smart/${config.networkPrefix}.100.42"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.dnsmasq = {
|
|
||||||
requires = [ "network-online.target" ];
|
|
||||||
after = [ "network-online.target" ];
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.firewall.allowedUDPPorts = [ 53 67 ];
|
|
||||||
}
|
|
||||||
|
|
@ -8,18 +8,6 @@
|
||||||
"cloonar-fw" = {
|
"cloonar-fw" = {
|
||||||
family = "inet";
|
family = "inet";
|
||||||
content = ''
|
content = ''
|
||||||
chain snap-qos-raw {
|
|
||||||
type filter hook prerouting priority raw; policy accept;
|
|
||||||
tcp dport 1704 counter mark set 10 comment "Mark Snapcast traffic"
|
|
||||||
tcp dport 3483 counter mark set 10 comment "Mark Squezelite traffic"
|
|
||||||
udp dport 3483 counter mark set 10 comment "Mark Squezelite traffic"
|
|
||||||
}
|
|
||||||
|
|
||||||
chain snap-qos-mangle {
|
|
||||||
type filter hook postrouting priority mangle + 10; policy accept;
|
|
||||||
mark 10 counter ip dscp set cs3 comment "Tag Snapcast with CS3"
|
|
||||||
}
|
|
||||||
|
|
||||||
chain output {
|
chain output {
|
||||||
type filter hook output priority 100; policy accept;
|
type filter hook output priority 100; policy accept;
|
||||||
}
|
}
|
||||||
|
|
@ -34,7 +22,6 @@
|
||||||
type filter hook input priority filter; policy drop;
|
type filter hook input priority filter; policy drop;
|
||||||
iifname "lo" accept comment "trusted interfaces"
|
iifname "lo" accept comment "trusted interfaces"
|
||||||
iifname "lan" counter accept comment "Spice"
|
iifname "lan" counter accept comment "Spice"
|
||||||
iifname { "server", "vserver", "vm-*", "lan", "wg_cloonar" } counter accept comment "allow trusted to router"
|
|
||||||
ct state vmap { invalid : drop, established : accept, related : accept, new : jump input-allow, untracked : jump input-allow }
|
ct state vmap { invalid : drop, established : accept, related : accept, new : jump input-allow, untracked : jump input-allow }
|
||||||
tcp flags syn / fin,syn,rst,ack log prefix "refused connection: " level info
|
tcp flags syn / fin,syn,rst,ack log prefix "refused connection: " level info
|
||||||
}
|
}
|
||||||
|
|
@ -47,14 +34,11 @@
|
||||||
iifname "lan" tcp dport 5931 counter accept comment "Spice"
|
iifname "lan" tcp dport 5931 counter accept comment "Spice"
|
||||||
iifname { "server", "vserver", "vm-*", "lan", "wg_cloonar" } counter accept comment "allow trusted to router"
|
iifname { "server", "vserver", "vm-*", "lan", "wg_cloonar" } counter accept comment "allow trusted to router"
|
||||||
iifname { "multimedia", "smart", "infrastructure", "podman0", "setup" } udp dport { 53, 5353 } counter accept comment "DNS"
|
iifname { "multimedia", "smart", "infrastructure", "podman0", "setup" } udp dport { 53, 5353 } counter accept comment "DNS"
|
||||||
iifname { "multimedia", "smart", "infrastructure", "server", "lan", "guest" } udp dport { 67 } counter accept comment "DHCP"
|
|
||||||
iifname { "wan", "multimedia" } icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
|
iifname { "wan", "multimedia" } icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
|
||||||
|
|
||||||
# Accept mDNS for avahi reflection
|
# Accept mDNS for avahi reflection
|
||||||
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 tcp dport { llmnr } counter accept
|
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 tcp dport { llmnr } counter accept
|
||||||
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 udp dport { mdns, llmnr } counter accept
|
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 udp dport { mdns, llmnr } counter accept
|
||||||
iifname "server" udp dport 5353 ip daddr 224.0.0.251 counter accept comment "Avahi mDNS"
|
|
||||||
iifname "lan" udp dport 5353 ip daddr 224.0.0.251 counter accept comment "Avahi mDNS"
|
|
||||||
|
|
||||||
# Allow all returning traffic
|
# Allow all returning traffic
|
||||||
ct state { established, related } counter accept
|
ct state { established, related } counter accept
|
||||||
|
|
@ -95,24 +79,10 @@
|
||||||
# multimedia airplay
|
# multimedia airplay
|
||||||
iifname "multimedia" oifname { "lan" } counter accept
|
iifname "multimedia" oifname { "lan" } counter accept
|
||||||
iifname "multimedia" oifname "server" tcp dport { 1704, 1705 } counter accept
|
iifname "multimedia" oifname "server" tcp dport { 1704, 1705 } counter accept
|
||||||
iifname "multimedia" oifname "server" tcp dport { 3483, 9000 } counter accept
|
|
||||||
iifname "multimedia" oifname "server" udp dport { 3483 } counter accept
|
|
||||||
iifname "multimedia" oifname "server" icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "Allow select ICMP"
|
|
||||||
iifname "lan" oifname "server" udp dport { 5000, 5353, 6001 - 6011 } counter accept
|
iifname "lan" oifname "server" udp dport { 5000, 5353, 6001 - 6011 } counter accept
|
||||||
# avahi
|
# avahi
|
||||||
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 oifname { "lan" } counter accept
|
iifname "server" ip saddr ${config.networkPrefix}.97.20/32 oifname { "lan" } counter accept
|
||||||
|
|
||||||
# Allow Chromecast
|
|
||||||
iifname "lan" oifname "server" udp dport 5353 ip daddr 224.0.0.251 counter accept comment "mDNS query LAN→Server"
|
|
||||||
iifname "server" oifname "lan" udp sport 5353 ip saddr 224.0.0.251 counter accept comment "mDNS response Server→LAN"
|
|
||||||
iifname "lan" oifname "server" tcp dport 9881 counter accept comment "chromecast"
|
|
||||||
|
|
||||||
# SSDP / UPnP discovery if needed
|
|
||||||
iifname { "lan", "server" } oifname { "server", "lan" } \
|
|
||||||
udp dport 1900 ip daddr 239.255.255.250 counter accept comment "SSDP query"
|
|
||||||
iifname { "lan", "server" } oifname { "server", "lan" } \
|
|
||||||
udp sport 1900 ip saddr 239.255.255.250 counter accept comment "SSDP response"
|
|
||||||
|
|
||||||
# smart home coap
|
# smart home coap
|
||||||
iifname "smart" oifname "server" ip daddr ${config.networkPrefix}.97.20/32 udp dport { 5683 } counter accept
|
iifname "smart" oifname "server" ip daddr ${config.networkPrefix}.97.20/32 udp dport { 5683 } counter accept
|
||||||
iifname "smart" oifname "server" ip daddr ${config.networkPrefix}.97.20/32 tcp dport { 1883 } counter accept
|
iifname "smart" oifname "server" ip daddr ${config.networkPrefix}.97.20/32 tcp dport { 1883 } counter accept
|
||||||
|
|
|
||||||
|
|
@ -421,62 +421,21 @@
|
||||||
"light.bathroom_bulb_2"
|
"light.bathroom_bulb_2"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
platform = "switch";
|
||||||
|
name = "Hallway Switch";
|
||||||
|
entity_id = "switch.hallway";
|
||||||
|
}
|
||||||
{
|
{
|
||||||
platform = "group";
|
platform = "group";
|
||||||
name = "Hallway Lights";
|
name = "Hallway Lights";
|
||||||
all = true;
|
all = true;
|
||||||
entities = [
|
entities = [
|
||||||
"light.hallway_light_switch_mini_switch"
|
"light.hallway_switch"
|
||||||
"light.hallway_bulb_1"
|
"light.hallway_bulb_1"
|
||||||
"light.hallway_bulb_2"
|
"light.hallway_bulb_2"
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
{
|
|
||||||
platform = "template";
|
|
||||||
lights = {
|
|
||||||
hallway_group_proxy = {
|
|
||||||
friendly_name = "Hallway Lights (Proxy)";
|
|
||||||
# follow the real group’s on/off state
|
|
||||||
value_template = "{{ is_state('light.hallway_lights','on') }}";
|
|
||||||
turn_on = {
|
|
||||||
service = "light.turn_on";
|
|
||||||
data = { entity_id = "light.hallway_lights"; };
|
|
||||||
};
|
|
||||||
turn_off = {
|
|
||||||
service = "light.turn_off";
|
|
||||||
data = { entity_id = "light.hallway_lights"; };
|
|
||||||
};
|
|
||||||
# brightness support
|
|
||||||
set_level = {
|
|
||||||
service = "light.turn_on";
|
|
||||||
data_template = {
|
|
||||||
entity_id = "light.hallway_lights";
|
|
||||||
brightness = "{{ brightness }}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# color temperature support (if you have CT-capable bulbs)
|
|
||||||
set_temperature = {
|
|
||||||
service = "light.turn_on";
|
|
||||||
data_template = {
|
|
||||||
entity_id = "light.hallway_lights";
|
|
||||||
color_temp = "{{ color_temp }}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# RGB color support
|
|
||||||
set_color = {
|
|
||||||
service = "light.turn_on";
|
|
||||||
data_template = {
|
|
||||||
entity_id = "light.hallway_lights";
|
|
||||||
rgb_color = [ "{{ red }}" "{{ green }}" "{{ blue }}" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
# always report as “available”
|
|
||||||
availability_template = "true";
|
|
||||||
# declare which color modes you need
|
|
||||||
supported_color_modes = [ "brightness" "color_temp" "rgb" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
platform = "switch";
|
platform = "switch";
|
||||||
name = "Toilet Switch";
|
name = "Toilet Switch";
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,4 @@
|
||||||
let
|
{
|
||||||
devices = [
|
|
||||||
"device_tracker.dominiks_iphone"
|
|
||||||
"device_tracker.dominiks_mp01"
|
|
||||||
];
|
|
||||||
in {
|
|
||||||
services.home-assistant.extraComponents = [
|
services.home-assistant.extraComponents = [
|
||||||
"nuki"
|
"nuki"
|
||||||
];
|
];
|
||||||
|
|
@ -14,7 +9,9 @@ in {
|
||||||
mode = "restart";
|
mode = "restart";
|
||||||
trigger = {
|
trigger = {
|
||||||
platform = "state";
|
platform = "state";
|
||||||
entity_id = devices;
|
entity_id = [
|
||||||
|
"device_tracker.dominiks_iphone"
|
||||||
|
];
|
||||||
from = "not_home";
|
from = "not_home";
|
||||||
to = "home";
|
to = "home";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -494,12 +494,6 @@
|
||||||
entity_id = "script.turn_on_tv";
|
entity_id = "script.turn_on_tv";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
|
||||||
service = "media_player.turn_off";
|
|
||||||
target = {
|
|
||||||
entity_id = "media_player.marantz_sr6015";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
{
|
{
|
||||||
services.home-assistant.extraComponents = [ "squeezebox" ];
|
|
||||||
services.home-assistant.config = {
|
services.home-assistant.config = {
|
||||||
"automation toilet music" = {
|
"automation toilet music" = {
|
||||||
alias = "toilet music";
|
alias = "toilet music";
|
||||||
trigger = {
|
trigger = {
|
||||||
platform = "state";
|
platform = "state";
|
||||||
entity_id = "light.toilet_switch";
|
entity_id = "light.toilett_lights";
|
||||||
};
|
};
|
||||||
action = [
|
action = [
|
||||||
{
|
{
|
||||||
|
|
@ -14,52 +13,10 @@
|
||||||
entity_id = "media_player.music_toilet_snapcast_client";
|
entity_id = "media_player.music_toilet_snapcast_client";
|
||||||
};
|
};
|
||||||
data = {
|
data = {
|
||||||
is_volume_muted = "{{ trigger.to_state.state != 'on' }}";
|
is_volume_muted = "{{ trigger.to_state.state == 'off' }}";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
"automation bathroom music" = {
|
|
||||||
alias = "bathroom music";
|
|
||||||
trigger = {
|
|
||||||
platform = "state";
|
|
||||||
entity_id = "light.bathroom_switch";
|
|
||||||
};
|
|
||||||
action = [
|
|
||||||
{
|
|
||||||
service = "media_player.volume_mute";
|
|
||||||
target = {
|
|
||||||
entity_id = "media_player.music_bathroom_snapcast_client";
|
|
||||||
};
|
|
||||||
data = {
|
|
||||||
is_volume_muted = "{{ trigger.to_state.state != 'on' }}";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
"automation piano" = {
|
|
||||||
alias = "piano";
|
|
||||||
trigger = {
|
|
||||||
platform = "state";
|
|
||||||
entity_id = "media_player.music_piano_snapcast_client";
|
|
||||||
attribute = "is_volume_muted";
|
|
||||||
};
|
|
||||||
condition = [
|
|
||||||
{
|
|
||||||
condition = "template";
|
|
||||||
value_template = "{{ trigger.from_state.state != 'unavailable' }}";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
condition = "template";
|
|
||||||
value_template = "{{ state_attr('media_player.music_piano_snapcast_client', 'is_volume_muted') == true or state_attr('media_player.music_piano_snapcast_client', 'is_volume_muted') == false }}";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
action = {
|
|
||||||
service = "switch.turn_on";
|
|
||||||
target = {
|
|
||||||
entity_id = "switch.piano_switch_power";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,31 @@
|
||||||
{
|
{
|
||||||
services.home-assistant = {
|
services.home-assistant = {
|
||||||
extraComponents = [ "snapcast" ];
|
extraComponents = [ "snapcast" ];
|
||||||
|
config = {
|
||||||
|
"automation piano" = {
|
||||||
|
alias = "piano";
|
||||||
|
trigger = {
|
||||||
|
platform = "state";
|
||||||
|
entity_id = "media_player.music_piano_snapcast_client";
|
||||||
|
attribute = "is_volume_muted";
|
||||||
|
};
|
||||||
|
condition = [
|
||||||
|
{
|
||||||
|
condition = "template";
|
||||||
|
value_template = "{{ trigger.from_state.state != 'unavailable' }}";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
condition = "template";
|
||||||
|
value_template = "{{ state_attr('media_player.music_piano_snapcast_client', 'is_volume_muted') == true or state_attr('media_player.music_piano_snapcast_client', 'is_volume_muted') == false }}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
action = {
|
||||||
|
service = "switch.turn_on";
|
||||||
|
target = {
|
||||||
|
entity_id = "switch.piano_switch_power";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,88 +0,0 @@
|
||||||
{ pkgs, config, lib, python3Packages, ... }:
|
|
||||||
|
|
||||||
let
|
|
||||||
lmsDomain = "lms.cloonar.com";
|
|
||||||
networkPrefix = config.networkPrefix;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
security.acme.certs."${lmsDomain}" = {
|
|
||||||
group = "nginx";
|
|
||||||
};
|
|
||||||
|
|
||||||
sops.secrets.lms-spotify = { };
|
|
||||||
|
|
||||||
containers.lms = {
|
|
||||||
autoStart = true;
|
|
||||||
ephemeral = false;
|
|
||||||
privateNetwork = true;
|
|
||||||
hostBridge = "server";
|
|
||||||
|
|
||||||
hostAddress = "${networkPrefix}.97.2";
|
|
||||||
localAddress = "${networkPrefix}.97.21/24";
|
|
||||||
|
|
||||||
extraFlags = [ "--capability=CAP_NET_ADMIN" ];
|
|
||||||
|
|
||||||
bindMounts = {
|
|
||||||
"/var/lib/acme/lms/" = {
|
|
||||||
hostPath = config.security.acme.certs.${lmsDomain}.directory;
|
|
||||||
isReadOnly = true;
|
|
||||||
};
|
|
||||||
"/run/secrets/lms-spotify" = {
|
|
||||||
hostPath = config.sops.secrets.lms-spotify.path;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = { pkgs, lib, config, ... }:
|
|
||||||
let
|
|
||||||
in
|
|
||||||
{
|
|
||||||
networking = {
|
|
||||||
hostName = "lms";
|
|
||||||
useHostResolvConf = false;
|
|
||||||
defaultGateway = {
|
|
||||||
address = "${networkPrefix}.97.1";
|
|
||||||
interface = "eth0";
|
|
||||||
};
|
|
||||||
nameservers = [ "${networkPrefix}.97.1" ];
|
|
||||||
firewall.enable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
slimserver # Logitech/Lyrion Media Server
|
|
||||||
];
|
|
||||||
|
|
||||||
services.slimserver = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.slimserver;
|
|
||||||
};
|
|
||||||
|
|
||||||
# make LMS discoverable via mDNS/Avahi
|
|
||||||
services.avahi = {
|
|
||||||
enable = true;
|
|
||||||
publish.enable = true;
|
|
||||||
publish.userServices = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx.enable = true;
|
|
||||||
services.nginx.virtualHosts."${lmsDomain}" = {
|
|
||||||
sslCertificate = "/var/lib/acme/lms/fullchain.pem";
|
|
||||||
sslCertificateKey = "/var/lib/acme/lms/key.pem";
|
|
||||||
sslTrustedCertificate = "/var/lib/acme/lms/chain.pem";
|
|
||||||
forceSSL = true;
|
|
||||||
extraConfig = "proxy_buffering off;";
|
|
||||||
|
|
||||||
locations."/".extraConfig = ''
|
|
||||||
proxy_pass http://127.0.0.1:9000/;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_redirect http:// https://;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
system.stateVersion = "23.05";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -261,10 +261,6 @@ in {
|
||||||
enable = true;
|
enable = true;
|
||||||
path = with pkgs; [ unbound inotify-tools ];
|
path = with pkgs; [ unbound inotify-tools ];
|
||||||
script = ''
|
script = ''
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# readFile and readFileUnique as before…
|
|
||||||
function readFile() {
|
function readFile() {
|
||||||
if [[ "''\$2" == "A" ]] ; then
|
if [[ "''\$2" == "A" ]] ; then
|
||||||
cat "''\$1" | tail -n +2 | while IFS=, read -r address hwaddr client_id valid_lifetime expire subnet_id fqdn_fwd fqdn_rev hostname state user_context
|
cat "''\$1" | tail -n +2 | while IFS=, read -r address hwaddr client_id valid_lifetime expire subnet_id fqdn_fwd fqdn_rev hostname state user_context
|
||||||
|
|
@ -277,8 +273,8 @@ in {
|
||||||
echo "''\${address},''\${hostname}"
|
echo "''\${address},''\${hostname}"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function readFileUnique() {
|
function readFileUnique() {
|
||||||
readFile "''\$1" ''\$2 | uniq | while IFS=, read -r address hostname
|
readFile "''\$1" ''\$2 | uniq | while IFS=, read -r address hostname
|
||||||
do
|
do
|
||||||
|
|
@ -317,27 +313,19 @@ in {
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncFile() {
|
||||||
|
# readFileUnique "''\$1" "''\$2"
|
||||||
|
while true; do
|
||||||
|
readFileUnique "''\$1" "''\$2"
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncLeases() {
|
syncFile "/var/lib/kea/dhcp4.leases" A &
|
||||||
# 1) nuke all of our old lease records from unbound
|
# syncFile "/var/lib/kea/dhcp6.leases" AAAA &
|
||||||
unbound-control list_local_data \
|
wait
|
||||||
| grep -E 'cloonar\.(com|multimedia|smart)|ip4\.arpa|in-addr\.arpa' \
|
|
||||||
| while read -r name type data; do
|
|
||||||
unbound-control local_data_remove "$name" "$type" "$data" \
|
|
||||||
> /dev/null 2>&1
|
|
||||||
done
|
|
||||||
|
|
||||||
# 2) re-push every current lease
|
|
||||||
readFileUnique "/var/lib/kea/dhcp4.leases" A
|
|
||||||
# if you need IPv6:
|
|
||||||
# readFileUnique "/var/lib/kea/dhcp6.leases" AAAA
|
|
||||||
}
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
syncLeases
|
|
||||||
sleep 10
|
|
||||||
done
|
|
||||||
'';
|
'';
|
||||||
wants = [ "network-online.target" "unbound.service" ];
|
wants = [ "network-online.target" "unbound.service" ];
|
||||||
after = [ "network-online.target" "unbound.service" ];
|
after = [ "network-online.target" "unbound.service" ];
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ matrix-shared-secret: ENC[AES256_GCM,data:67imd3m6WBeGP/5Msmjy8B6sP983jMyWzRIzWg
|
||||||
palworld: ENC[AES256_GCM,data:rdqChPt4gSJHS1D60+HJ+4m5mg35JbC+pOmevK21Y95QyAIeyBLVGhRYlOaUcqdZM2e4atyTTSf6z4nHsm539ddCbW7J2DCdF5PQkrAGDmmdTVq+jyJAT8gTrbXXCglT1wvFYY5dbf2NKA4ASJIA8bdVNuwRZU0CtFiishzLuc9m8ZcGCNwQ/+xkMZgkUAHYRlEJAZyMpXR6KkFftiR05JRAFczD4N7GXPPe+vyvgXg7QBGtf20Qd4SGBUw0zI/SNTRmifHUuc4Z6+Fe9JHgvTc3uFcTMVnty0fEuL+a29liaVdAFq8BnqJfc5CNV401ZSUeMbG41lCn1cegP/WChs9J6HXNrhWDgiXa6ln++NoKcfOHIfZVbYOCoOxFR6+YWeBU2+sHmdwI9j5XQf5Ly2hmg12j0Ds2Cn8k4PG5aQP+HT2bedqyxwSt6fi97A0Osnh4ig7+DzYAjSNLewbYLzVdK39VdvB9hqLto+yFS3gAaeYOHwPwtqa+COI85c55lHiyKHlSwPhBqYaaiDu00lQTUzq9R5vz6F/l+T3bUjuna5RryUu8yhnk5DyK834KycTOg4ETcZTqro6prfiEBxc+Utsc9JvEtZgwFv6fsVLOu7nHxuiYuvseZ4YA8LlYdwPJboMPO2XsuhwWtT1uz/rh2orH7/vsXvzA/kF8NFemWBEMVLYA8byC5ze8doiGDYp4T5AAf10nJB1ceQ==,iv:gs78fxhvo9KlTaR5nzs12/LdgPChSFPHD2k4VQp3ARo=,tag:lpWBOi9xh2cWkS+71KD/UQ==,type:str]
|
palworld: ENC[AES256_GCM,data:rdqChPt4gSJHS1D60+HJ+4m5mg35JbC+pOmevK21Y95QyAIeyBLVGhRYlOaUcqdZM2e4atyTTSf6z4nHsm539ddCbW7J2DCdF5PQkrAGDmmdTVq+jyJAT8gTrbXXCglT1wvFYY5dbf2NKA4ASJIA8bdVNuwRZU0CtFiishzLuc9m8ZcGCNwQ/+xkMZgkUAHYRlEJAZyMpXR6KkFftiR05JRAFczD4N7GXPPe+vyvgXg7QBGtf20Qd4SGBUw0zI/SNTRmifHUuc4Z6+Fe9JHgvTc3uFcTMVnty0fEuL+a29liaVdAFq8BnqJfc5CNV401ZSUeMbG41lCn1cegP/WChs9J6HXNrhWDgiXa6ln++NoKcfOHIfZVbYOCoOxFR6+YWeBU2+sHmdwI9j5XQf5Ly2hmg12j0Ds2Cn8k4PG5aQP+HT2bedqyxwSt6fi97A0Osnh4ig7+DzYAjSNLewbYLzVdK39VdvB9hqLto+yFS3gAaeYOHwPwtqa+COI85c55lHiyKHlSwPhBqYaaiDu00lQTUzq9R5vz6F/l+T3bUjuna5RryUu8yhnk5DyK834KycTOg4ETcZTqro6prfiEBxc+Utsc9JvEtZgwFv6fsVLOu7nHxuiYuvseZ4YA8LlYdwPJboMPO2XsuhwWtT1uz/rh2orH7/vsXvzA/kF8NFemWBEMVLYA8byC5ze8doiGDYp4T5AAf10nJB1ceQ==,iv:gs78fxhvo9KlTaR5nzs12/LdgPChSFPHD2k4VQp3ARo=,tag:lpWBOi9xh2cWkS+71KD/UQ==,type:str]
|
||||||
ark: ENC[AES256_GCM,data:YYGyzoVIKI9Ac1zGOr0BEpd3fgBsvp1hSwAvfO07/EQdg8ufMWUkNvqNHDKN62ZK5A1NnY3JTA1p4gyZ4ryQeAOsbwqU1GSk2YKHFyPeEnpLz/Ml82KMsv7XPGXuKRXZ4v3UcLu0R8k1Q0gQsMWo4FjCs3FF5mVtJG/YWxxbCYHoBLJ/di5p0DgjuFgJBQknYBpuLzr+yIoeqEyN7XcGYAJO53trEJuOOxLILULifkqISHjZ66i5F1fHW0iUdRbmeWV4aOAeOrsQqXYv,iv:gJwV5ip84zHqpU0l0uESfWWOtcgihMvEEdLaeI+twcU=,tag:sy8udVQsKxV/jOqwhJmWAg==,type:str]
|
ark: ENC[AES256_GCM,data:YYGyzoVIKI9Ac1zGOr0BEpd3fgBsvp1hSwAvfO07/EQdg8ufMWUkNvqNHDKN62ZK5A1NnY3JTA1p4gyZ4ryQeAOsbwqU1GSk2YKHFyPeEnpLz/Ml82KMsv7XPGXuKRXZ4v3UcLu0R8k1Q0gQsMWo4FjCs3FF5mVtJG/YWxxbCYHoBLJ/di5p0DgjuFgJBQknYBpuLzr+yIoeqEyN7XcGYAJO53trEJuOOxLILULifkqISHjZ66i5F1fHW0iUdRbmeWV4aOAeOrsQqXYv,iv:gJwV5ip84zHqpU0l0uESfWWOtcgihMvEEdLaeI+twcU=,tag:sy8udVQsKxV/jOqwhJmWAg==,type:str]
|
||||||
firefox-sync: ENC[AES256_GCM,data:uAJAdyKAuXRuqCFl8742vIejU5RnAPpUxUFCC0s0QeXZR5oH2YOrDh+3vKUmckW4V1cIhSHoe+4+I4HuU5E73DDrJThfIzBEw+spo4HXwZf5KBtu3ujgX6/fSTlPWV7pEsDDsZ0y6ziKPADBDym8yEk0bU9nRedvTBUhVryo3aolzF/c+gJvdeDvKUYa8+8=,iv:yuvE4KG7z7Rp9ZNlLiJ2rh0keed3DuvrELzsfJu4+bs=,tag:HFo1A53Eva31NJ8fRE7TlA==,type:str]
|
firefox-sync: ENC[AES256_GCM,data:uAJAdyKAuXRuqCFl8742vIejU5RnAPpUxUFCC0s0QeXZR5oH2YOrDh+3vKUmckW4V1cIhSHoe+4+I4HuU5E73DDrJThfIzBEw+spo4HXwZf5KBtu3ujgX6/fSTlPWV7pEsDDsZ0y6ziKPADBDym8yEk0bU9nRedvTBUhVryo3aolzF/c+gJvdeDvKUYa8+8=,iv:yuvE4KG7z7Rp9ZNlLiJ2rh0keed3DuvrELzsfJu4+bs=,tag:HFo1A53Eva31NJ8fRE7TlA==,type:str]
|
||||||
knot-tsig-key: ENC[AES256_GCM,data:H2jEkRSVSIJl1dSolAXj9uUmzD6eEh9zPpoajZLxfuuFt7/LJF8aCEHyk+Q=,iv:9aqywuaILYtejuZGd+Cy8oErrHIoL2XhL1g9HtcUn/o=,tag:K3SnVEXGC/NhlchU7OyA6Q==,type:str]
|
|
||||||
sops:
|
sops:
|
||||||
kms: []
|
kms: []
|
||||||
gcp_kms: []
|
gcp_kms: []
|
||||||
|
|
@ -60,8 +59,8 @@ sops:
|
||||||
WXJpUUxadERyYUExRFMzNzBXaUVET3cKG9ZwWy5YvTr/BAw/i+ZJos5trwRvaW5j
|
WXJpUUxadERyYUExRFMzNzBXaUVET3cKG9ZwWy5YvTr/BAw/i+ZJos5trwRvaW5j
|
||||||
eV/SHiEteZZtCuCVFAp3iolE/mJyu97nA2yFwWaLN86h+/xkOJsdqA==
|
eV/SHiEteZZtCuCVFAp3iolE/mJyu97nA2yFwWaLN86h+/xkOJsdqA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2025-05-01T20:36:09Z"
|
lastmodified: "2025-03-01T22:14:10Z"
|
||||||
mac: ENC[AES256_GCM,data:ZtXJcuwDpDlBl2xdRtMF1PwwqbW00Eps2ZZG5x4C2djAq+meXJCxKS9sNazQhMYFOqphQXe3JEhChykLxnJyWivY/Er1ig2sU6Ke1uVcfSP85B1/rpzhe/7QI+GBDWrkCk1O0xGKKj8fWt+Yv2MV8gw2XctdtJ9Md4imUhcK7zo=,iv:5NFH+7Z0alBiq/b94T40XJSCar2+BGaFB20z0Kc59fU=,tag:18n0tt17RNMyyE0eECH2kQ==,type:str]
|
mac: ENC[AES256_GCM,data:UWwjvi8jLNgu4l7ldMYtkAATm3y5+BSxbCuPN/e1OC4/3ULYJndqFLfTOMpqQbj2+uHo3onelK4f0MAJuSH0oUx58CclkNBBLE0RXafxbowa7kJtTNDfTboJNqH7rFmhGhqCtHAOOpKBuowqoOUHP5BtzZfucra0Q/pIJt5lma0=,iv:iJEW/mTbizioPSN8G+WqHSipx8P6VCDrVG/Cmk+MBUc=,tag:L4OkeKec5AZdCrpUrnqcOA==,type:str]
|
||||||
pgp: []
|
pgp: []
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.9.4
|
version: 3.9.4
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ in {
|
||||||
./utils/modules/nur.nix
|
./utils/modules/nur.nix
|
||||||
./modules/appimage.nix
|
./modules/appimage.nix
|
||||||
./modules/sway/sway.nix
|
./modules/sway/sway.nix
|
||||||
# ./modules/printer.nix
|
./modules/printer.nix
|
||||||
# ./modules/cyberghost.nix
|
# ./modules/cyberghost.nix
|
||||||
./utils/modules/autoupgrade.nix
|
./utils/modules/autoupgrade.nix
|
||||||
./modules/puppeteer.nix
|
./modules/puppeteer.nix
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,6 @@ let
|
||||||
"media.ffmpeg.vaapi.enabled" = true;
|
"media.ffmpeg.vaapi.enabled" = true;
|
||||||
"media.ffmpeg.vaapi-drm-display.enabled" = true;
|
"media.ffmpeg.vaapi-drm-display.enabled" = true;
|
||||||
"gfx.webrender.all" = true;
|
"gfx.webrender.all" = true;
|
||||||
"xpinstall.signatures.required" = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
firefoxUserChrome = ''
|
firefoxUserChrome = ''
|
||||||
|
|
@ -532,7 +531,7 @@ in
|
||||||
|
|
||||||
programs.firefox = {
|
programs.firefox = {
|
||||||
enable = true;
|
enable = true;
|
||||||
package = pkgs.firefox-devedition.overrideAttrs (a: {
|
package = pkgs.firefox.overrideAttrs (a: {
|
||||||
postInstall = a.postInstall or "" + ''
|
postInstall = a.postInstall or "" + ''
|
||||||
wrapProgram "$out/bin/firefox" \
|
wrapProgram "$out/bin/firefox" \
|
||||||
export MOZ_ENABLE_WAYLAND=1
|
export MOZ_ENABLE_WAYLAND=1
|
||||||
|
|
@ -559,11 +558,6 @@ in
|
||||||
icon = "fingerprint";
|
icon = "fingerprint";
|
||||||
id = 1;
|
id = 1;
|
||||||
};
|
};
|
||||||
"dating" = {
|
|
||||||
color = "pink";
|
|
||||||
icon = "circle";
|
|
||||||
id = 5;
|
|
||||||
};
|
|
||||||
"cloonar technologies" = {
|
"cloonar technologies" = {
|
||||||
color = "red";
|
color = "red";
|
||||||
icon = "briefcase";
|
icon = "briefcase";
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,7 @@
|
||||||
server_name = "code.cloonar.com";
|
server_name = "code.cloonar.com";
|
||||||
aliasgroup1 = "https://nextcloud.cloonar.com:443";
|
aliasgroup1 = "https://nextcloud.cloonar.com:443";
|
||||||
aliasgroup2 = "https://cloud.cloonar.com:443";
|
aliasgroup2 = "https://cloud.cloonar.com:443";
|
||||||
# Hannes
|
dictionaries = "en_US";
|
||||||
aliasgroup3 = "https://nx67898.your-storageshare.de:443";
|
|
||||||
aliasgroup4 = "https://hs-cloud.cloonar.com:443";
|
|
||||||
dictionaries = "en_GB en_US de_DE";
|
|
||||||
extra_params = "--o:ssl.enable=false --o:ssl.termination=true";
|
extra_params = "--o:ssl.enable=false --o:ssl.termination=true";
|
||||||
};
|
};
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ in
|
||||||
enable = true;
|
enable = true;
|
||||||
hostName = "nextcloud.cloonar.com";
|
hostName = "nextcloud.cloonar.com";
|
||||||
https = true;
|
https = true;
|
||||||
package = pkgs.nextcloud31;
|
package = nextcloud30;
|
||||||
# Instead of using pkgs.nextcloud27Packages.apps,
|
# Instead of using pkgs.nextcloud27Packages.apps,
|
||||||
# we'll reference the package version specified above
|
# we'll reference the package version specified above
|
||||||
extraApps = {
|
extraApps = {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{ pkgs, ... }: {
|
|
||||||
services.postfix = {
|
|
||||||
enable = true;
|
|
||||||
domain = "cloonar.com";
|
|
||||||
hostname = "web-arm.cloonar.com";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Must be run as root
|
|
||||||
if [[ $EUID -ne 0 ]]; then
|
|
||||||
echo "This script must be run as root. Try sudo $0 ..." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Default env file
|
|
||||||
ENV_FILE="./.env"
|
|
||||||
|
|
||||||
# PiCorePlayer version to use
|
|
||||||
PCP_VERSION="10.0.0"
|
|
||||||
BASE_URL="https://repo.pcplayer.org/insitu/piCorePlayer${PCP_VERSION}"
|
|
||||||
IMG_ZIP="piCorePlayer${PCP_VERSION}.img.xz"
|
|
||||||
DOWNLOAD_URL="${BASE_URL}/${IMG_ZIP}"
|
|
||||||
|
|
||||||
# Print usage
|
|
||||||
usage() {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: sudo $0 --device <rpi-4|rpi-zero|rpi-zero-2> \
|
|
||||||
--sdcard </dev/sdX> \
|
|
||||||
[--env-file /path/to/.env]
|
|
||||||
|
|
||||||
--device Target board (rpi-4, rpi-zero, rpi-zero-2)
|
|
||||||
--sdcard Device node of the SD card (e.g. /dev/sdb)
|
|
||||||
--env-file File containing WIFI_SSID and WIFI_PSK (defaults to ./.env)
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse args
|
|
||||||
DEVICE="" SDCARD=""
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--device) DEVICE="$2"; shift 2;;
|
|
||||||
--sdcard) SDCARD="$2"; shift 2;;
|
|
||||||
--env-file) ENV_FILE="$2"; shift 2;;
|
|
||||||
-h|--help) usage;;
|
|
||||||
*) echo "Unknown option: $1" >&2; usage;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Validate
|
|
||||||
if [[ -z "$DEVICE" || -z "$SDCARD" ]]; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
if [[ ! -b "$SDCARD" ]]; then
|
|
||||||
echo "Error: $SDCARD is not a block device." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [[ ! -f "$ENV_FILE" ]]; then
|
|
||||||
echo "Error: env file '$ENV_FILE' not found." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Load Wi-Fi credentials
|
|
||||||
source "$ENV_FILE"
|
|
||||||
if [[ -z "${WIFI_SSID:-}" || -z "${WIFI_PSK:-}" ]]; then
|
|
||||||
echo "Error: WIFI_SSID and WIFI_PSK must be set in $ENV_FILE" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Download if needed
|
|
||||||
if [[ ! -f "$IMG_ZIP" ]]; then
|
|
||||||
echo "Downloading $IMG_ZIP ..."
|
|
||||||
wget -q --show-progress "$DOWNLOAD_URL"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Flash image
|
|
||||||
echo "Flashing $IMG_ZIP to $SDCARD (will overwrite everything!)"
|
|
||||||
sync
|
|
||||||
xzcat "$IMG_ZIP" | dd of="$SDCARD" bs=4M status=progress
|
|
||||||
sync
|
|
||||||
|
|
||||||
# Determine partition suffixes (/dev/sdX1 vs /dev/mmcblk0p1)
|
|
||||||
if [[ "$SDCARD" =~ [0-9]$ ]]; then
|
|
||||||
PART1="${SDCARD}p1"; PART2="${SDCARD}p2"
|
|
||||||
else
|
|
||||||
PART1="${SDCARD}1"; PART2="${SDCARD}2"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Mount partitions
|
|
||||||
BOOT_MNT=$(mktemp -d)
|
|
||||||
ROOT_MNT=$(mktemp -d)
|
|
||||||
mount "$PART1" "$BOOT_MNT"
|
|
||||||
mount "$PART2" "$ROOT_MNT"
|
|
||||||
|
|
||||||
# Create hidden Wi-Fi config on boot partition
|
|
||||||
cat > "$BOOT_MNT/wpa_supplicant.conf" <<EOF
|
|
||||||
ctrl_interface=/var/run/wpa_supplicant
|
|
||||||
ctrl_interface_group=staff
|
|
||||||
country=AT
|
|
||||||
update_config=1
|
|
||||||
|
|
||||||
network={
|
|
||||||
ssid="$WIFI_SSID"
|
|
||||||
psk="$WIFI_PSK"
|
|
||||||
scan_ssid=1
|
|
||||||
key_mgmt=WPA-PSK
|
|
||||||
auth_alg=OPEN
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# If a Zero device, enable Hifiberry DAC+ and disable onboard audio
|
|
||||||
if [[ "$DEVICE" == "rpi-zero" || "$DEVICE" == "rpi-zero-2" ]]; then
|
|
||||||
cat >> "$BOOT_MNT/config.txt" <<EOF
|
|
||||||
|
|
||||||
# Hifiberry DAC+ overlay for Zero models
|
|
||||||
dtoverlay=hifiberry-dacplus-std
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
umount "$BOOT_MNT" "$ROOT_MNT"
|
|
||||||
rmdir "$BOOT_MNT" "$ROOT_MNT"
|
|
||||||
|
|
||||||
echo "Done! SD card is ready with PiCorePlayer ${PCP_VERSION} on $DEVICE,"
|
|
||||||
echo "hidden Wi-Fi '$WIFI_SSID'."
|
|
||||||
echo "Insert the SD card into the Pi and power it on."
|
|
||||||
echo "You can now connect to the PiCorePlayer web interface at http://pcp.local"
|
|
||||||
|
|
@ -6,8 +6,8 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
src = fetchgit {
|
src = fetchgit {
|
||||||
url = "https://github.com/dpolakovics/bento.git";
|
url = "https://github.com/dpolakovics/bento.git";
|
||||||
rev = "73092673b194fd734d782f5b7e83dfbb5d169372";
|
rev = "8d911a02dc9af222ffb5892bbddd4a3895893959";
|
||||||
sha256 = "sha256-/37RJTjo+FJa1Flt59LrQbaJIcBid/z+Hy1xfhYGXNA=";
|
sha256 = "sha256-9R3glZcjc+t8LKvo5HOAo+HzXFQ6GOtzehJpb7GjmYM=";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildInputs = [ ];
|
buildInputs = [ ];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue