Compare commits

..

No commits in common. "3a10536e71494a1294b96ac6f583b9f34024bdfe" and "ff284125dbb07e0833dfcb2d7255bcc83d8fa3b2" have entirely different histories.

57 changed files with 214 additions and 2437 deletions

View File

@ -12,26 +12,14 @@ log:
#jwt_secret: SECRET_GOES_HERE # use docker secret file instead AUTHELIA_JWT_SECRET_FILE
# https://docs.authelia.com/configuration/miscellaneous.html#default-redirection-url
# default_redirection_url: https://authelia.milvert.com
default_redirection_url: https://authelia.milvert.com
webauthn: #FIDO2 Authentication
disable: false
enable_passkey_login: true
display_name: Authelia
attestation_conveyance_preference: direct
user_verification: required
timeout: 60s
filtering:
prohibit_backup_eligibility: false
selection_criteria:
attachment: ''
discoverability: 'preferred'
user_verification: 'preferred'
metadata:
enabled: false
validate_trust_anchor: true
validate_entry: true
validate_status: true
validate_entry_permit_zero_aaguid: false
totp:
issuer: authelia.com
@ -75,10 +63,10 @@ access_control:
policy: two_factor
- domain: "milvert.com"
policy: two_factor
#- domain:
#- 'uptime.example.com'
#subject: 'oauth2:client:uptime-kuma'
#policy: 'one_factor'
- domain:
- 'uptime.example.com'
subject: 'oauth2:client:uptime-kuma'
policy: 'one_factor'
session:
name: authelia_session
@ -87,9 +75,7 @@ session:
# secret: SECRET_GOES_HERE # use docker secret file instead AUTHELIA_SESSION_SECRET_FILE
expiration: 3600 # 1 hour
inactivity: 1800 # 30 min
cookies:
- domain: 'milvert.com'
authelia_url: https://authelia.milvert.com
domain: milvert.com # Should match whatever your root protected domain is
# Optional. Can improve performance on a busy system. If not enabled, session info is stored in memory.
# redis:

View File

@ -1,39 +0,0 @@
{
"carConnectivity": {
"log_level": "info",
"connectors": [
{
"type": "skoda",
"config": {
"netrc": "/root/.netrc",
"api_log_level": "warning",
"interval": 600,
"max_age": 300
}
}
],
"plugins": [
{
"type": "mqtt",
"config": {
"broker": "mqtt",
"username": "simon",
"password": "bajsa123"
}
},
{
"type": "mqtt_homeassistant",
"config": {}
}
,
{
"type": "database",
"config": {
"db_url": "sqlite:///carconnectivity.db"
}
}
]
}
}

View File

@ -1,18 +0,0 @@
#!/bin/sh
set -e
# Läs secrets
PW=$(cat /run/secrets/skoda_password)
SPIN=$(cat /run/secrets/skoda_spin)
cat > /root/.netrc <<EOF
machine skoda
login simon@milvert.com
password $PW
account $SPIN
EOF
chmod 600 /root/.netrc
# Kör original-cmd
exec "$@"

View File

@ -17,7 +17,7 @@ services:
networks:
- backend
volumes:
- ${DIR_LOCAL}/database:/var/lib/mysql:rw
- ${DIR}/database:/var/lib/mysql:rw
ports:
- "3307:3306"
labels:
@ -72,7 +72,7 @@ services:
networks:
- backend
volumes:
- ${DIR_LOCAL}/database_pg/data:/var/lib/postgresql/data
- ${DIR}/database_pg/data:/var/lib/postgresql/data
labels:
- diun.enable=true
- "traefik.enable=false"
@ -94,7 +94,7 @@ services:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
volumes:
- ${DIR_LOCAL}/database_pg/pgadmin:/root/.pgadmin
- ${DIR}/database_pg/pgadmin:/root/.pgadmin
networks:
- backend
restart: unless-stopped
@ -123,7 +123,7 @@ services:
networks:
- backend
volumes:
- ${DIR_LOCAL}/redis:/var/lib/redis
- ${DIR}/redis:/var/lib/redis
#entrypoint: redis-server --appendonly yes --requirepass $REDIS_PASSWORD --maxmemory 512mb --maxmemory-policy allkeys-lru
labels:
- diun.enable=true

View File

@ -33,6 +33,33 @@ services:
- "traefik.http.routers.node-red-secure.tls.certresolver=milvert_dns"
- "traefik.http.routers.node-red-secure.tls=true"
landet_domo:
container_name: "landet_domo"
image: ghcr.io/linuxserver/domoticz
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
restart: unless-stopped
networks:
- backend
volumes:
- ${DIR}/landet/domo:/config
- /etc/localtime:/etc/localtime:ro
ports:
- "8002:8080"
environment:
- TZ=${TZ}
- PUID=${UID}
- PGID=${GID}
labels:
- "traefik.enable=false"
- "traefik.http.services.landet_domo-service.loadbalancer.server.port=8080"
- "traefik.http.routers.landet_domo-secure.entrypoints=web-secure"
- "traefik.http.routers.landet_domo-secure.rule=Host(`landet_old.${DOMAIN}`)"
- "traefik.http.routers.landet_domo-secure.tls.certresolver=milvert_dns"
- "traefik.http.routers.landet_domo-secure.tls=true"
huawei_inverter:
image: huawei_inverter:1.0

View File

@ -12,7 +12,7 @@ services:
- db_peek
image: wordpress:5.6.0-apache
volumes:
- ${DIR_LOCAL}/peekskog/wp:/var/www/html
- /srv/docker/peekskog/wp:/var/www/html
- ./wp/php.conf.ini:/usr/local/etc/php/conf.d/uploads.ini
ports:
- "8008:80"
@ -59,7 +59,7 @@ services:
max-size: "5m"
max-file: "3"
volumes:
- ${DIR_LOCAL}/peekskog/db:/var/lib/mysql
- /srv/docker/peekskog/db:/var/lib/mysql
restart: always
networks:
- backend

View File

@ -13,7 +13,7 @@ services:
- backend
ports:
- "8088:8080"
image: koenkk/zigbee2mqtt:2.7
image: koenkk/zigbee2mqtt:2.1
restart: always
volumes:
- ./zigbee_home_2:/app/data
@ -43,7 +43,7 @@ services:
max-file: "5"
networks:
- backend
image: koenkk/zigbee2mqtt:2.6
image: koenkk/zigbee2mqtt:2.1
restart: always
volumes:
- ${DIR}/zigbee2matt:/app/data
@ -110,7 +110,6 @@ services:
telegraf:
image: telegraf:1.25
restart: always
container_name: telegraf
logging:
driver: "json-file"
@ -193,8 +192,8 @@ services:
- TZ=Europe/Stockholm
volumes:
- ./mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
- ${DIR_LOCAL}/mqtt/data:/mqtt/data
- ${DIR_LOCAL}/mqtt/log:/mqtt/log
- ${DIR}/mqtt/data:/mqtt/data
- ${DIR}/mqtt/log:/mqtt/log
labels:
- "traefik.enable=false"
- diun.enable=true

View File

@ -24,8 +24,8 @@ services:
- "traefik.http.routers.milvertcom-secure.tls=true"
#- "traefik.http.routers.milvert-secure.priority=1"
volumes:
- "${DIR_LOCAL}/milvert-nginx/conf:/etc/nginx/conf.d"
- "${DIR_LOCAL}/milvert-nginx/html:/html"
- "${DIR}/milvert-nginx/conf:/etc/nginx/conf.d"
- "${DIR}/milvert-nginx/html:/html"
whoami:
# A container that exposes an API to show its IP address

View File

