Add luz-sala remote control from local Home Assistant

Installs ha-bridge.py on vini@192.168.1.105 as a systemd user service
that proxies light commands to the remote HA via JWT authentication.
Local HA gets rest_command, rest sensor, template switch, and a
button-card for both dashboards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ltadeu6 2026-05-17 16:28:32 -03:00
parent f85cf6b2df
commit 82e6ed9271
No known key found for this signature in database
GPG key ID: FB9FDAB6B6F3418D
3 changed files with 202 additions and 0 deletions

View file

@ -4,6 +4,81 @@ views:
title: Home
type: masonry
cards:
- type: custom:button-card
entity: switch.luz_sala
triggers_update:
- sensor.luz_sala_remota
icon: mdi:lightbulb
name: Luz Sala
show_icon: true
show_name: true
show_state: false
show_label: false
tap_action:
action: call-service
service: switch.toggle
service_data:
entity_id: switch.luz_sala
hold_action:
action: none
custom_fields:
status: >
[[[
const raw = states['sensor.luz_sala_remota']?.state;
if (raw === 'on') return 'Ligada';
if (raw === 'off') return 'Desligada';
return raw || 'Indisponível';
]]]
styles:
card:
- padding: 18px
- border-radius: 22px
- background: |
[[[
const s = states['sensor.luz_sala_remota']?.state;
return s === 'on'
? 'linear-gradient(135deg, rgba(255,215,0,0.22), rgba(255,184,108,0.10))'
: 'var(--ha-card-background, var(--card-background-color, #1c1c1c))';
]]]
- box-shadow: none
grid:
- grid-template-areas: '"i n" "i status"'
- grid-template-columns: min-content 1fr
- grid-template-rows: min-content min-content
- column-gap: 12px
- row-gap: 4px
img_cell:
- justify-self: start
- align-self: center
- width: 42px
- height: 42px
- border-radius: 16px
- background: rgba(255,255,255,0.10)
icon:
- color: |
[[[
const s = states['sensor.luz_sala_remota']?.state;
return s === 'on' ? '#ffd700' : 'rgba(255,255,255,0.4)';
]]]
- width: 24px
- height: 24px
name:
- justify-self: start
- align-self: end
- color: white
- font-size: 22px
- font-weight: 700
custom_fields:
status:
- justify-self: start
- color: |
[[[
const s = states['sensor.luz_sala_remota']?.state;
return s === 'on' ? '#ffd700' : 'rgba(248,250,252,0.82)';
]]]
- font-size: 15px
- font-weight: 600
- type: weather-forecast
entity: weather.forecast_casa
show_forecast: true

View file

@ -4,6 +4,81 @@ views:
title: Visão Geral
type: masonry
cards:
- type: custom:button-card
entity: switch.luz_sala
triggers_update:
- sensor.luz_sala_remota
icon: mdi:lightbulb
name: Luz Sala
show_icon: true
show_name: true
show_state: false
show_label: false
tap_action:
action: call-service
service: switch.toggle
service_data:
entity_id: switch.luz_sala
hold_action:
action: none
custom_fields:
status: >
[[[
const raw = states['sensor.luz_sala_remota']?.state;
if (raw === 'on') return 'Ligada';
if (raw === 'off') return 'Desligada';
return raw || 'Indisponível';
]]]
styles:
card:
- padding: 18px
- border-radius: 22px
- background: |
[[[
const s = states['sensor.luz_sala_remota']?.state;
return s === 'on'
? 'linear-gradient(135deg, rgba(255,215,0,0.22), rgba(255,184,108,0.10))'
: 'var(--ha-card-background, var(--card-background-color, #1c1c1c))';
]]]
- box-shadow: none
grid:
- grid-template-areas: '"i n" "i status"'
- grid-template-columns: min-content 1fr
- grid-template-rows: min-content min-content
- column-gap: 12px
- row-gap: 4px
img_cell:
- justify-self: start
- align-self: center
- width: 42px
- height: 42px
- border-radius: 16px
- background: rgba(255,255,255,0.10)
icon:
- color: |
[[[
const s = states['sensor.luz_sala_remota']?.state;
return s === 'on' ? '#ffd700' : 'rgba(255,255,255,0.4)';
]]]
- width: 24px
- height: 24px
name:
- justify-self: start
- align-self: end
- color: white
- font-size: 22px
- font-weight: 700
custom_fields:
status:
- justify-self: start
- color: |
[[[
const s = states['sensor.luz_sala_remota']?.state;
return s === 'on' ? '#ffd700' : 'rgba(248,250,252,0.82)';
]]]
- font-size: 15px
- font-weight: 600
- type: weather-forecast
entity: weather.forecast_casa
show_forecast: true

View file

@ -9,6 +9,8 @@ let
repoDir = "${homeDir}/Projetos/Sistemas/nixos-config";
codexStatusPath = "/var/lib/hass/codex_status.json";
claudeUsagePath = "/var/lib/hass/claude_usage.json";
luzSalaBridgeUrl = "http://192.168.1.105:8766";
luzSalaBridgeSecret = "a3c41709c9da4ea77059eb734570726950b9a70cb7af6a3bf0ece94d54d0c8c0";
haAirConditioner = "climate.ar";
haLaundryDryingToggle = "input_boolean.secar_roupas";
haClimateAction = action: data: {
@ -648,6 +650,56 @@ in {
}
];
}
{
switch = [
{
name = "Luz Sala";
unique_id = "luz_sala_remota_switch";
state = "{{ states('sensor.luz_sala_remota') == 'on' }}";
turn_on.action = "rest_command.luz_sala_turn_on";
turn_off.action = "rest_command.luz_sala_turn_off";
icon = "mdi:lightbulb";
}
];
}
];
rest_command = {
luz_sala_turn_on = {
url = "${luzSalaBridgeUrl}/turn_on";
method = "post";
headers = { X-Secret = luzSalaBridgeSecret; };
content_type = "application/json";
payload = "{}";
};
luz_sala_turn_off = {
url = "${luzSalaBridgeUrl}/turn_off";
method = "post";
headers = { X-Secret = luzSalaBridgeSecret; };
content_type = "application/json";
payload = "{}";
};
luz_sala_toggle = {
url = "${luzSalaBridgeUrl}/toggle";
method = "post";
headers = { X-Secret = luzSalaBridgeSecret; };
content_type = "application/json";
payload = "{}";
};
};
rest = [
{
resource = "${luzSalaBridgeUrl}/state";
headers = { X-Secret = luzSalaBridgeSecret; };
scan_interval = 10;
sensor = [{
name = "Luz Sala Remota";
unique_id = "luz_sala_remota";
value_template = "{{ value_json.state }}";
icon = "mdi:lightbulb";
}];
}
];
lovelace = {