@ -22,12 +22,6 @@ secrets:
file: $SECRETSDIR/vwfriend_password
vwconnect_password:
file: $SECRETSDIR/vwconnect_password
skoda_password:
file: $SECRETSDIR/skoda_password
skoda_spin:
file: $SECRETSDIR/skoda_spin
carconnect_grafana_pw:
file: $SECRETSDIR/carconnect_grafana_pw
########################### EXTENSION FIELDS ##########################
@ -49,7 +43,7 @@ services:
reverse-proxy:
# The official v2.0 Traefik docker image
#image: traefik:v2.11
image: traefik:v3.3
image: traefik:v3.1
container_name: "traefik"
logging:
driver: "json-file"
@ -348,7 +342,7 @@ services:
ha:
container_name: ha
image: homeassistant/home-assistant:2026.1
image: homeassistant/home-assistant:2025.2
restart: always
privileged: true
networks:
@ -444,33 +438,11 @@ services:
labels:
- diun.enable=true
esphome:
container_name: esphome
image: ghcr.io/esphome/esphome:2025.7.3
volumes:
- ./esphome:/config
- /etc/localtime:/etc/localtime:ro
restart: always
ports:
- 6052:6052
- 6053:6053
# privileged: true # Testa utan
environment:
- PUID=${UUID}
- PGID=${PGID}
- TZ=${TZ}
- USERNAME=${ESPHOME_USERNAME}
- PASSWORD=${ESPHOME_PASSWORD}
networks:
- backend
labels:
- diun.enable=true
evcc:
command:
- evcc
container_name: evcc
image: evcc/evcc:0.300.3
image: evcc/evcc:0.200.5
ports:
- 7070:7070/tcp
volumes:
@ -515,8 +487,9 @@ services:
- "traefik.http.routers.grafana-secure.tls=true"
node-red:
image: nodered/node-red:4.1
# command: ["node-red", "--safe"]
image: nodered/node-red:3.1.6
# image: nodered/node-red-dev:3.0.0-beta.4-14
container_name: "node-red"
logging:
driver: "json-file"
@ -535,14 +508,12 @@ services:
user: ${UID}
volumes:
- ${DIR_LOCAL}/nodered:/data
- ./node-red/settings.js:/data/settings.js
labels:
- diun.enable=true
- "traefik.enable=true"
- "traefik.http.services.node-red-service.loadbalancer.server.port=1880"
- "traefik.http.routers.node-red-secure.entrypoints=web-secure"
- "traefik.http.routers.node-red-secure.rule=Host(`nodered.${DOMAIN}`)"
- "traefik.http.routers.node-red-secure.middlewares=chain-authelia@file"
- "traefik.http.routers.node-red-secure.tls.certresolver=milvert_dns"
- "traefik.http.routers.node-red-secure.tls=true"
@ -819,60 +790,6 @@ services:
#- BROKER_ADDRESS=mqtt
#- ADDITIONAL_PARAMETERS=--mqtt-username simon --mqtt-password bajsa123 --spin 9331 -vv
carconnectivity:
image: "tillsteinbach/carconnectivity-mqtt:latest"
container_name: carconnectivity
volumes:
- ./carconnectivity/carconnectivity.json:/carconnectivity.json
- ./carconnectivity/entrypoint.sh:/root/entrypoint.sh:ro
- ${DIR_LOCAL}/carconnectivity/state:/state
- ${DIR_LOCAL}/carconnectivity/sqlite.db:/carconnectivity.db:rw
environment:
- "ADDITIONAL_INSTALLS=carconnectivity-plugin-mqtt_homeassistant carconnectivity-plugin-database"
- TZ=$TZ
- LC_ALL=sv_SE
- TMPDIR=/state
secrets:
- skoda_password
- skoda_spin
entrypoint: ["/root/entrypoint.sh"]
command: ["carconnectivity-mqtt", "/carconnectivity.json"]
restart: unless-stopped
networks:
- backend
labels:
- diun.enable=true
carconnectivity-grafana:
image: "ghcr.io/tillsteinbach/carconnectivity-grafana:edge"
container_name: carconnect-grafana
volumes:
- ${DIR_LOCAL}/carconnect-grafana:/var/lib/grafana
- ${DIR_LOCAL}/carconnectivity/sqlite.db:/carconnectivity.db:ro
- ./carconnectivity/carconnectivity-sqlite.yaml:/etc/grafana/provisioning/datasources/carconnectivity-sqlite.yml
environment:
- PUID=1000
- PGID=1004
- TZ=Europe/Stockholm
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD_FILE=/run/secrets/carconnect_grafana_pw
- GF_PLUGINS_TRUSTED_FILES=/carconnectivity.db
secrets:
- carconnect_grafana_pw
restart: unless-stopped
ports:
- "3123:3000"
networks:
- backend
labels:
- diun.enable=true
- "traefik.enable=true"
- "traefik.http.services.carconnect-grafana.loadbalancer.server.port=3000"
- "traefik.http.routers.carconnect-grafana.entrypoints=web-secure"
- "traefik.http.routers.carconnect-grafana.rule=Host(`skoda.${DOMAIN}`)"
- "traefik.http.routers.carconnect-grafana.middlewares=chain-no-auth@file"
- "traefik.http.routers.carconnect-grafana.tls.certresolver=milvert_dns"
- "traefik.http.routers.carconnect-grafana.tls=true"
networks:
frontend:

View File

@ -1,21 +0,0 @@
esphome:
name: $devicename
friendly_name: $friendly_name
esp32:
board: esp32-s3-devkitc-1
flash_size: 16MB
framework:
type: esp-idf
psram:
mode: octal
speed: 80MHz
packages:
sensors: !include nfc-playbox/sensors.yaml
hw: !include nfc-playbox/hw.yaml
images: !include nfc-playbox/images.yaml
ui: !include nfc-playbox/ui.yaml

View File

@ -1,27 +0,0 @@
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: !secret esphome_api_key_nfc1
ota:
- platform: esphome
password: !secret esphome_ota_pass_nfc1
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: none
output_power: 17dB
use_address: 10.0.3.29
domain: .milvert.com
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: ${friendly_name} Hotspot
password: !secret esphome_fallback_ap_password
captive_portal:

5
esphome/.gitignore vendored
View File

@ -1,5 +0,0 @@
# Gitignore settings for ESPHome
# This is an example and may include too much for your use-case.
# You can modify this file to suit your needs.
/.esphome/
/secrets.yaml

View File

@ -1,27 +0,0 @@
substitutions:
devicename: nfc-playbox-1
friendly_name: NFC Playbox_1
SCREEN_W: "320"
SCREEN_H: "240"
RIGHT_COL_W: "80"
ICON_W: "32"
ICON_H: "32"
MARGIN: "8"
HIT_PAD: "6"
globals:
- id: current_image
type: int
initial_value: '0'
- id: show_volume
type: bool
initial_value: 'false'
- id: local_vol
type: float
initial_value: '0.0'
<<: !include .base.yaml
<<: !include .base.nfc-playbox.yaml

View File

@ -1,33 +0,0 @@
spi:
- id: spi_bus
clk_pin: 39 # LCD_SCLK
mosi_pin: 38 # LCD_MOSI
miso_pin: 40 # (MISO finns men används ej av LCD)
- id: spi_bus_rc522
clk_pin: 9
mosi_pin: 14
miso_pin: 13
i2c:
- sda: 48 # TP_SDA
scl: 47 # TP_SCL
id: i2c_bus
scan: true
frequency: 400kHz
time:
- platform: sntp
id: esptime
timezone: "Europe/Stockholm"
light:
- platform: monochromatic
name: "LCD Backlight"
id: backlight
default_transition_length: 0s
output: lcd_bl
restore_mode: ALWAYS_ON

View File

@ -1,20 +0,0 @@
image:
- file: "nfc-playbox/images/spellista_dolly.jpeg"
id: spellista_dolly
type: RGB
- file: "nfc-playbox/images/spellista_godnattstund.jpg"
id: spellista_godnattstund
type: RGB
- file: "nfc-playbox/images/spellista_disco.jpg"
id: spellista_disco
type: RGB
- file: "nfc-playbox/images/spellista_rosahelikopter.jpg"
id: spellista_rosahelikopter
type: RGB
- file: "nfc-playbox/images/background.jpg"
id: background
type: RGB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,129 +0,0 @@
sensor:
- platform: wifi_signal
name: "NFC Playbox WiFi RSSI"
update_interval: 30s
- platform: uptime
name: "NFC Playbox Uptime"
- platform: homeassistant
id: spotvol
entity_id: media_player.ada
attribute: volume_level
on_value:
then:
- lambda: |-
ESP_LOGI("vol", "HA volume_level x=%.3f", (float)x);
if (!isnan(x)) {
id(local_vol) = x;
ESP_LOGI("vol", "local_vol updated to %.3f", id(local_vol));
} else {
ESP_LOGW("vol", "HA volume_level is NaN (ignoring)");
}
- component.update: display_main
# filters:
# - multiply: 100
binary_sensor:
- platform: homeassistant
entity_id: input_boolean.esp32_spotify_volume
id: display_volume
script:
- id: wake_screen
mode: restart
then:
if:
condition:
light.is_off: backlight
then:
- light.turn_on:
id: backlight
brightness: 100%
transition_length: 0s
- delay: 60s
- light.turn_off: backlight
- lambda: |-
id(current_image) = 0;
- component.update: display_main
- id: send_volume_debounced
mode: restart
then:
- delay: 400ms
- homeassistant.service:
service: media_player.volume_set
data:
entity_id: media_player.ada
volume_level: !lambda "ESP_LOGI(\"vol\", \"debounced send volume_set=%.3f\", id(local_vol)); return id(local_vol);"
- id: volume_flash_hide
mode: restart
then:
- delay: 5s
- lambda: |-
id(show_volume) = false;
- component.update: display_main
- id: set_vol_and_flash
mode: restart
parameters:
level: float
then:
- lambda: |-
float clamped = std::max(0.0f, std::min(0.4f, level));
ESP_LOGI("vol", "set_vol_and_flash target=%.3f (clamped)", clamped);
id(local_vol) = clamped;
id(show_volume) = true;
ESP_LOGI("vol", "show_volume=true, local_vol=%.3f", id(local_vol));
- component.update: display_main
- script.execute: send_volume_debounced
- script.execute: volume_flash_hide
- id: volume_up_trigger
then:
- lambda: |-
float step = 0.02f;
float target = id(local_vol) + step;
ESP_LOGI("vol", "volume_up_trigger step=%.2f from=%.3f -> %.3f", step, id(local_vol), target);
id(set_vol_and_flash)->execute(target);
- id: volume_down_trigger
then:
- lambda: |-
float step = 0.02f;
float target = id(local_vol) - step;
ESP_LOGI("vol", "volume_down_trigger step=%.2f from=%.3f -> %.3f", step, id(local_vol), target);
id(set_vol_and_flash)->execute(target);
rc522_spi:
spi_id: spi_bus_rc522
cs_pin: 12
reset_pin: 11
update_interval: 3s
on_tag:
then:
- homeassistant.tag_scanned: !lambda 'return x;'
- lambda: |-
std::string uid = x;
ESP_LOGI("nfc", "Tag scanned: %s", uid.c_str());
//
if (uid == "04-A1-4E-94-2E-02-89") { // spellista_dolly
id(current_image) = 1;
} else if (uid == "04-01-BA-52-2E-02-89") { // spellista_godnattstund
id(current_image) = 2;
} else if (uid == "04-51-0C-91-2E-02-89") { // spellista_disco
id(current_image) = 3;
} else if (uid == "04-01-DF-98-2E-02-89") { // spellista_rosahelikopter
id(current_image) = 4;
} else {
id(current_image) = 0;
}
ESP_LOGI("nfc", "current_image set to %d", id(current_image));
- component.update: display_main
output:
- platform: ledc
pin: 1
id: lcd_bl

View File

@ -1,151 +0,0 @@
touchscreen:
- platform: cst816
id: tp
i2c_id: i2c_bus
interrupt_pin: 46 # TP_INT
reset_pin: 21 # TP_RESET
transform:
mirror_x: false
mirror_y: true
swap_xy: true
calibration:
x_min: 0
x_max: 320
y_min: 30
y_max: 240
on_touch:
then:
- lambda: |-
int px = touch.x;
int py = touch.y;
ESP_LOGI("touch", "Pixel (%d,%d)", px, py);
const int SCREEN_W = ${SCREEN_W};
const int SCREEN_H = ${SCREEN_H};
const int RIGHT_COL_W= ${RIGHT_COL_W};
const int X_SPLIT = SCREEN_W - RIGHT_COL_W;
const int Y_MID = SCREEN_H / 2;
const int CX_RIGHT = X_SPLIT + RIGHT_COL_W / 2;
const int CY_UP = Y_MID / 2;
const int CY_DOWN = Y_MID + (Y_MID / 2);
const int RING_R = 45;
auto hit = [&](int cx, int cy) {
int dx = px - cx;
int dy = py - cy;
return dx*dx + dy*dy <= RING_R*RING_R;
};
if (hit(CX_RIGHT, CY_UP)) {
ESP_LOGI("touch", "VOLUME UP pressed");
id(volume_up_trigger).execute();
} else if (hit(CX_RIGHT, CY_DOWN)) {
id(volume_down_trigger).execute();
ESP_LOGI("touch", "VOLUME DOWN pressed");
}
- script.execute: wake_screen
display:
- platform: ili9xxx
id: display_main
model: ST7789V
cs_pin: 45 # LCD_CS
dc_pin: 42 # LCD_DC
reset_pin: 0 # LCD_RST
spi_id: spi_bus
dimensions:
width: 240
height: 320
rotation: 90 # matchar Waveshares exempel (~EXAMPLE_LCD_ROTATION=1)
invert_colors: true
update_interval: never
lambda: |-
const int SCREEN_W = ${SCREEN_W};
const int SCREEN_H = ${SCREEN_H};
const int RIGHT_COL_W = ${RIGHT_COL_W};
const int X_SPLIT = SCREEN_W - RIGHT_COL_W;
const int Y_MID = SCREEN_H / 2;
const int CX_RIGHT = X_SPLIT + RIGHT_COL_W / 2;
const int CY_UP = Y_MID / 2;
const int CY_DOWN = Y_MID + (Y_MID / 2);
switch (id(current_image)) {
case 1:
it.image(0, 0, id(spellista_dolly));
break;
case 2:
it.image(0, 0, id(spellista_godnattstund));
break;
case 3:
it.image(0, 0, id(spellista_disco));
break;
case 4:
it.image(0, 0, id(spellista_rosahelikopter));
break;
default:
// valfri default-bild/blank
it.image(0, 0, id(background)); // behåll din gamla default om du vill
break;
}
// Svart background till höger
it.filled_rectangle(X_SPLIT, 0, SCREEN_W - 1, SCREEN_H - 1, id(my_black));
it.line(X_SPLIT, 0, X_SPLIT, SCREEN_H - 1);
it.line(X_SPLIT, Y_MID, SCREEN_W - 1, Y_MID);
// Rita minus-cirkel (volym up)
it.print(CX_RIGHT, CY_UP, id(font_icon_spotify), id(my_white), TextAlign::CENTER, "\U000F0417");
// Rita minus-cirkel (volym ned)
it.print(CX_RIGHT, CY_DOWN, id(font_icon_spotify), id(my_white), TextAlign::CENTER, "\U000F0376");
if (id(show_volume)) {
ESP_LOGI("display", "VOLUME is %f", id(local_vol));
it.filled_circle(230, 122, 35, id(my_green));
it.printf(230, 145, id(font40), id(my_black), TextAlign::BOTTOM_CENTER, "%.0f", id(local_vol) * 100.0f);
// HA_value-> to slow?
// it.printf(230, 145, id(font40), id(my_black), TextAlign::BOTTOM_CENTER, "%.0f", id(spotvol).state);
}
color:
- id: my_red
red: 100%
green: 0%
- id: my_green
red: 11.76%
green: 84.31%
blue: 37.65%
- id: my_white
red: 1.0000
green: 1.0000
blue: 1.0000
- id: my_grey
red: 0.6000
green: 0.6000
blue: 0.6000
- id: my_black
red: 0.0000
green: 0.0000
blue: 0.0000
font:
- file: "gfonts://Roboto"
id: font_small
size: 16
- file: 'gfonts://Roboto'
id: font40
size: 40
glyphs: °.0123456789-%d
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_icon_spotify
size: 75
glyphs:
- "\U000F040C" # play-circle
- "\U000F03E5" # pause-circle
- "\U000F0661" # skip-next-circle
- "\U000F0376" # minus-circle
- "\U000F0417" # plus-circle

View File

@ -1,216 +0,0 @@
esphome:
name: nfc-playbox-1
friendly_name: NFC Playbox_1
esp32:
board: esp32-s3-devkitc-1
flash_size: 16MB
framework:
type: esp-idf
psram:
mode: octal
speed: 80MHz
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "OQlmeshTtUZg/iavLExjuNt1H7ywTohWAYozqNym+9M="
ota:
- platform: esphome
password: "14106c281b3e5b1ac1da204b7ff99728"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: none # stabilare link
output_power: 17dB # maxa sändarnivån
use_address: 10.0.3.29
domain: .milvert.com
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Nfc-Playbox-1 Fallback Hotspot"
password: "kQAdTCPYabwd"
captive_portal:
sensor:
- platform: wifi_signal
name: "NFC Playbox WiFi RSSI"
update_interval: 30s
- platform: uptime
name: "NFC Playbox Uptime"
script:
- id: wake_screen
mode: restart
then:
- light.turn_on:
id: backlight
brightness: 100%
# - delay: 60s
# - light.turn_off: backlight
image:
- file: "images/play.png"
id: img_playpause
type: BINARY
- file: "images/low-volume.png"
id: img_voldown
type: BINARY
- file: "images/high-volume.png"
id: img_volup
type: BINARY
globals:
- id: touch_x
type: int
initial_value: "0"
- id: touch_y
type: int
initial_value: "0"
# ---- SPI-buss till LCD
spi:
- id: spi_bus
clk_pin: 39 # LCD_SCLK
mosi_pin: 38 # LCD_MOSI
miso_pin: 40 # (MISO finns men används ej av LCD)
- id: spi_bus_rc522
clk_pin: 13
mosi_pin: 14
miso_pin: 9
rc522_spi:
spi_id: spi_bus_rc522
cs_pin: 12
reset_pin: 11
update_interval: 1s
on_tag:
then:
- logger.log:
format: "RFID Tag UID: %s"
args: [ 'x.c_str()' ]
- homeassistant.tag_scanned: !lambda 'return x;'
# ---- Bakgrundsbelysning (GPIO1 via PWM)
output:
- platform: ledc
pin: 1
id: lcd_bl
light:
- platform: monochromatic
name: "LCD Backlight"
id: backlight
output: lcd_bl
restore_mode: ALWAYS_ON
# ---- I2C för touch (CST816D)
i2c:
sda: 48 # TP_SDA
scl: 47 # TP_SCL
id: i2c_bus
scan: true
frequency: 400kHz
touchscreen:
- platform: cst816
id: tp
interrupt_pin: 46 # TP_INT
reset_pin: 21 # TP_RESET
transform:
mirror_x: false
mirror_y: true
swap_xy: true
calibration:
x_min: 0
x_max: 320
y_min: 30 # offset för min display
y_max: 240
on_touch:
then:
- lambda: |-
const int CELL_SIZE = 40;
const int ICON_R = 22; // radie på cirkeln runt ikonen
// Hjälpfunktion för att kolla träff
auto hit_circle = [&](int col, int row, int px, int py) {
int cx = (col + 1) * CELL_SIZE;
int cy = (row + 1) * CELL_SIZE;
int dx = px - cx;
int dy = py - cy;
return (dx*dx + dy*dy) <= (ICON_R * ICON_R);
};
- script.execute: wake_screen
- logger.log:
format: "Touch coordinates: (%d, %d)"
args: ["touch.x", "touch.y"]
substitutions:
SCREEN_W: "320" # från loggen: ili9xxx Dimensions: 320 x 240
SCREEN_H: "240"
ICON_W: "32"
ICON_H: "32"
MARGIN: "8"
HIT_PAD: "6"
# ---- Display (ST7789T3/ ST7789V 240x320) via moderna 'ili9xxx'
display:
- platform: ili9xxx
id: display_main
model: ST7789V
cs_pin: 45 # LCD_CS
dc_pin: 42 # LCD_DC
reset_pin: 0 # LCD_RST
spi_id: spi_bus
dimensions:
width: 240
height: 320
rotation: 90 # matchar Waveshares exempel (~EXAMPLE_LCD_ROTATION=1)
invert_colors: false
update_interval: 500ms
lambda: |-
const int CELL_SIZE = 40;
auto draw_centered_2x2 = [&](int col, int row, const esphome::display::BaseImage *img) {
const int center_x = (col + 1) * CELL_SIZE;
const int center_y = (row + 1) * CELL_SIZE;
// cirkel runt ikonen
it.circle(center_x, center_y, 22);
// rita ikonen (32x32 → offset 16)
it.image(center_x - 16, center_y - 16,
const_cast<esphome::display::BaseImage*>(img));
};
// PLAY i blocket (1,2)-(2,3)
draw_centered_2x2(1, 2, id(img_playpause));
// VOL UP i blocket (3,2)-(4,3)
draw_centered_2x2(3, 2, id(img_volup));
// VOL DOWN i blocket (5,2)-(6,3)
draw_centered_2x2(5, 2, id(img_voldown));
# ---- Klocka och font (för att visa något)
time:
- platform: sntp
id: esptime
timezone: "Europe/Stockholm"
font:
- file: "gfonts://Roboto"
id: font_small
size: 16

View File

@ -1,634 +0,0 @@
# https://community.home-assistant.io/t/awesome-spotify-touch-control-via-ili9341-screen/406328
logger:
ota:
api:
captive_portal:
time:
platform: homeassistant
id: esptime
spi:
clk_pin: GPIO18
mosi_pin: GPIO23
miso_pin: GPIO19
font:
- file: 'fonts/verdana.ttf'
id: font40
size: 40
glyphs: °.0123456789-%d
- file: 'fonts/verdana.ttf'
id: font_spot_time
size: 12
glyphs: :0123456789
- file: 'fonts/verdana.ttf'
id: font21
size: 21
glyphs: ['&', '@', '<', '>', '$', '!', ',', '.', '?', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/', '\', '\xab', '\xc3', '\xaf', '''', 'ß' ]
- file: 'fonts/verdana.ttf'
id: font18
size: 18
glyphs: ['&', '@', '<', '>', '$', '!', ',', '.', '?', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/', '\', '''', 'ß' ]
- file: 'fonts/verdana.ttf'
id: font16
size: 16
glyphs: ['&', '@', '!', ',', '.', '?', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/', '\', '''', 'ß' ]
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_icon_spotify
size: 75
glyphs:
- "\U000F040C" # play-circle
- "\U000F03E5" # pause-circle
- "\U000F0661" # skip-next-circle
- "\U000F0376" # minus-circle
- "\U000F0417" # plus-circle
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_icon_spotify_big
size: 80
glyphs:
- "\U000F04C7" # Spotify Icon
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_icon_spotify_infobar
size: 30
glyphs:
- "\U000F04C7" # Spotify Icon
- "\U000F0595" # Wetter Icon
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_icon_spotify_infobar_s
size: 24
glyphs:
- "\U000F049D" # Shuffle on Icon
- "\U000F049E" # Shuffle off Icon
color:
- id: my_red
red: 100%
green: 0%
- id: my_green
red: 0%
green: 100%
blue: 30%
- id: my_white
red: 1.0000
green: 1.0000
blue: 1.0000
- id: my_grey
red: 0.6000
green: 0.6000
blue: 0.6000
- id: my_black
red: 0.0000
green: 0.0000
blue: 0.0000
output:
# backlight
- platform: ledc
pin: 15
id: gpio_15_backlight_pwm_touch
inverted: false
light:
- platform: monochromatic
output: gpio_15_backlight_pwm_touch
name: "ILI9341 Display Backlight Touch"
id: back_light_touch
restore_mode: RESTORE_DEFAULT_ON
text_sensor:
- platform: homeassistant
id: current_title
entity_id: sensor.esp32_media_player_current_title
- platform: homeassistant
id: current_artist
entity_id: sensor.esp32_media_player_current_artist
- platform: homeassistant
id: current_playlist
entity_id: sensor.esp32_media_player_current_playlist
- platform: homeassistant
id: spotify
entity_id: sensor.esp32_media_player_status
- platform: homeassistant
id: spotpostime
entity_id: sensor.esp32_spotify_position_time
- platform: homeassistant
id: spotdur
entity_id: sensor.esp32_spotify_duration
sensor:
- platform: homeassistant
id: spotvol
entity_id: sensor.esp32_spotify_volume
filters:
- multiply: 10
- platform: homeassistant
id: spotpos
entity_id: sensor.esp32_spotify_position
- platform: homeassistant
id: spotpos2
entity_id: sensor.esp32_spotify_position
filters:
- offset: 78
binary_sensor:
- platform: homeassistant
entity_id: input_boolean.esp32_wetter_screen
id: display_wetter
- platform: homeassistant
entity_id: input_boolean.esp32_spotify_volume
id: display_volume
- platform: homeassistant
entity_id: binary_sensor.esp32_spotify_shuffle
id: spotify_shuffle
- platform: homeassistant
entity_id: input_boolean.esp32_spotify_playlist_menu
id: playlist
- platform: xpt2046
xpt2046_id: touchscreen # Start Play/Pause
id: touch_play
x_min: 35
x_max: 110
y_min: 2
y_max: 77
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state == "playing";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- and:
- lambda: 'return id(spotify).state == "paused";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
then:
- homeassistant.service:
service: script.esp32_spotify_play_pause
- platform: xpt2046
xpt2046_id: touchscreen # Next Track
id: touch_next
x_min: 35
x_max: 110
y_min: 78
y_max: 154
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state == "playing";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- and:
- lambda: 'return id(spotify).state == "paused";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
then:
- homeassistant.service:
service: media_player.media_next_track
data:
entity_id: media_player.spotify_xxx
- platform: xpt2046
xpt2046_id: touchscreen # Volume -
id: touch_minus
x_min: 35
x_max: 110
y_min: 155
y_max: 230
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state == "playing";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- and:
- lambda: 'return id(spotify).state == "paused";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
then:
- homeassistant.service:
service: script.esp32_spotify_volume_down
- platform: xpt2046
xpt2046_id: touchscreen # Volume +
id: touch_plus
x_min: 35
x_max: 110
y_min: 232
y_max: 295
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state == "playing";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- and:
- lambda: 'return id(spotify).state == "paused";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
then:
- homeassistant.service:
service: script.esp32_spotify_volume_up
- platform: xpt2046
xpt2046_id: touchscreen # Start Spotify
id: touch_info_spot
x_min: 195
x_max: 239
y_min: 275
y_max: 319
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state != "playing";'
- lambda: 'return id(spotify).state != "paused";'
- and:
- lambda: 'return id(display_wetter).state;'
then:
- homeassistant.service:
service: script.esp32_open_spotify
- platform: xpt2046
xpt2046_id: touchscreen # Turn on Display Wetter
id: touch_info_wetter
x_min: 195
x_max: 239
y_min: 275
y_max: 319
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state == "playing";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- and:
- lambda: 'return id(spotify).state == "paused";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
then:
- homeassistant.service:
service: script.esp32_open_display_wetter
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_info_spot_shuffle_off # Touch Shuffle off
x_min: 205
x_max: 239
y_min: 75
y_max: 120
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state == "playing";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- lambda: 'return id(spotify_shuffle).state == false;'
- and:
- lambda: 'return id(spotify).state == "paused";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- lambda: 'return id(spotify_shuffle).state == false;'
then:
- homeassistant.service:
service: media_player.shuffle_set
data:
shuffle: 'true'
entity_id: media_player.spotify_xxx
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_info_spot_shuffle_on # Touch Shuffle on
x_min: 205
x_max: 239
y_min: 75
y_max: 120
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state == "playing";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- lambda: 'return id(spotify_shuffle).state;'
- and:
- lambda: 'return id(spotify).state == "paused";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- lambda: 'return id(spotify_shuffle).state;'
then:
- homeassistant.service:
service: media_player.shuffle_set
data:
shuffle: 'false'
entity_id: media_player.spotify_xxx
#START SPOTIFY PLAYLIST TOUCH
- platform: xpt2046
xpt2046_id: touchscreen # Spotify Icon Playlist
id: touch_playlist
x_max: 180
y_min: 3
x_min: 105
y_max: 75
on_press:
if:
condition:
or:
- and:
- lambda: 'return id(spotify).state == "playing";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
- and:
- lambda: 'return id(spotify).state == "paused";'
- lambda: 'return id(playlist).state;'
- lambda: 'return id(display_wetter).state == false;'
then:
- homeassistant.service:
service: input_boolean.toggle
data:
entity_id: input_boolean.esp32_spotify_playlist_menu
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_B1
x_max: 239
y_min: 200
x_min: 201
y_max: 319
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_b1
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_A1
x_max: 239
y_min: 75
x_min: 201
y_max: 199
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_a1
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_B2
x_max: 200
y_min: 200
x_min: 161
y_max: 319
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_b2
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_A2
x_max: 200
y_min: 75
x_min: 161
y_max: 199
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_a2
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_B3
x_max: 160
y_min: 200
x_min: 121
y_max: 319
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_b3
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_A3
x_max: 160
y_min: 75
x_min: 121
y_max: 199
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_a3
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_B4
x_max: 120
y_min: 200
x_min: 81
y_max: 319
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_b4
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_A4
x_max: 120
y_min: 75
x_min: 81
y_max: 199
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_a4
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_B5
x_max: 80
y_min: 200
x_min: 41
y_max: 319
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_b5
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_A5
x_max: 80
y_min: 75
x_min: 41
y_max: 199
on_press:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_a5
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_B6
x_max: 40
y_min: 200
x_min: 2
y_max: 319
on_state:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_b6
- platform: xpt2046
xpt2046_id: touchscreen
id: touch_A6
x_max: 40
y_min: 75
x_min: 2
y_max: 199
on_state:
if:
condition:
binary_sensor.is_off: playlist
then:
- homeassistant.service:
service: script.esp32_spotify_playlist_a6
xpt2046:
id: touchscreen
cs_pin: 14
irq_pin: 27
update_interval: 50ms
report_interval: 1s
threshold: 400
dimension_x: 240
dimension_y: 320
calibration_x_min: 3860
calibration_x_max: 280
calibration_y_min: 340
calibration_y_max: 3860
swap_x_y: false
display:
- platform: ili9341
model: TFT 2.4
id: touch_display
cs_pin: GPIO5
dc_pin: GPIO4
reset_pin: GPIO22
rotation: 270
lambda: |-
auto black = Color(0, 0, 0);
it.fill(black);
// WENN SPOTIFY SPIELT BUTTONS
if ((id(spotify).state == "playing" or id(spotify).state == "paused") and id(display_wetter).state == false) {
if (id(spotify).state == "playing")
{ it.print(0, 155, id(font_icon_spotify), id(my_green), TextAlign::TOP_LEFT, "\U000F03E5"); } // Pause Icon
else
{ it.print(0, 155, id(font_icon_spotify), id(my_white), TextAlign::TOP_LEFT, "\U000F040C"); } // Play Icon
it.print(-5, 43, id(font_icon_spotify_big), id(my_green), TextAlign::TOP_LEFT, "\U000F04C7"); // Spotify Icon gross
// WENN SPOTIFY SPIELT UND PLAYLIST GESCHLOSSEN
if (id(playlist).state) {
if (id(spotify_shuffle).state) {
it.print(98, 3, id(font_icon_spotify_infobar_s), id(my_green), TextAlign::TOP_RIGHT, "\U000F049D"); // Shuffle on
}
else {
it.print(98, 3, id(font_icon_spotify_infobar_s), id(my_white), TextAlign::TOP_RIGHT, "\U000F049E"); // Shuffle off
}
it.strftime(4, 0, id(font21), id(my_white), TextAlign::TOP_LEFT, "%H:%M", id(esptime).now());
it.filled_circle(319, 0, 40, id(my_white));
it.print(319, 1, id(font_icon_spotify_infobar), id(my_black), TextAlign::TOP_RIGHT, "\U000F0595"); // Wetter Display
it.print(78, 66, id(font21), id(my_white), TextAlign::TOP_LEFT, id(current_title).state.c_str()); // Track Infos
it.print(78, 91, id(font21), id(my_white), TextAlign::TOP_LEFT, id(current_artist).state.c_str());
it.print(78, 46, id(font18), id(my_green), TextAlign::TOP_LEFT, id(current_playlist).state.c_str());
// it.printf(78, 35, id(font18), id(my_green), TextAlign::TOP_LEFT, "%.0f", id(spotpos).state);
it.filled_rectangle(78, 130, 222, 2, id(my_grey)); // Progress Back
it.filled_rectangle(78, 130, id(spotpos).state, 2, id(my_green)); // Progress Bar
it.filled_circle(id(spotpos2).state, 130, 4, id(my_green)); // Progress Circle
it.print(78, 133, id(font_spot_time), id(my_green), TextAlign::TOP_LEFT, id(spotpostime).state.c_str()); // Position Song
it.print(300, 133, id(font_spot_time), id(my_green), TextAlign::TOP_RIGHT, id(spotdur).state.c_str()); // Duration Song
it.print(78, 155, id(font_icon_spotify), id(my_white), TextAlign::TOP_LEFT, "\U000F0661"); // Next Track
it.print(155, 155, id(font_icon_spotify), id(my_white), TextAlign::TOP_LEFT, "\U000F0376"); // Volume-
it.print(232, 155, id(font_icon_spotify), id(my_white), TextAlign::TOP_LEFT, "\U000F0417"); // Volume+
if (id(display_volume).state) { // Volume State
it.filled_circle(230, 122, 35, id(my_green));
it.printf(230, 145, id(font40), id(my_black), TextAlign::BOTTOM_CENTER, "%.0f", id(spotvol).state);
}
}
// WENN SPOTIFY SPIELT UND PLAYLIST OFFEN
else if ((id(spotify).state == "playing" or id(spotify).state == "paused") and id(playlist).state == false) {
it.line(76, 0, 76, 240);
it.line(200, 0, 200, 240);
it.line(319, 0, 319, 240);
it.line(76, 0, 319, 0);
it.line(76, 40, 319, 40);
it.line(76, 80, 319, 80);
it.line(76, 120, 319, 120);
it.line(76, 160, 319, 160);
it.line(76, 200, 319, 200);
it.line(76, 239, 319, 239);
it.print(85, 20, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Mix d.Woche");
it.print(85, 60, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Playlist W");
it.print(85, 100, id(font18), id(my_white), TextAlign::CENTER_LEFT, "me right no");
it.print(85, 140, id(font18), id(my_white), TextAlign::CENTER_LEFT, "House Party");
it.print(85, 180, id(font18), id(my_white), TextAlign::CENTER_LEFT, "News");
it.print(85, 220, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Playlist Z");
it.print(209, 20, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Playlist X");
it.print(209, 60, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Playlist Y");
it.print(209, 100, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Pool Electro");
it.print(209, 140, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Hot Hits");
it.print(209, 180, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Kaffeehaus");
it.print(209, 220, id(font18), id(my_white), TextAlign::CENTER_LEFT, "Chilled Dan");
}}
else {
// STATUSLEISTE ZEIT ODER WETTERWARNUNG
it.strftime(4, 3, id(font21), id(my_white), TextAlign::TOP_LEFT, "%H:%M", id(esptime).now());
it.filled_circle(319, 0, 40, id(my_white));
it.print(319, 1, id(font_icon_spotify_infobar), id(my_black), TextAlign::TOP_RIGHT, "\U000F04C7"); // Spotify Icon Infobar
}

View File

@ -1,59 +1,37 @@
sponsortoken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJldmNjLmlvIiwic3ViIjoibWlsdmVydCIsImV4cCI6MTgzMDE5MzIwMCwiaWF0IjoxNzM1NTg1MjAwLCJzcmMiOiJnaCJ9._K23QsA15DIHRjujwH8rnFZyloSw1RPIeIS4W5WLFGE
log: info
log: error
levels:
tariff: info
tariff: trace
interval: 30s
vehicles:
# - name: car
# type: custom
# title: id4
# capacity: 79 # kWh
# soc:
# source: mqtt
# topic: weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/charging/batteryStatus/currentSOC_pct
# range:
# source: mqtt
# topic: weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/fuelStatus/rangeStatus/primaryEngine/remainingRange_km
# odometer:
# source: mqtt
# topic: weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/measurements/odometerStatus/odometer
# climater:
# source: go
# vm: shared
# script: |
# remoteClimateState != "off"
# in:
# - name: remoteClimateState
# type: string
# config:
# source: mqtt
# topic: weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/climatisation/climatisationStatus/climatisationState
- name: skoda_car
- name: car
type: custom
title: elroq
capacity: 64 # kWh
title: id4
capacity: 79 # kWh
soc:
source: mqtt
topic: carconnectivity/0/garage/TMBNC7NY8SF105227/drives/primary/level
topic: weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/charging/batteryStatus/currentSOC_pct
range:
source: mqtt
topic: carconnectivity/0/garage/TMBNC7NY8SF105227/drives/primary/range
topic: weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/fuelStatus/rangeStatus/primaryEngine/remainingRange_km
odometer:
source: mqtt
topic: carconnectivity/0/garage/TMBNC7NY8SF105227/odometer
topic: weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/measurements/odometerStatus/odometer
climater:
source: mqtt
topic: carconnectivity/0/garage/TMBNC7NY8SF105227/climatization/binarystate
limitsoc:
source: mqtt
topic: carconnectivity/0/garage/TMBNC7NY8SF105227/charging/settings/target_level
status:
source: mqtt
topic: carconnectivity/0/garage/TMBNC7NY8SF105227/charging/state
source: go
vm: shared
script: |
remoteClimateState != "off"
in:
- name: remoteClimateState
type: string
config:
source: mqtt
topic: weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/climatisation/climatisationStatus/climatisationState
chargers:
- name: wallbox
@ -72,9 +50,10 @@ circuits:
loadpoints:
- title: Garage
charger: wallbox
vehicle: skoda_car
vehicle: car
circuit: main
mode: pv
phases: 3
enable:
threshold: 0
delay: 15s

View File

@ -1,87 +0,0 @@
APP_NAME = Gitea: Git with a cup of simon
RUN_MODE = prod
RUN_USER = git
WORK_PATH = /data/gitea
[repository]
ROOT = /data/git/repositories
[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
[repository.upload]
TEMP_PATH = /data/gitea/uploads
[server]
APP_DATA_PATH = /data/gitea
SSH_DOMAIN = milvert.com
HTTP_PORT = 3000
ROOT_URL = https://gitea.milvert.com/
# ROOT_URL = http://localhost:3000/
DISABLE_SSH = false
SSH_PORT = 22
LFS_START_SERVER = true
LFS = /data/git/lfs
DOMAIN = gitea.milvert.com
LFS_JWT_SECRET = k0fQxO-UgL1dT55DxBy7ylQpj4A7HDjXiZQs-VxSs6E
OFFLINE_MODE = false
[database]
PATH = /data/gitea/gitea.db
DB_TYPE = sqlite3
HOST = localhost:3306
NAME = gitea
USER = root
PASSWD =
SSL_MODE = disable
CHARSET = utf8
[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER = file
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = true
[attachment]
PATH = /data/gitea/attachments
[log]
ROOT_PATH = /data/gitea/log
MODE = file
LEVEL = info
[security]
INSTALL_LOCK = true
SECRET_KEY = 5Aocki6hsR7kzfZ7LJsKF7VESSZ4IMxEtGVc1YLEjGVUTYjnlTtOxL8vY7dLVFOi
INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE1NzM5MzU0OTl9.F1h5ZnL5eXqAgPp8Ya4tvhwFK08CyZQdETkyB9O5D34
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = true
ENABLE_CAPTCHA = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING = true
SHOW_REGISTRATION_BUTTON = false
NO_REPLY_ADDRESS = noreply.example.org
[oauth2]
JWT_SECRET = bnlTPZHUxEH5WGrJIAcY5IAqisk3BFb7XY8SUeI5XjA
[mailer]
ENABLED = false
[openid]
ENABLE_OPENID_SIGNIN = false
ENABLE_OPENID_SIGNUP = true
WHITELISTED_URIS = authelia.milvert.com

View File

@ -1135,6 +1135,5 @@ api_url = https://authelia.milvert.com/api/oidc/userinfo # Replace with y
login_attribute_path = preferred_username
groups_attribute_path = groups
name_attribute_path = name
role_attribute_path = contains(groups[*], 'admin') && 'Admin' || 'Editor'
use_pkce = true
auto_login = true

View File

@ -614,142 +614,3 @@
message: Varning! Frost kan vara på gång ❄️ (enligt prognos eller temptrend)
action: notify.mobile_app_simon_mobil
mode: single
- id: '1745266231556'
alias: Nimly_31_manual
description: ''
triggers:
- trigger: time
at: 06:45:00
conditions: []
actions:
- action: mqtt.publish
metadata: {}
data:
qos: '0'
retain: false
topic: zigbee_home_2/h014s/set/pin_code
payload: "{\n \"user\": 31,\n \"user_type\": \"unrestricted\",\n \"user_enabled\":
true,\n \"pin_code\": 9480\n }\n"
mode: single
- id: '1745266911651'
alias: enable_31
description: ''
use_blueprint:
path: user/nimly_lock.yaml
input:
lock_device: lock.h014s
trigger_time: 06:45:00
pin_code: '9480'
user_id: 31
enabled: true
- id: '1745267035417'
alias: disable_31
description: ''
use_blueprint:
path: user/nimly_lock.yaml
input:
trigger_time: '17:00:00'
lock_device: lock.h014s
user_id: 31
pin_code: 'null'
enabled: false
- id: '1746992840091'
alias: Save last person detection
description: ''
triggers:
- type: turned_on
device_id: 80ecd4d9a212d4bc811d958b336ccec0
entity_id: 390b057edde8e3a7ce5dd96fbc8f7486
domain: binary_sensor
trigger: device
conditions: []
actions:
- action: camera.snapshot
metadata: {}
data:
filename: /config/www/last_person_detection.jpg
target:
device_id: 80ecd4d9a212d4bc811d958b336ccec0
mode: single
- id: '1755028231874'
alias: 'Spela musik '
description: ''
triggers:
- trigger: tag
tag_id: d317de29-a548-4041-92a8-b34627e45cc3
conditions: []
actions:
- action: media_player.play_media
metadata: {}
data:
media_content_type: Music
media_content_id: spotify:playlist:37i9dQZF1DWVCKO3xAlT1Q
target:
entity_id: media_player.ada
mode: single
- id: '1756585900611'
alias: NFC Playbox
description: ''
triggers:
- event_type: tag_scanned
trigger: event
actions:
- choose:
- conditions:
- condition: template
value_template: '{{ current is defined and current.method == ''play_media''
}}'
sequence:
- target:
entity_id: '{{ current.player }}'
data:
media:
media_content_id: '{{ current.media_content_id }}'
media_content_type: '{{ current.media_content_type | default(''Music'')
}}'
metadata: {}
action: media_player.play_media
- conditions:
- condition: template
value_template: '{{ current is defined and current.method == ''select_source''
}}'
sequence:
- target:
entity_id: '{{ current.player }}'
data:
source: '{{ current.source }}'
action: media_player.select_source
default:
- data:
title: NFC Playbox
message: 'Okänd NFC-tagg: {{ tag_id }}'
action: persistent_notification.create
mode: single
variables:
TAGS:
04-A1-4E-94-2E-02-89:
info: spellista_dolly
method: play_media
player: media_player.ada
media_content_id: spotify:playlist:3CTFR7Tf99Nj6rSM5l5HRf
media_content_type: playlist
04-01-BA-52-2E-02-89:
info: spellista_godnattstund
method: play_media
player: media_player.ada
media_content_id: spotify:playlist:2hHIaWS6pELC5w58vJraVJ
media_content_type: playlist
04-51-0C-91-2E-02-89:
info: spellista_disco
method: play_media
player: media_player.ada
media_content_id: spotify:playlist:7Lu5u70XvPDvRMc4fwMsLY
media_content_type: playlist
04-01-DF-98-2E-02-89:
info: spellista_rosahelikopter
method: play_media
player: media_player.ada
media_content_id: spotify:playlist:37i9dQZF1E8C5l0TDkGXpx
media_content_type: playlist
tag_id: '{{ trigger.event.data.tag_id }}'
current: '{{ TAGS.get(tag_id) }}'

View File

@ -1,58 +0,0 @@
blueprint:
name: Nimly lås - Enable/Disable användare
description: Aktivera/inaktivera användare via MQTT till Nimly-lås i Zigbee2MQTT.
domain: automation
input:
trigger_time:
name: Tidpunkt
description: När automationen ska köras
selector:
time: {}
lock_device:
name: Välj låsenhet
description: Låset som ska styras
selector:
entity:
domain: lock
user_id:
name: Användar-ID
description: ID för användaren på låset
selector:
number:
min: 1
max: 250
pin_code:
name: PIN-kod
description: PIN-kod för användaren. Sätt till null för att ta bort den.
default: null
selector:
text:
enabled:
name: Aktivera användare
description: true för att aktivera, false för att inaktivera
selector:
boolean: {}
mode: single
triggers:
- trigger: time
at: !input trigger_time
variables:
topic: "zigbee_home_2/h014s/set/pin_code"
user_id: !input user_id
pin_code: !input pin_code
enabled: !input enabled
actions:
- service: mqtt.publish
data:
topic: "{{ topic }}"
payload: >
{
"user": {{ user_id }},
"user_type": "unrestricted",
"user_enabled": {{ enabled | lower }},
"pin_code": {{ 'null' if pin_code == 'null' else '"' ~ pin_code ~ '"' }}
}

View File

@ -1,36 +0,0 @@
blueprint:
name: Announce
description: A script that announces a message on a media player using text-to-speech.
domain: script
input:
text_to_speech_engine:
selector:
entity:
domain:
- tts
multiple: false
name: Text-to-Speech engine
media_player:
selector:
entity:
domain:
- media_player
multiple: true
name: Media Player
source_url: https://community.home-assistant.io/t/announce-text-to-speech-on-media-player/699186
mode: queued
fields:
message:
selector:
text:
multiline: true
name: Message
description: The message to broadcast
required: true
sequence:
- service: tts.speak
data:
media_player_entity_id: !input media_player
message: '{{ message }}'
target:
entity_id: !input text_to_speech_engine

View File

@ -1,27 +0,0 @@
blueprint:
name: Invert a binary sensor
description: Creates a binary_sensor which holds the inverted value of a reference binary_sensor
domain: template
source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/template/blueprints/inverted_binary_sensor.yaml
input:
reference_entity:
name: Binary sensor to be inverted
description: The binary_sensor which needs to have its value inverted
selector:
entity:
domain: binary_sensor
variables:
reference_entity: !input reference_entity
binary_sensor:
state: >
{% if states(reference_entity) == 'on' %}
off
{% elif states(reference_entity) == 'off' %}
on
{% else %}
{{ states(reference_entity) }}
{% endif %}
# delay_on: not_used in this example
# delay_off: not_used in this example
# auto_off: not_used in this example
availability: "{{ states(reference_entity) not in ('unknown', 'unavailable') }}"

View File

@ -110,3 +110,4 @@ template:

View File

@ -1,9 +0,0 @@
house_mode:
name: Husläge
options:
- HOME
- AWAY
- GUEST
icon: mdi:home-account

View File

@ -1,18 +0,0 @@
simon_location:
name: Simon Location
options:
- Home
- Just Arrived
- Just Left
- Away
- Extended Away
initial: Away
simon_work_state:
name: Simon - Arbetsläge
options:
- Hemma
- På jobbet
- Okänd
initial: Okänd
icon: mdi:briefcase

View File

@ -1,31 +0,0 @@
sensor:
# A. Konverterar källsensorn (kW) till Watt (W)
# - platform: template
# sensors:
# total_power_w:
# friendly_name: "Total Effekt i Watt"
# unit_of_measurement: "W"
# value_template: "{{ (states('sensor.dsmr_reading_electricity_currently_delivered') | float(0) * 1000) | round(0) }}"
#
# # B. 60-minuters medeleffekt (Filter-sensorn)
# - platform: filter
# name: "Medeleffekt 60 minuter"
# entity_id: sensor.total_power_w
# filters:
# # Filter 1: time_throttle (Använder 'filter' nyckeln)
# - filter: time_throttle
# duration: "00:01:00" # Mätpunkter tillåts max varje minut
#
# # Filter 2: mean (Använder 'filter' nyckeln)
# - filter: mean # <-- KORRIGERAD: Använder 'filter: mean'
# window_size: 60 # Beräknar rullande medelvärde över de senaste 60 mätpunkterna
#
# # C. Högsta Medeleffekt Månad (Max/Min-sensorn)
# - platform: max_min
# name: "Högsta Timmedeleffekt Månad"
# entity_id: sensor.medeleffekt_60_minuter
# type: max
# unique_id: ellevio_max_timme_manad
# max_age:
# days: 35

View File

@ -0,0 +1,11 @@
group:
jul_group:
entities:
- light.jul_angel_ada
- switch.nodeid_7_nodeid_7_switch
- switch.ute_garage_slinga
- switch.nodeid_14_nodeid_14_switch
- switch.nodeid_4_nodeid_4_switch
- switch.nodeid_26_nodeid_26_switch
- switch.nodeid_27_nodeid_27_switch

View File

@ -1,83 +0,0 @@
#automation:
# - id: arbetsrum_reglering_simon_work_state
# alias: Arbetsrum reglering med inkrementell styrning
# trigger:
# - platform: state
# entity_id: input_select.simon_work_state
# - platform: state
# entity_id: sensor.h015l_device_temperature
# mode: single
# action:
# - choose:
# # === Jobbar hemma ===
# - conditions:
# - condition: state
# entity_id: input_select.simon_work_state
# state: "Hemma"
# sequence:
# - choose:
# # för kallt
# - conditions:
# - condition: numeric_state
# entity_id: sensor.h015l_device_temperature
# below: 19.5
# sequence:
# - service: climate.set_temperature
# target:
# entity_id: climate.arbetsrum
# data:
# temperature: >
# {{ state_attr('climate.arbetsrum', 'temperature') | float + 1 }}
# # för varmt
# - conditions:
# - condition: numeric_state
# entity_id: sensor.h015l_device_temperature
# above: 20.5
# sequence:
# - service: climate.set_temperature
# target:
# entity_id: climate.arbetsrum
# data:
# temperature: >
# {{ state_attr('climate.arbetsrum', 'temperature') | float - 1 }}
# default: []
#
# # === Inte hemmaläge ===
# - conditions:
# - condition: or
# conditions:
# - condition: state
# entity_id: input_select.simon_work_state
# state: "På jobbet"
# - condition: state
# entity_id: input_select.simon_work_state
# state: "Okänd"
# sequence:
# - choose:
# # för kallt (håll runt 17)
# - conditions:
# - condition: numeric_state
# entity_id: sensor.h015l_device_temperature
# below: 16.5
# sequence:
# - service: climate.set_temperature
# target:
# entity_id: climate.arbetsrum
# data:
# temperature: >
# {{ state_attr('climate.arbetsrum', 'temperature') | float + 1 }}
# # för varmt
# - conditions:
# - condition: numeric_state
# entity_id: sensor.h015l_device_temperature
# above: 17.5
# sequence:
# - service: climate.set_temperature
# target:
# entity_id: climate.arbetsrum
# data:
# temperature: >
# {{ state_attr('climate.arbetsrum', 'temperature') | float - 1 }}
# default: []
# default: []
#

View File

@ -1,13 +0,0 @@
automation:
- id: simon_arrives_home
alias: Simon arrives home
trigger:
- platform: state
entity_id: binary_sensor.simon_presence
to: "on"
action:
- service: input_select.select_option
target:
entity_id: input_select.location
data:
option: "Home"

View File

@ -1,12 +0,0 @@
binary_sensor:
- platform: bayesian
name: "Simon Presence"
prior: 0.7
probability_threshold: 0.9
observations:
- platform: state
entity_id: person.simon
to_state: "home"
prob_given_true: 0.95
prob_given_false: 0.15

View File

@ -1,64 +0,0 @@
automation:
- id: simon_work_home
alias: Simon works from home
trigger:
- platform: state
entity_id:
- device_tracker.rd0203606
- device_tracker.simon_jobbdator
condition:
- condition: time
after: "08:00:00"
before: "17:00:00"
weekday:
- mon
- tue
- wed
- thu
- fri
- condition: or
conditions:
- condition: state
entity_id: device_tracker.rd0203606
state: "home"
- condition: state
entity_id: device_tracker.simon_jobbdator
state: "home"
action:
- service: input_select.select_option
target:
entity_id: input_select.simon_work_state
data:
option: "Hemma"
- id: simon_work_office
alias: Simon works at office
trigger:
- platform: state
entity_id:
- device_tracker.rd0203606
- device_tracker.simon_jobbdator
condition:
- condition: time
after: "08:00:00"
before: "17:00:00"
weekday:
- mon
- tue
- wed
- thu
- fri
- condition: and
conditions:
- condition: state
entity_id: device_tracker.rd0203606
state: "not_home"
- condition: state
entity_id: device_tracker.simon_jobbdator
state: "not_home"
action:
- service: input_select.select_option
target:
entity_id: input_select.simon_work_state
data:
option: "På jobbet"

View File

@ -0,0 +1,85 @@
mqtt:
lock:
- name: jaffa_locked
unique_id: uniqueid__jaffa_locked
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/access/accessStatus/doorLockStatus"
command_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/controls/access"
payload_lock: "locked"
payload_unlock: "unlocked"
device:
identifiers: jaffa
sensor:
- name: jaffa_long
unique_id: uniqueid__jaffa_long
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/parking/parkingPosition/longitude"
unit_of_measurement: °
entity_category: diagnostic
device:
identifiers: jaffa
- name: jaffa_lat
unique_id: uniqueid__jaffa_lat
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/parking/parkingPosition/latitude"
unit_of_measurement: °
entity_category: diagnostic
device:
identifiers: jaffa
- name: jaffa_parikingtime
unique_id: uniqueid__jaffa_parikingtime
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/parking/parkingPosition/carCapturedTimestamp"
value_template: "{{ as_datetime(value) }}"
device_class: "timestamp"
entity_category: diagnostic
device:
identifiers: jaffa
- name: jaffa_battery_soc
unique_id: uniqueid__jaffa_battery_soc
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/charging/batteryStatus/currentSOC_pct"
unit_of_measurement: "%"
device_class: battery
device:
identifiers: jaffa
- name: jaffa_battery_target_soc
unique_id: uniqueid_jjaffa_battery_target_soc
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/charging/chargingSettings/targetSOC_pct"
unit_of_measurement: "%"
device_class: battery
device:
identifiers: jaffa
- name: jaffa_rated_battery_range_km
unique_id: jaffa_rated_battery_range_km
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/charging/batteryStatus/cruisingRangeElectric_km"
unit_of_measurement: km
device_class: distance
device:
identifiers: jaffa
- name: jaffa_odometer
unique_id: jaffa_odometer
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/measurements/odometerStatus/odometer"
unit_of_measurement: km
device_class: distance
device:
identifiers: jaffa
- name: jaffa_charge_mode
unique_id: jaffa_charge_mode
state_topic: "weconnect/0/vehicles/WVGZZZE2ZPE051949/domains/charging/chargingStatus/chargeMode"
device_class: enum
value_template: >
{% set mapper = {
'0': 'manual',
'1': 'timer',
'2': 'onlyOwnCurrent',
'3': 'preferredChargingTimes',
'4': 'timerChargingWithClimatisation',
'5': 'invalid'
} %}
{{ mapper.get(value, 'Unknown') }}
device:
identifiers: jaffa

View File

@ -0,0 +1,30 @@
# Example configuration.yaml entry
#rflink:
# host: 172.19.0.1
# port: 20108
#light:
# - platform: rflink
# automatic_add: false
#devices:
# newkaku_0008f252_1:
# name: Ute Framsidan
#sensor:
# - platform: rflink
# automatic_add: true
#switch:
# - platform: rflink
# device_defaults:
# fire_event: true
# devices:
# newkaku_000a134e_10:
# name: "Utebaksida brytare"
# newkaku_002c5ad2_1:
# name: "Oscar moln"
# newkaku_002c5ad2_2:
# name: "Oscar skrivbord"
# newkaku_002c5ad2_3:
# name: "Oscar tak"

View File

@ -21,3 +21,8 @@ sensor:
'00:00:00'
{% endif %}
scan_interval: 60
- platform: command_line
name: Simple Test Sensor
command: "echo 'Test success'"
scan_interval: 10

View File

@ -281,51 +281,3 @@ varmepump_nattlage_med_stegvis_justering:
seconds: 0
- action: climate.set_fan_mode
data: {}
nfc_playbox_volume_handler:
alias: NFC-playbox Volume up
sequence:
- data: {}
target:
entity_id: input_boolean.esp32_spotify_volume
action: input_boolean.turn_on
- data: {}
target:
entity_id:
- media_player.ada
action: media_player.volume_up
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- data: {}
target:
entity_id: input_boolean.esp32_spotify_volume
action: input_boolean.turn_off
mode: restart
icon: mdi:spotify
description: ''
nfc_playbox_volume_down:
sequence:
- data: {}
target:
entity_id: input_boolean.esp32_spotify_volume
action: input_boolean.turn_on
- data: {}
target:
entity_id:
- media_player.ada
action: media_player.volume_down
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- data: {}
target:
entity_id: input_boolean.esp32_spotify_volume
action: input_boolean.turn_off
alias: NFC-playbox Volume down
mode: restart
icon: mdi:spotify
description: ''

View File

@ -1 +0,0 @@
{}

View File

@ -1 +0,0 @@
{"mqtt":{"name":"zwave-js-ui","host":"mqtt","port":1883,"qos":1,"prefix":"zwave","reconnectPeriod":3000,"retain":true,"clean":true,"auth":true,"username":"simon","password":"bajsa123","_ca":"","ca":"","_cert":"","cert":"","_key":"","key":""},"gateway":{"type":0,"plugins":[],"authEnabled":false,"payloadType":0,"nodeNames":true,"hassDiscovery":true,"discoveryPrefix":"homeassistant","logEnabled":true,"logLevel":"error","logToFile":false,"values":[],"jobs":[],"disableChangelog":false,"notifyNewVersions":false,"retainedDiscovery":true,"includeNodeInfo":true,"versions":{"app":"9.33.1","driver":"14.3.12","server":"1.40.3"}},"zwave":{"enabled":true,"port":"/dev/zwave","allowBootloaderOnly":false,"commandsTimeout":30,"logLevel":"debug","rf":{"txPower":{},"region":0},"securityKeys":{"S0_Legacy":"6DF43E869CE71A15B0AF1D7896766D35","S2_AccessControl":"9804893D142536A33941225F4337A9E9","S2_Unauthenticated":"7BDA36CC5F29E284F775CED69658F1D5","S2_Authenticated":"2F5AE4900CD7C23C32CA8D15EEAA66AB"},"securityKeysLongRange":{},"deviceConfigPriorityDir":"/usr/src/app/store/config","logEnabled":false,"logToFile":false,"maxFiles":7,"serverEnabled":false,"serverServiceDiscoveryDisabled":false,"enableSoftReset":true,"enableStatistics":false,"serverPort":3000,"maxNodeEventsQueueSize":100,"higherReportsTimeout":false,"disableControllerRecovery":false,"disableWatchdog":false,"disclaimerVersion":1},"backup":{"storeBackup":false,"storeCron":"0 0 * * *","storeKeep":7,"nvmBackup":false,"nvmBackupOnEvent":false,"nvmCron":"0 0 * * *","nvmKeep":7},"zniffer":{"enabled":false,"port":"","logEnabled":true,"logToFile":true,"maxFiles":7,"securityKeys":{"S2_Unauthenticated":"","S2_Authenticated":"","S2_AccessControl":"","S0_Legacy":""},"securityKeysLongRange":{"S2_Authenticated":"","S2_AccessControl":""},"convertRSSI":false},"ui":{"darkMode":false,"navTabs":false,"compactMode":false,"streamerMode":false}}

View File

@ -1 +0,0 @@
[{"username":"admin","passwordHash":"df1ffe80e145cdf4:b9e829c2b1d80b67c1a07997b9b4bd444ec868161bc5a0e29d91a413d280032233c34814cb8a394f861749d8fdbb1115d1eb5105bcf8ae6f7719a9e51b326bd8"}]

View File

View File

@ -1,31 +0,0 @@
version: "3"
services:
nextcloud:
image: linuxserver/nextcloud
container_name: nextcloud
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Stockholm
volumes:
- </path/to/appdata>:/config
- <path/to/data>:/data
ports:
- 7999:443
restart: unless-stopped
volumes:
- ${DIR}/nextcloud/data:/data
- ${DIR}/nextcloud/config:/config
labels:
- "traefik.enable=true"
- "traefik.http.services.nextcloud-service.loadbalancer.server.port=3000"
- "traefik.http.routers.nextcloud-secure.entrypoints=web-secure"
- "traefik.http.routers.nextcloud-secure.rule=Host(`nextcloud.${DOMAIN}`)"
- "traefik.http.routers.nextcloud-secure.tls.certresolver=milvert"
networks:
frontend:
external: true
backend:
external: false

View File

@ -1,281 +0,0 @@
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
// The `https` setting requires the `fs` module. Uncomment the following
// to make it available:
//var fs = require("fs");
module.exports = {
// the tcp port that the Node-RED web server is listening on
uiPort: process.env.PORT || 1880,
// By default, the Node-RED UI accepts connections on all IPv4 interfaces.
// To listen on all IPv6 addresses, set uiHost to "::",
// The following property can be used to listen on a specific interface. For
// example, the following would only allow connections from the local machine.
//uiHost: "127.0.0.1",
// Retry time in milliseconds for MQTT connections
mqttReconnectTime: 15000,
// Retry time in milliseconds for Serial port connections
serialReconnectTime: 15000,
// Retry time in milliseconds for TCP socket connections
//socketReconnectTime: 10000,
// Timeout in milliseconds for TCP server socket connections
// defaults to no timeout
//socketTimeout: 120000,
// Maximum number of messages to wait in queue while attempting to connect to TCP socket
// defaults to 1000
//tcpMsgQueueSize: 2000,
// Timeout in milliseconds for HTTP request connections
// defaults to 120 seconds
//httpRequestTimeout: 120000,
// The maximum length, in characters, of any message sent to the debug sidebar tab
debugMaxLength: 1000,
// The maximum number of messages nodes will buffer internally as part of their
// operation. This applies across a range of nodes that operate on message sequences.
// defaults to no limit. A value of 0 also means no limit is applied.
//nodeMessageBufferMaxLength: 0,
// To disable the option for using local files for storing keys and certificates in the TLS configuration
// node, set this to true
//tlsConfigDisableLocalFiles: true,
// Colourise the console output of the debug node
//debugUseColors: true,
// The file containing the flows. If not set, it defaults to flows_<hostname>.json
//flowFile: 'flows.json',
// To enabled pretty-printing of the flow within the flow file, set the following
// property to true:
//flowFilePretty: true,
// By default, credentials are encrypted in storage using a generated key. To
// specify your own secret, set the following property.
// If you want to disable encryption of credentials, set this property to false.
// Note: once you set this property, do not change it - doing so will prevent
// node-red from being able to decrypt your existing credentials and they will be
// lost.
credentialSecret: "min_långa_secret_som_är_säker",
// By default, all user data is stored in a directory called `.node-red` under
// the user's home directory. To use a different location, the following
// property can be used
//userDir: '/home/nol/.node-red/',
// Node-RED scans the `nodes` directory in the userDir to find local node files.
// The following property can be used to specify an additional directory to scan.
//nodesDir: '/home/nol/.node-red/nodes',
// By default, the Node-RED UI is available at http://localhost:1880/
// The following property can be used to specify a different root path.
// If set to false, this is disabled.
//httpAdminRoot: '/admin',
// Some nodes, such as HTTP In, can be used to listen for incoming http requests.
// By default, these are served relative to '/'. The following property
// can be used to specifiy a different root path. If set to false, this is
// disabled.
//httpNodeRoot: '/red-nodes',
// The following property can be used in place of 'httpAdminRoot' and 'httpNodeRoot',
// to apply the same root to both parts.
//httpRoot: '/red',
// When httpAdminRoot is used to move the UI to a different root path, the
// following property can be used to identify a directory of static content
// that should be served at http://localhost:1880/.
//httpStatic: '/home/nol/node-red-static/',
// The maximum size of HTTP request that will be accepted by the runtime api.
// Default: 5mb
//apiMaxLength: '5mb',
// If you installed the optional node-red-dashboard you can set it's path
// relative to httpRoot
//ui: { path: "ui" },
// Securing Node-RED
// -----------------
// To password protect the Node-RED editor and admin API, the following
// property can be used. See http://nodered.org/docs/security.html for details.
//adminAuth: {
// type: "credentials",
// users: [{
// username: "admin",
// password: "$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN.",
// permissions: "*"
// }]
//},
adminAuth: false,
// To password protect the node-defined HTTP endpoints (httpNodeRoot), or
// the static content (httpStatic), the following properties can be used.
// The pass field is a bcrypt hash of the password.
// See http://nodered.org/docs/security.html#generating-the-password-hash
//httpNodeAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
//httpStaticAuth: {user:"user",pass:"$2a$08$zZWtXTja0fB1pzD4sHCMyOCMYz2Z6dNbM6tl8sJogENOMcxWV9DN."},
// The following property can be used to enable HTTPS
// See http://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
// for details on its contents.
// See the comment at the top of this file on how to load the `fs` module used by
// this setting.
//
//https: {
// key: fs.readFileSync('privatekey.pem'),
// cert: fs.readFileSync('certificate.pem')
//},
// The following property can be used to cause insecure HTTP connections to
// be redirected to HTTPS.
//requireHttps: true,
// The following property can be used to disable the editor. The admin API
// is not affected by this option. To disable both the editor and the admin
// API, use either the httpRoot or httpAdminRoot properties
//disableEditor: false,
// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
//httpNodeCors: {
// origin: "*",
// methods: "GET,PUT,POST,DELETE"
//},
// If you need to set an http proxy please set an environment variable
// called http_proxy (or HTTP_PROXY) outside of Node-RED in the operating system.
// For example - http_proxy=http://myproxy.com:8080
// (Setting it here will have no effect)
// You may also specify no_proxy (or NO_PROXY) to supply a comma separated
// list of domains to not proxy, eg - no_proxy=.acme.co,.acme.co.uk
// The following property can be used to add a custom middleware function
// in front of all http in nodes. This allows custom authentication to be
// applied to all http in nodes, or any other sort of common request processing.
//httpNodeMiddleware: function(req,res,next) {
// // Handle/reject the request, or pass it on to the http in node by calling next();
// // Optionally skip our rawBodyParser by setting this to true;
// //req.skipRawBodyParser = true;
// next();
//},
// The following property can be used to pass custom options to the Express.js
// server used by Node-RED. For a full list of available options, refer
// to http://expressjs.com/en/api.html#app.settings.table
//httpServerOptions: { },
// The following property can be used to verify websocket connection attempts.
// This allows, for example, the HTTP request headers to be checked to ensure
// they include valid authentication information.
//webSocketNodeVerifyClient: function(info) {
// // 'info' has three properties:
// // - origin : the value in the Origin header
// // - req : the HTTP request
// // - secure : true if req.connection.authorized or req.connection.encrypted is set
// //
// // The function should return true if the connection should be accepted, false otherwise.
// //
// // Alternatively, if this function is defined to accept a second argument, callback,
// // it can be used to verify the client asynchronously.
// // The callback takes three arguments:
// // - result : boolean, whether to accept the connection or not
// // - code : if result is false, the HTTP error status to return
// // - reason: if result is false, the HTTP reason string to return
//},
// The following property can be used to seed Global Context with predefined
// values. This allows extra node modules to be made available with the
// Function node.
// For example,
// functionGlobalContext: { os:require('os') }
// can be accessed in a function block as:
// global.get("os")
functionGlobalContext: {
// os:require('os'),
// jfive:require("johnny-five"),
// j5board:require("johnny-five").Board({repl:false})
},
// `global.keys()` returns a list of all properties set in global context.
// This allows them to be displayed in the Context Sidebar within the editor.
// In some circumstances it is not desirable to expose them to the editor. The
// following property can be used to hide any property set in `functionGlobalContext`
// from being list by `global.keys()`.
// By default, the property is set to false to avoid accidental exposure of
// their values. Setting this to true will cause the keys to be listed.
exportGlobalContextKeys: false,
// Context Storage
// The following property can be used to enable context storage. The configuration
// provided here will enable file-based context that flushes to disk every 30 seconds.
// Refer to the documentation for further options: https://nodered.org/docs/api/context/
//
//contextStorage: {
// default: {
// module:"localfilesystem"
// },
//},
// The following property can be used to order the categories in the editor
// palette. If a node's category is not in the list, the category will get
// added to the end of the palette.
// If not set, the following default order is used:
//paletteCategories: ['subflows','flow','input','output','function','parser','social','mobile','storage','analysis','advanced'],
// Configure the logging output
logging: {
// Only console logging is currently supported
console: {
// Level of logging to be recorded. Options are:
// fatal - only those errors which make the application unusable should be recorded
// error - record errors which are deemed fatal for a particular request + fatal errors
// warn - record problems which are non fatal + errors + fatal errors
// info - record information about the general running of the application + warn + error + fatal errors
// debug - record information which is more verbose than info + info + warn + error + fatal errors
// trace - record very detailed logging + debug + info + warn + error + fatal errors
// off - turn off all logging (doesn't affect metrics or audit)
level: "info",
// Whether or not to include metric events in the log output
metrics: false,
// Whether or not to include audit events in the log output
audit: false
}
},
// Customising the editor
editorTheme: {
projects: {
// To enable the Projects feature, set this value to true
enabled: false
},
tours: false,
codeEditor: {
lib: "monaco"
}
}
}

View File

@ -1 +0,0 @@
rtorrent_sess

View File

@ -14,20 +14,19 @@ providers:
log:
level: info
filePath: "/log/info.log"
format: json
# filePath: "/log/info.log"
#format: json
accessLog:
filePath: "/log/access.log"
bufferingSize: 100
format: json
filters:
statusCodes:
- "200"
- "300-302"
- "500"
retryAttempts: true
minDuration: "10ms"
#filters:
#statusCodes:
#- "200"
#- "300-302"
#retryAttempts: true
#minDuration: "10ms"
#metrics:
#influxDB:

View File

@ -62,7 +62,7 @@ http:
landet-service:
loadBalancer:
servers:
- url: "http://10.0.10.5:8123"
- url: "http://10.0.10.3:8123"
lampa-service:
loadBalancer:
servers: