Initial Commit
@@ -0,0 +1 @@
|
||||
2026.6.2
|
||||
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,13 @@
|
||||
# Home Assistant Core Exclusions
|
||||
*.db
|
||||
*.db-shm
|
||||
*.db-wal
|
||||
*.log
|
||||
.storage/
|
||||
secrets.yaml
|
||||
*icon*.png
|
||||
|
||||
|
||||
# Custom integrations and private tokens
|
||||
.google_nest_prompt_info.json
|
||||
nest_protect_cookies.json
|
||||
@@ -0,0 +1 @@
|
||||
{"pid": 72, "version": 1, "ha_version": "2026.6.2", "start_ts": 1781098592.353074}
|
||||
@@ -0,0 +1,373 @@
|
||||
- id: '1780072464609'
|
||||
alias: 'Camera: Send Motion Notifications'
|
||||
description: Sends a push notification to your primary mobile device when Nest cameras
|
||||
detect activity.
|
||||
triggers:
|
||||
- entity_id:
|
||||
- camera.entryway_camera
|
||||
- camera.front_door
|
||||
- camera.hallway_camera
|
||||
- camera.living_room_camera
|
||||
trigger: state
|
||||
conditions: []
|
||||
actions:
|
||||
- action: notify.notify
|
||||
data:
|
||||
title: Motion Detected!
|
||||
message: Activity detected on one of your Nest security cameras.
|
||||
mode: parallel
|
||||
max: 10
|
||||
- id: '1780125759253'
|
||||
alias: 'Tablet: Dim Screen at Night'
|
||||
description: Drops tablet brightness to zero at night
|
||||
triggers:
|
||||
- at: 01:00:00
|
||||
trigger: time
|
||||
actions:
|
||||
- action: notify.mobile_app_sm_t387w
|
||||
data:
|
||||
message: command_screen_brightness_level
|
||||
data:
|
||||
command: 0
|
||||
- id: '1780125803824'
|
||||
alias: 'Tablet: Restore Screen in Morning'
|
||||
description: Restores tablet brightness to normal in the morning
|
||||
triggers:
|
||||
- at: 07:00:00
|
||||
trigger: time
|
||||
actions:
|
||||
- action: notify.mobile_app_sm_t387w
|
||||
data:
|
||||
message: command_screen_brightness_level
|
||||
data:
|
||||
command: 180
|
||||
- id: '1780343863793'
|
||||
alias: Front Door Notification
|
||||
description: ''
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id:
|
||||
- binary_sensor.front_door
|
||||
from:
|
||||
- 'off'
|
||||
to:
|
||||
- 'on'
|
||||
- trigger: state
|
||||
entity_id:
|
||||
- binary_sensor.patio_door
|
||||
from:
|
||||
- 'off'
|
||||
to:
|
||||
- 'on'
|
||||
conditions: []
|
||||
actions:
|
||||
- target:
|
||||
entity_id:
|
||||
- light.kitchen_home_kitchen
|
||||
action: light.toggle
|
||||
- delay: 00:00:15
|
||||
- target:
|
||||
entity_id:
|
||||
- light.kitchen_home_kitchen
|
||||
action: light.toggle
|
||||
- data:
|
||||
message: There is someone at the front door
|
||||
action: notify.notify
|
||||
mode: single
|
||||
variables:
|
||||
_cafe_metadata:
|
||||
version: 1
|
||||
strategy: native
|
||||
nodes:
|
||||
trigger_1780343037167_0:
|
||||
x: -615
|
||||
y: -705
|
||||
action_1780343442574_1:
|
||||
x: -360
|
||||
y: -630
|
||||
delay_1780343604675_2:
|
||||
x: -120
|
||||
y: -360
|
||||
action_1780343739141_3:
|
||||
x: 75
|
||||
y: -615
|
||||
action_1780343804458_4:
|
||||
x: 330
|
||||
y: -615
|
||||
trigger_1780343965767_5:
|
||||
x: -615
|
||||
y: -555
|
||||
graph_id: 7ad98446-4ce0-4b88-a400-430ac474a617
|
||||
graph_version: 1
|
||||
- id: '1780441470361'
|
||||
alias: Reload Hilo Integrations on Reboot
|
||||
description: Reloads problematic integrations 2 minutes after Home Assistant starts
|
||||
up.
|
||||
triggers:
|
||||
- trigger: homeassistant
|
||||
event: start
|
||||
conditions: []
|
||||
actions:
|
||||
- delay:
|
||||
hours: 0
|
||||
minutes: 3
|
||||
seconds: 0
|
||||
milliseconds: 0
|
||||
- action: homeassistant.reload_config_entry
|
||||
metadata: {}
|
||||
target:
|
||||
device_id:
|
||||
- 3e67afd88a4b4d17552c8f370aaf40b5
|
||||
- baad176ac2f415f3642e2d075bb6a977
|
||||
data: {}
|
||||
mode: single
|
||||
- id: '1780509027967'
|
||||
alias: Notify When Ring Console Battery Low
|
||||
description: ''
|
||||
triggers:
|
||||
- trigger: numeric_state
|
||||
entity_id:
|
||||
- sensor.entryway_keypad_battery
|
||||
below: 25
|
||||
conditions: []
|
||||
actions:
|
||||
- data:
|
||||
message: Keypad Battery Low. Please Charge ASAP
|
||||
title: Ring Console Battery
|
||||
action: notify.notify
|
||||
mode: single
|
||||
variables:
|
||||
_cafe_metadata:
|
||||
version: 1
|
||||
strategy: native
|
||||
nodes:
|
||||
trigger_1780508927611_4:
|
||||
x: 15
|
||||
y: -105
|
||||
action_1780508992783_5:
|
||||
x: 285
|
||||
y: 45
|
||||
graph_id: 816af3b7-3eac-47c3-8da3-8797d1774c0c
|
||||
graph_version: 1
|
||||
- id: '1780516946807'
|
||||
alias: Notify When Front Door Sensor Battery Low
|
||||
description: ''
|
||||
triggers:
|
||||
- trigger: numeric_state
|
||||
entity_id:
|
||||
- sensor.front_door_battery
|
||||
below: 25
|
||||
conditions: []
|
||||
actions:
|
||||
- data:
|
||||
message: Front Door Sensor Battery Low. Please Change Batteries ASAP.
|
||||
title: Ring Console Battery
|
||||
action: notify.notify
|
||||
mode: single
|
||||
variables:
|
||||
_cafe_metadata:
|
||||
version: 1
|
||||
strategy: native
|
||||
nodes:
|
||||
trigger_1780508927611_4:
|
||||
x: 15
|
||||
y: -105
|
||||
action_1780508992783_5:
|
||||
x: 285
|
||||
y: 45
|
||||
graph_id: 816af3b7-3eac-47c3-8da3-8797d1774c0c
|
||||
graph_version: 1
|
||||
- id: '1780813227139'
|
||||
alias: 'Alert: Fridge or Freezer Power Outage'
|
||||
description: Triggers an alert if the fridge or freezer smart plug power consumption
|
||||
drops to 0W for too long.
|
||||
triggers:
|
||||
- trigger: numeric_state
|
||||
entity_id:
|
||||
- sensor.freezer_power
|
||||
for:
|
||||
hours: 0
|
||||
minutes: 45
|
||||
seconds: 0
|
||||
below: 1
|
||||
id: freezer_down
|
||||
- trigger: numeric_state
|
||||
entity_id:
|
||||
- sensor.fridge_power
|
||||
for:
|
||||
hours: 0
|
||||
minutes: 20
|
||||
seconds: 0
|
||||
below: 1
|
||||
id: fridge_down
|
||||
conditions: []
|
||||
actions:
|
||||
- if:
|
||||
- condition: trigger
|
||||
id: freezer_down
|
||||
then:
|
||||
- data:
|
||||
title: "\U0001F6A8 URGENT: Freezer Power Failure"
|
||||
message: The Freezer smart plug has drawn 0W of power for over 40 minutes!
|
||||
Check the physical appliance immediately.
|
||||
action: notify.notify
|
||||
else:
|
||||
- if:
|
||||
- condition: trigger
|
||||
id: fridge_down
|
||||
then:
|
||||
- data:
|
||||
title: "\U0001F6A8 URGENT: Fridge Power Failure"
|
||||
message: The Fridge smart plug has drawn 0W of power for over 20 minutes!
|
||||
Check the physical appliance immediately.
|
||||
action: notify.notify
|
||||
else: []
|
||||
mode: single
|
||||
variables:
|
||||
_cafe_metadata:
|
||||
version: 1
|
||||
strategy: native
|
||||
nodes:
|
||||
trigger_1780846348490_0_0:
|
||||
x: 12
|
||||
y: 182
|
||||
trigger_1780846348490_1_1:
|
||||
x: 12
|
||||
y: 22
|
||||
condition_1780846348491_2_2:
|
||||
x: 312
|
||||
y: 92
|
||||
action_1780846348491_3_3:
|
||||
x: 632
|
||||
y: 12
|
||||
condition_1780846348491_4_4:
|
||||
x: 632
|
||||
y: 172
|
||||
action_1780846348491_5_5:
|
||||
x: 952
|
||||
y: 102
|
||||
graph_id: 5948b900-b45d-4c2e-ae73-c880acc3a1bf
|
||||
graph_version: 1
|
||||
- id: '1780989340205'
|
||||
alias: 'Kitchen: Coffee Maker Active Notification'
|
||||
description: Sends a mobile application push notification when the coffee maker
|
||||
power exceeds 1000W for 5 seconds.
|
||||
triggers:
|
||||
- entity_id: sensor.coffee_maker_power
|
||||
above: 1000
|
||||
for:
|
||||
hours: 0
|
||||
minutes: 0
|
||||
seconds: 5
|
||||
trigger: numeric_state
|
||||
conditions: []
|
||||
actions:
|
||||
- data:
|
||||
title: ☕ Coffee Time
|
||||
message: Someone is Making Coffee
|
||||
action: notify.notify
|
||||
- action: notify.persistent_notification
|
||||
metadata: {}
|
||||
data:
|
||||
title: ☕ Coffee Time
|
||||
message: Someone is Making Coffee
|
||||
- delay:
|
||||
hours: 0
|
||||
minutes: 4
|
||||
seconds: 0
|
||||
milliseconds: 0
|
||||
mode: single
|
||||
- id: '1781024962776'
|
||||
alias: 'Office: Turn On Lights on Motion then Door Open'
|
||||
description: Triggers when office door opens, but only if living room motion happened
|
||||
in the last 30 seconds and light is off.
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: binary_sensor.office_door_contact
|
||||
to: 'on'
|
||||
conditions:
|
||||
- condition: time
|
||||
after: '10:00:00'
|
||||
before: '21:00:00'
|
||||
- condition: state
|
||||
entity_id: light.playroom_light
|
||||
state: 'off'
|
||||
- condition: template
|
||||
value_template: '{{ (now() - states.binary_sensor.basement.last_changed).total_seconds()
|
||||
< 30 }}'
|
||||
actions:
|
||||
- action: light.turn_on
|
||||
target:
|
||||
entity_id: light.playroom_light
|
||||
data: {}
|
||||
mode: single
|
||||
- id: '1781034724187'
|
||||
alias: 'Office: Turn Off Lights on Exit'
|
||||
description: Turns off office lights 2 minutes after the door closes, but only if living
|
||||
room motion was detected after the door shut.
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: binary_sensor.office_door_contact
|
||||
to: 'off'
|
||||
for:
|
||||
minutes: 2
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: light.playroom_light
|
||||
state: 'on'
|
||||
- condition: template
|
||||
value_template: '{{ states.binary_sensor.basement.last_changed > states.binary_sensor.office_door_contact.last_changed
|
||||
}}'
|
||||
actions:
|
||||
- action: light.turn_off
|
||||
target:
|
||||
entity_id: light.playroom_light
|
||||
data: {}
|
||||
mode: single
|
||||
- id: '1781102033733'
|
||||
alias: Water Leak Detected
|
||||
description: ''
|
||||
triggers:
|
||||
- type: moist
|
||||
device_id: 59bc102f385d7a3524c8f21a5c53592b
|
||||
entity_id: c268ff8842e905515de2274d09c5ab9e
|
||||
domain: binary_sensor
|
||||
metadata:
|
||||
secondary: false
|
||||
trigger: device
|
||||
conditions: []
|
||||
actions:
|
||||
- action: notify.notify
|
||||
metadata: {}
|
||||
data:
|
||||
title: "\U0001F6A8 URGENT: Water Leak Detected"
|
||||
message: Water Leak Detected in Basement. Check Water Heater for Leaks.
|
||||
- action: persistent_notification.create
|
||||
metadata: {}
|
||||
data:
|
||||
title: "\U0001F6A8 URGENT: Water Leak Detected"
|
||||
message: Water Leak Detected in Basement. Check Water Heater for Leaks.
|
||||
mode: single
|
||||
- id: '1781112110968'
|
||||
alias: 'Freezer Safety: Alert if Plug Turns Off'
|
||||
description: Triggers an immediate notification if the freezer smart plug is turned
|
||||
off.
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: switch.freezer
|
||||
to: 'off'
|
||||
for:
|
||||
minutes: 1
|
||||
actions:
|
||||
- action: notify.notify
|
||||
data:
|
||||
title: "\U0001F6A8 FREEZER PLUG TRIPPED!"
|
||||
message: The freezer smart plug turned off. Check it immediately to prevent
|
||||
food spoilage.
|
||||
- action: notify.persistent_notification
|
||||
metadata: {}
|
||||
data:
|
||||
title: "\U0001F6A8 FREEZER PLUG TRIPPED!"
|
||||
message: The freezer smart plug turned off. Check it immediately to prevent
|
||||
food spoilage.
|
||||
mode: single
|
||||
@@ -0,0 +1,58 @@
|
||||
blueprint:
|
||||
name: Motion-activated Light
|
||||
description: Turn on a light when motion is detected.
|
||||
domain: automation
|
||||
source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/motion_light.yaml
|
||||
author: Home Assistant
|
||||
input:
|
||||
motion_entity:
|
||||
name: Motion Sensor
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- device_class: occupancy
|
||||
domain: binary_sensor
|
||||
- device_class: motion
|
||||
domain: binary_sensor
|
||||
light_target:
|
||||
name: Light
|
||||
selector:
|
||||
target:
|
||||
entity:
|
||||
domain: light
|
||||
no_motion_wait:
|
||||
name: Wait time
|
||||
description: Time to leave the light on after last motion is detected.
|
||||
default: 120
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 3600
|
||||
unit_of_measurement: seconds
|
||||
|
||||
# If motion is detected within the delay,
|
||||
# we restart the script.
|
||||
mode: restart
|
||||
max_exceeded: silent
|
||||
|
||||
triggers:
|
||||
trigger: state
|
||||
entity_id: !input motion_entity
|
||||
from: "off"
|
||||
to: "on"
|
||||
|
||||
actions:
|
||||
- alias: "Turn on the light"
|
||||
action: light.turn_on
|
||||
target: !input light_target
|
||||
- alias: "Wait until there is no motion from device"
|
||||
wait_for_trigger:
|
||||
trigger: state
|
||||
entity_id: !input motion_entity
|
||||
from: "on"
|
||||
to: "off"
|
||||
- alias: "Wait the number of seconds that has been set"
|
||||
delay: !input no_motion_wait
|
||||
- alias: "Turn off the light"
|
||||
action: light.turn_off
|
||||
target: !input light_target
|
||||
@@ -0,0 +1,50 @@
|
||||
blueprint:
|
||||
name: Zone Notification
|
||||
description: Send a notification to a device when a person leaves a specific zone.
|
||||
domain: automation
|
||||
source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/notify_leaving_zone.yaml
|
||||
author: Home Assistant
|
||||
input:
|
||||
person_entity:
|
||||
name: Person
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
domain: person
|
||||
zone_entity:
|
||||
name: Zone
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
domain: zone
|
||||
notify_device:
|
||||
name: Device to notify
|
||||
description: Device needs to run the official Home Assistant app to receive notifications.
|
||||
selector:
|
||||
device:
|
||||
filter:
|
||||
integration: mobile_app
|
||||
|
||||
triggers:
|
||||
trigger: state
|
||||
entity_id: !input person_entity
|
||||
|
||||
variables:
|
||||
zone_entity: !input zone_entity
|
||||
# This is the state of the person when it's in this zone.
|
||||
zone_state: "{{ states[zone_entity].name }}"
|
||||
person_entity: !input person_entity
|
||||
person_name: "{{ states[person_entity].name }}"
|
||||
|
||||
conditions:
|
||||
condition: template
|
||||
# The first case handles leaving the Home zone which has a special state when zoning called 'home'.
|
||||
# The second case handles leaving all other zones.
|
||||
value_template: "{{ zone_entity == 'zone.home' and trigger.from_state.state == 'home' and trigger.to_state.state != 'home' or trigger.from_state.state == zone_state and trigger.to_state.state != zone_state }}"
|
||||
|
||||
actions:
|
||||
- alias: "Notify that a person has left the zone"
|
||||
domain: mobile_app
|
||||
type: notify
|
||||
device_id: !input notify_device
|
||||
message: "{{ person_name }} has left {{ zone_state }}"
|
||||
@@ -0,0 +1,86 @@
|
||||
blueprint:
|
||||
name: Confirmable Notification
|
||||
description: >-
|
||||
A script that sends an actionable notification with a confirmation before
|
||||
running the specified action.
|
||||
domain: script
|
||||
source_url: https://github.com/home-assistant/core/blob/master/homeassistant/components/script/blueprints/confirmable_notification.yaml
|
||||
author: Home Assistant
|
||||
input:
|
||||
notify_device:
|
||||
name: Device to notify
|
||||
description: Device needs to run the official Home Assistant app to receive notifications.
|
||||
selector:
|
||||
device:
|
||||
filter:
|
||||
integration: mobile_app
|
||||
title:
|
||||
name: "Title"
|
||||
description: "The title of the button shown in the notification."
|
||||
default: ""
|
||||
selector:
|
||||
text:
|
||||
message:
|
||||
name: "Message"
|
||||
description: "The message body"
|
||||
selector:
|
||||
text:
|
||||
confirm_text:
|
||||
name: "Confirmation Text"
|
||||
description: "Text to show on the confirmation button"
|
||||
default: "Confirm"
|
||||
selector:
|
||||
text:
|
||||
confirm_action:
|
||||
name: "Confirmation Action"
|
||||
description: "Action to run when notification is confirmed"
|
||||
default: []
|
||||
selector:
|
||||
action:
|
||||
dismiss_text:
|
||||
name: "Dismiss Text"
|
||||
description: "Text to show on the dismiss button"
|
||||
default: "Dismiss"
|
||||
selector:
|
||||
text:
|
||||
dismiss_action:
|
||||
name: "Dismiss Action"
|
||||
description: "Action to run when notification is dismissed"
|
||||
default: []
|
||||
selector:
|
||||
action:
|
||||
|
||||
mode: restart
|
||||
|
||||
sequence:
|
||||
- alias: "Set up variables"
|
||||
variables:
|
||||
action_confirm: "{{ 'CONFIRM_' ~ context.id }}"
|
||||
action_dismiss: "{{ 'DISMISS_' ~ context.id }}"
|
||||
- alias: "Send notification"
|
||||
domain: mobile_app
|
||||
type: notify
|
||||
device_id: !input notify_device
|
||||
title: !input title
|
||||
message: !input message
|
||||
data:
|
||||
actions:
|
||||
- action: "{{ action_confirm }}"
|
||||
title: !input confirm_text
|
||||
- action: "{{ action_dismiss }}"
|
||||
title: !input dismiss_text
|
||||
- alias: "Awaiting response"
|
||||
wait_for_trigger:
|
||||
- trigger: event
|
||||
event_type: mobile_app_notification_action
|
||||
event_data:
|
||||
action: "{{ action_confirm }}"
|
||||
- trigger: event
|
||||
event_type: mobile_app_notification_action
|
||||
event_data:
|
||||
action: "{{ action_dismiss }}"
|
||||
- choose:
|
||||
- conditions: "{{ wait.trigger.event.data.action == action_confirm }}"
|
||||
sequence: !input confirm_action
|
||||
- conditions: "{{ wait.trigger.event.data.action == action_dismiss }}"
|
||||
sequence: !input dismiss_action
|
||||
@@ -0,0 +1,27 @@
|
||||
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') }}"
|
||||
@@ -0,0 +1,153 @@
|
||||
# Loads default set of integrations. Do not remove.
|
||||
default_config:
|
||||
|
||||
# Core Utility Meter Engine (Required for Hilo to generate compatible energy dashboard metrics)
|
||||
utility_meter:
|
||||
|
||||
# Load frontend themes from the themes folder
|
||||
frontend:
|
||||
themes: !include_dir_merge_named themes
|
||||
|
||||
automation: !include automations.yaml
|
||||
script: !include scripts.yaml
|
||||
scene: !include scenes.yaml
|
||||
|
||||
panel_custom:
|
||||
- name: developer-tools
|
||||
sidebar_title: Developer Tools
|
||||
sidebar_icon: mdi:hammer-wrench
|
||||
url_path: developer-tools/yaml
|
||||
embed_iframe: true
|
||||
require_admin: true
|
||||
|
||||
# Combined Template Section
|
||||
template:
|
||||
# Nest Camera Event Trigger
|
||||
- trigger:
|
||||
- platform: event
|
||||
event_type: nest_event
|
||||
event_data:
|
||||
type: camera_motion
|
||||
binary_sensor:
|
||||
- name: "Nest Camera Motion"
|
||||
state: "true"
|
||||
auto_off: 10
|
||||
device_class: motion
|
||||
|
||||
# Time-Pattern Trigger (Forces calculation updates every minute)
|
||||
- trigger:
|
||||
- platform: time_pattern
|
||||
minutes: "/1"
|
||||
sensor:
|
||||
- name: "Hydro Quebec Active Rate"
|
||||
unique_id: hydro_quebec_active_rate
|
||||
unit_of_measurement: "CAD/kWh"
|
||||
state: >
|
||||
{% set daily_consumption = states('sensor.meter00_daily_grid_energy') | float(999) %}
|
||||
{% set low_rate = states('sensor.hilo_rate_low') | float(0.07065) %}
|
||||
{% set medium_rate = states('sensor.hilo_rate_medium') | float(0.11142) %}
|
||||
|
||||
{% if daily_consumption < 40.0 %}
|
||||
{{ low_rate }}
|
||||
{% else %}
|
||||
{{ medium_rate }}
|
||||
{% endif %}
|
||||
|
||||
# AUTOMATIC LOOKUP SENSOR: Dynamically extracts the active living room climate entity ID
|
||||
- name: "HVAC Real-Time Power Draw"
|
||||
unique_id: hvac_real_time_power_draw
|
||||
unit_of_measurement: "kW"
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
state: >
|
||||
{% set hvac = states.climate | selectattr('entity_id', 'search', 'living_room') | map(attribute='entity_id') | first %}
|
||||
{% if hvac %}
|
||||
{% set action = state_attr(hvac, 'hvac_action') | string | lower %}
|
||||
{% if action == 'cooling' %}
|
||||
2.12
|
||||
{% elif action == 'heating' %}
|
||||
{% if is_state_attr(hvac, 'is_aux_heat', true) %}
|
||||
20.5
|
||||
{% else %}
|
||||
2.5
|
||||
{% endif %}
|
||||
{% else %}
|
||||
0
|
||||
{% endif %}
|
||||
{% else %}
|
||||
0
|
||||
{% endif %}
|
||||
|
||||
# ADJUSTED SENSOR: Scaled down from 1.50 to 1.35 to fix Energy Dashboard overlap
|
||||
- name: "Pool Pump Estimated Power Draw"
|
||||
unique_id: pool_pump_estimated_power_draw
|
||||
unit_of_measurement: "kW"
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
state: >
|
||||
{% if is_state('input_boolean.pool_pump_in_use', 'on') %}
|
||||
1.25
|
||||
{% else %}
|
||||
0
|
||||
{% endif %}
|
||||
|
||||
# FIXED SENSOR: Pulls true variable watts from sensor.basement_power and converts to kW
|
||||
- name: "Basement Heater Power Draw"
|
||||
unique_id: basement_heater_power_draw
|
||||
unit_of_measurement: "kW"
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
state: >
|
||||
{% set raw_watts = states('sensor.basement_power') | float(0) %}
|
||||
{{ (raw_watts / 1000) | round(2) }}
|
||||
|
||||
# WATER HEATER SENSOR: Pulls hardware power from Hilo water heater switch and converts W to kW
|
||||
- name: "Water Heater Power Draw"
|
||||
unique_id: water_heater_power_draw
|
||||
unit_of_measurement: "kW"
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
state: >
|
||||
{% set raw_watts = states('sensor.water_heater_power') | float(0) %}
|
||||
{{ (raw_watts / 1000) | round(2) }}
|
||||
|
||||
# HTTP Proxy Configuration
|
||||
http:
|
||||
use_x_forwarded_for: true
|
||||
trusted_proxies:
|
||||
- 192.168.122.1
|
||||
- 192.168.1.130
|
||||
- 192.168.1.125
|
||||
- 192.168.1.135
|
||||
|
||||
# Legacy and Integration Sensor Section
|
||||
sensor:
|
||||
- platform: torque
|
||||
email: torque-car@asuscomm.com
|
||||
name: MyCar
|
||||
|
||||
# RE-ADDED INTEGRATION ENGINE: Converts your pool pump kW into valid long-term energy stats
|
||||
- platform: integration
|
||||
source: sensor.pool_pump_estimated_power_draw
|
||||
name: Pool Pump Total Energy
|
||||
unique_id: pool_pump_total_energy_riemann_sum
|
||||
method: left
|
||||
round: 2
|
||||
|
||||
# NEW INTEGRATION SENSOR: Converts HVAC kW into valid long-term energy stats (kWh)
|
||||
- platform: integration
|
||||
source: sensor.hvac_real_time_power_draw
|
||||
name: HVAC Total Energy
|
||||
unique_id: hvac_total_energy_riemann_sum
|
||||
method: left
|
||||
round: 2
|
||||
|
||||
emulated_hue:
|
||||
host_ip: 192.168.1.140
|
||||
advertise_ip: 192.168.1.140
|
||||
listen_port: 80
|
||||
expose_by_default: false
|
||||
entities:
|
||||
input_boolean.cync_motion_bridge:
|
||||
name: "Cync Motion Bridge"
|
||||
hidden: false
|
||||
@@ -0,0 +1,120 @@
|
||||
"""Support for AsusRouter devices."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceEntry
|
||||
|
||||
from .const import ASUSROUTER, DOMAIN, PLATFORMS, STOP_LISTENER
|
||||
from .router import ARDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
) -> bool:
|
||||
"""Set up AsusRouter platform."""
|
||||
|
||||
_LOGGER.debug("Setting up entry")
|
||||
|
||||
router = ARDevice(hass, config_entry)
|
||||
await router.setup()
|
||||
|
||||
router.async_on_close(config_entry.add_update_listener(update_listener))
|
||||
|
||||
async def async_close_connection(event):
|
||||
"""Close router connection on HA stop."""
|
||||
|
||||
await router.close()
|
||||
|
||||
stop_listener = hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_STOP, async_close_connection
|
||||
)
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = {
|
||||
ASUSROUTER: router,
|
||||
STOP_LISTENER: stop_listener,
|
||||
}
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(
|
||||
config_entry, PLATFORMS
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
) -> bool:
|
||||
"""Unload AsusRouter config entry."""
|
||||
|
||||
_LOGGER.debug("Unloading entry")
|
||||
|
||||
unload = await hass.config_entries.async_unload_platforms(
|
||||
config_entry, PLATFORMS
|
||||
)
|
||||
|
||||
if unload:
|
||||
# Close connection
|
||||
hass.data[DOMAIN][config_entry.entry_id][STOP_LISTENER]()
|
||||
await hass.data[DOMAIN][config_entry.entry_id][ASUSROUTER].close()
|
||||
hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||
|
||||
return unload
|
||||
|
||||
|
||||
async def update_listener(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
) -> None:
|
||||
"""Reload on config entry update."""
|
||||
|
||||
_LOGGER.debug("Update listener activated")
|
||||
|
||||
router = hass.data[DOMAIN][config_entry.entry_id][ASUSROUTER]
|
||||
|
||||
if router.update_options(config_entry.options):
|
||||
await hass.config_entries.async_reload(config_entry.entry_id)
|
||||
|
||||
|
||||
# Example migration function
|
||||
async def async_migrate_entry(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> bool:
|
||||
"""Migrate old entry."""
|
||||
|
||||
_LOGGER.debug("Migrating from version %s", config_entry.version)
|
||||
|
||||
if config_entry.version == 4: # noqa: PLR2004
|
||||
new_options = {**config_entry.options}
|
||||
new_options["interval_network"] = new_options.pop(
|
||||
"interval_network_stat", 30
|
||||
)
|
||||
|
||||
config_entry.version = 5
|
||||
hass.config_entries.async_update_entry(
|
||||
config_entry, options=new_options
|
||||
)
|
||||
|
||||
_LOGGER.debug("Migration to version %s successful", config_entry.version)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_remove_config_entry_device(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry, device_entry: DeviceEntry
|
||||
) -> bool:
|
||||
"""Remove a device."""
|
||||
|
||||
# This would actually work and should not provide any issues
|
||||
|
||||
_LOGGER.debug("Removing device")
|
||||
|
||||
return True
|
||||
@@ -0,0 +1,118 @@
|
||||
"""AsusRouter AiMesh module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.aimesh import AiMeshDevice
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
|
||||
|
||||
class AiMeshNode:
|
||||
"""Representation of an AiMesh node."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
mac: str,
|
||||
) -> None:
|
||||
"""Initialize an AiMesh node."""
|
||||
|
||||
self._mac: str = mac
|
||||
self.native = AiMeshDevice()
|
||||
self.identity: dict[str, Any] = {
|
||||
"mac": None,
|
||||
"ip": None,
|
||||
"alias": None,
|
||||
"model": None,
|
||||
"type": None,
|
||||
"connected": None,
|
||||
}
|
||||
self._extra_state_attributes: dict[str, Any] = {}
|
||||
|
||||
@callback
|
||||
def update(
|
||||
self,
|
||||
node_info: AiMeshDevice | None = None,
|
||||
event_call: Callable[[str, dict[str, Any] | None], None] | None = None,
|
||||
) -> None:
|
||||
"""Update AiMesh device."""
|
||||
|
||||
if node_info:
|
||||
self.native = node_info
|
||||
self._mac = self._extra_state_attributes["mac"] = self.identity[
|
||||
"mac"
|
||||
] = format_mac(node_info.mac)
|
||||
# Online
|
||||
if node_info.status:
|
||||
# State: router / node
|
||||
self._extra_state_attributes["type"] = self.identity[
|
||||
"type"
|
||||
] = node_info.type
|
||||
# IP
|
||||
self._extra_state_attributes["ip"] = self.identity["ip"] = (
|
||||
node_info.ip
|
||||
)
|
||||
# Alias
|
||||
self._extra_state_attributes["alias"] = self.identity[
|
||||
"alias"
|
||||
] = node_info.alias
|
||||
# Model
|
||||
self._extra_state_attributes["model"] = self.identity[
|
||||
"model"
|
||||
] = node_info.model
|
||||
# Product ID
|
||||
self._extra_state_attributes["product_id"] = (
|
||||
node_info.product_id
|
||||
)
|
||||
# Node level
|
||||
self._extra_state_attributes["level"] = node_info.level
|
||||
# Node parent
|
||||
if node_info.parent == {}:
|
||||
self._extra_state_attributes["parent"] = {
|
||||
"connection": "wired",
|
||||
}
|
||||
else:
|
||||
self._extra_state_attributes["parent"] = node_info.parent
|
||||
# Node config
|
||||
# self._extra_state_attributes[CONFIG] = node_info.config
|
||||
# Access point
|
||||
# self._extra_state_attributes[ACCESS_POINT] = node_info.ap
|
||||
# Notify reconnect
|
||||
if self.identity["connected"] is False and callable(
|
||||
event_call
|
||||
):
|
||||
event_call(
|
||||
"node_reconnected",
|
||||
self.identity,
|
||||
)
|
||||
# Connection status
|
||||
self.identity["connected"] = True
|
||||
else:
|
||||
# Notify disconnect
|
||||
if self.identity["connected"] is True and callable(event_call):
|
||||
event_call(
|
||||
"node_disconnected",
|
||||
self.identity,
|
||||
)
|
||||
# Connection status
|
||||
self.identity["connected"] = False
|
||||
elif callable(event_call):
|
||||
# Notify disconnect
|
||||
event_call(
|
||||
"node_disconnected",
|
||||
self.identity,
|
||||
)
|
||||
|
||||
@property
|
||||
def mac(self):
|
||||
"""Return node mac address."""
|
||||
|
||||
return self._mac
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return extra state attributes."""
|
||||
|
||||
return self._extra_state_attributes
|
||||
@@ -0,0 +1,189 @@
|
||||
"""AsusRouter binary sensor module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
BinarySensorEntity,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
from .const import (
|
||||
AIMESH,
|
||||
ASUSROUTER,
|
||||
CONF_DEFAULT_HIDE_PASSWORDS,
|
||||
CONF_HIDE_PASSWORDS,
|
||||
DOMAIN,
|
||||
MANUFACTURER,
|
||||
PASSWORD,
|
||||
STATIC_BINARY_SENSORS,
|
||||
)
|
||||
from .dataclass import ARBinarySensorDescription
|
||||
from .entity import ARBinaryEntity, async_setup_ar_entry
|
||||
from .helpers import to_unique_id
|
||||
from .router import AiMeshNode, ARDevice
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AsusRouter binary sensors."""
|
||||
|
||||
binary_sensors = STATIC_BINARY_SENSORS.copy()
|
||||
|
||||
hide = []
|
||||
if config_entry.options.get(
|
||||
CONF_HIDE_PASSWORDS, CONF_DEFAULT_HIDE_PASSWORDS
|
||||
):
|
||||
hide.append(PASSWORD)
|
||||
|
||||
await async_setup_ar_entry(
|
||||
hass,
|
||||
config_entry,
|
||||
async_add_entities,
|
||||
binary_sensors,
|
||||
ARBinarySensor,
|
||||
hide,
|
||||
)
|
||||
|
||||
router = hass.data[DOMAIN][config_entry.entry_id][ASUSROUTER]
|
||||
tracked: set = set()
|
||||
|
||||
@callback
|
||||
def update_router():
|
||||
"""Update the values of the router."""
|
||||
|
||||
add_entities(router, async_add_entities, tracked)
|
||||
|
||||
router.async_on_close(
|
||||
async_dispatcher_connect(hass, router.signal_aimesh_new, update_router)
|
||||
)
|
||||
|
||||
update_router()
|
||||
|
||||
|
||||
class ARBinarySensor(ARBinaryEntity, BinarySensorEntity):
|
||||
"""AsusRouter binary sensor."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
router: ARDevice,
|
||||
description: ARBinarySensorDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter binary sensor."""
|
||||
|
||||
super().__init__(coordinator, router, description)
|
||||
self.entity_description: ARBinarySensorDescription = description
|
||||
|
||||
|
||||
@callback
|
||||
def add_entities(
|
||||
router: ARDevice,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
tracked: set[str],
|
||||
) -> None:
|
||||
"""Add new tracker entities from the router."""
|
||||
|
||||
new_tracked = []
|
||||
|
||||
for mac, node in router.aimesh.items():
|
||||
if mac in tracked:
|
||||
continue
|
||||
|
||||
new_tracked.append(AMBinarySensor(router, node))
|
||||
tracked.add(mac)
|
||||
|
||||
if new_tracked:
|
||||
async_add_entities(new_tracked)
|
||||
|
||||
|
||||
class AMBinarySensor(BinarySensorEntity):
|
||||
"""AsusRouter AiMesh sensor."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
router: ARDevice,
|
||||
node: AiMeshNode,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter AiMesh sensor."""
|
||||
|
||||
self._router = router
|
||||
self._node = node
|
||||
self._attr_unique_id = to_unique_id(
|
||||
f"{router.mac}_{AIMESH}_{node.mac}"
|
||||
)
|
||||
self._attr_name = f"AiMesh {node.native.model} ({node.native.mac})"
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Get the state."""
|
||||
|
||||
return self._node.native.status
|
||||
|
||||
@property
|
||||
def device_class(self) -> BinarySensorDeviceClass:
|
||||
"""Device class."""
|
||||
|
||||
return BinarySensorDeviceClass.CONNECTIVITY
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return extra state attributes."""
|
||||
|
||||
return dict(sorted(self._node.extra_state_attributes.items())) or {}
|
||||
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
"""Return device info."""
|
||||
|
||||
device_info: DeviceInfo = DeviceInfo(
|
||||
identifiers={
|
||||
(DOMAIN, self._node.mac),
|
||||
},
|
||||
name=self._node.native.model,
|
||||
model=self._node.native.model,
|
||||
manufacturer=MANUFACTURER,
|
||||
sw_version=self._node.native.fw,
|
||||
)
|
||||
if self._router.mac != self._node.mac:
|
||||
device_info = DeviceInfo(
|
||||
identifiers={
|
||||
(DOMAIN, self._node.mac),
|
||||
},
|
||||
name=self._node.native.model,
|
||||
model=self._node.native.model,
|
||||
manufacturer=MANUFACTURER,
|
||||
sw_version=self._node.native.fw,
|
||||
via_device=(DOMAIN, self._router.mac),
|
||||
)
|
||||
|
||||
return device_info
|
||||
|
||||
@callback
|
||||
def async_on_demand_update(self) -> None:
|
||||
"""Update the state."""
|
||||
|
||||
if self._node.mac in self._router.aimesh:
|
||||
self._node = self._router.aimesh[self._node.mac]
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register state update callback."""
|
||||
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
self._router.signal_aimesh_update,
|
||||
self.async_on_demand_update,
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,824 @@
|
||||
"""AsusRouter bridge module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
import dataclasses
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import aiohttp
|
||||
from asusrouter import AsusRouter
|
||||
from asusrouter.config import ARConfig, ARConfigKey as ARConfKey
|
||||
from asusrouter.const import DEFAULT_PORT_HTTP, DEFAULT_PORT_HTTPS
|
||||
from asusrouter.error import AsusRouterError
|
||||
from asusrouter.modules.aimesh import AiMeshDevice
|
||||
from asusrouter.modules.client import AsusClient
|
||||
from asusrouter.modules.data import AsusData
|
||||
from asusrouter.modules.homeassistant import (
|
||||
convert_to_ha_data,
|
||||
convert_to_ha_sensors,
|
||||
convert_to_ha_state_bool,
|
||||
)
|
||||
from asusrouter.modules.identity import AsusDevice
|
||||
from asusrouter.modules.parental_control import ParentalControlRule, PCRuleType
|
||||
from asusrouter.tools.connection import get_cookie_jar
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
CONF_SSL,
|
||||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
from homeassistant.helpers.update_coordinator import UpdateFailed
|
||||
|
||||
from . import helpers
|
||||
from .const import (
|
||||
AURA,
|
||||
BOOTTIME,
|
||||
CONF_CACHE_TIME,
|
||||
CONF_DEFAULT_CACHE_TIME,
|
||||
CONF_DEFAULT_MODE,
|
||||
CONF_DEFAULT_PORT,
|
||||
CONF_MODE,
|
||||
CPU,
|
||||
DDNS,
|
||||
DEFAULT_SENSORS,
|
||||
DOMAIN,
|
||||
DSL,
|
||||
FIRMWARE,
|
||||
GWLAN,
|
||||
LED,
|
||||
LIST,
|
||||
LIST_PORTS,
|
||||
METHOD,
|
||||
MODE_SENSORS,
|
||||
NETWORK,
|
||||
PARENTAL_CONTROL,
|
||||
PORT_FORWARDING,
|
||||
PORTS,
|
||||
RAM,
|
||||
SENSORS,
|
||||
SENSORS_BOOTTIME,
|
||||
SENSORS_FIRMWARE,
|
||||
SENSORS_LED,
|
||||
SENSORS_PARENTAL_CONTROL,
|
||||
SENSORS_PORT_FORWARDING,
|
||||
SENSORS_RAM,
|
||||
STATE,
|
||||
SYSINFO,
|
||||
TEMPERATURE,
|
||||
WLAN,
|
||||
)
|
||||
from .const_v1 import DEFAULT_IDENTITY_BRAND, DEFAULT_IDENTITY_NAME
|
||||
from .modules.aura import aura_to_ha
|
||||
from .modules.firmware import to_ha as firmware_to_ha
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ARBridge:
|
||||
"""Bridge to the AsusRouter library."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
configs: dict[str, Any],
|
||||
options: dict[str, Any] | None = None,
|
||||
) -> None:
|
||||
"""Initialize bridge to the library."""
|
||||
|
||||
self.hass = hass
|
||||
|
||||
# Save all the HA configs and options
|
||||
self._configs = configs.copy()
|
||||
if options:
|
||||
self._configs.update(options)
|
||||
|
||||
# Get session from HA
|
||||
# By default, don't verify SSL <- this is a temp solution
|
||||
# which should be done properly in the future
|
||||
session = async_create_clientsession(
|
||||
hass,
|
||||
verify_ssl=False,
|
||||
cookie_jar=get_cookie_jar(),
|
||||
)
|
||||
|
||||
# Prepare configs
|
||||
config = self._get_api_config()
|
||||
|
||||
# Initialize API
|
||||
self._api = self._get_api(self._configs, session, config)
|
||||
|
||||
# Switch API to robust mode
|
||||
# Robust boottime will avoid 1 second jitter due to the raw data
|
||||
# uncertainty. This can provide up to 1 second overestimation
|
||||
# of the boottime, but will avoid saving extra data when the
|
||||
# integration restarts and loses the previous boottime data.
|
||||
ARConfig.set(ARConfKey.ROBUST_BOOTTIME, True)
|
||||
|
||||
self._host = self._configs[CONF_HOST]
|
||||
self._identity: AsusDevice | None = None
|
||||
|
||||
# Define properties
|
||||
port = self._configs.get(CONF_PORT, None)
|
||||
if not port:
|
||||
port = (
|
||||
DEFAULT_PORT_HTTPS
|
||||
if self._configs.get(CONF_SSL, False)
|
||||
else DEFAULT_PORT_HTTP
|
||||
)
|
||||
self._configuration_url = (
|
||||
f"http{'s' if self._configs.get(CONF_SSL, False) else ''}"
|
||||
f"://{self._host}:{port}"
|
||||
)
|
||||
self._identifiers: set[tuple[str, str]] = set()
|
||||
self._manufacturer = DEFAULT_IDENTITY_BRAND
|
||||
self._model: str | None = None
|
||||
self._model_id: str | None = None
|
||||
self._name: str = DEFAULT_IDENTITY_NAME
|
||||
self._serial_number: str | None = None
|
||||
self._sw_version: str | None = None
|
||||
|
||||
@staticmethod
|
||||
def _get_api(
|
||||
configs: dict[str, Any],
|
||||
session: aiohttp.ClientSession,
|
||||
config: dict[ARConfKey, Any],
|
||||
) -> AsusRouter:
|
||||
"""Get AsusRouter API."""
|
||||
|
||||
return AsusRouter(
|
||||
hostname=configs[CONF_HOST],
|
||||
username=configs[CONF_USERNAME],
|
||||
password=configs[CONF_PASSWORD],
|
||||
port=configs.get(CONF_PORT, CONF_DEFAULT_PORT),
|
||||
use_ssl=configs[CONF_SSL],
|
||||
cache_time=configs.get(CONF_CACHE_TIME, CONF_DEFAULT_CACHE_TIME),
|
||||
session=session,
|
||||
config=config,
|
||||
)
|
||||
|
||||
def _get_api_config(self) -> dict[ARConfKey, Any]:
|
||||
"""Get configuration for AsusRouter instance."""
|
||||
|
||||
return {
|
||||
# Enable automatic temperature fix
|
||||
ARConfKey.OPTIMISTIC_TEMPERATURE: True,
|
||||
# Disable log warning message
|
||||
ARConfKey.NOTIFIED_OPTIMISTIC_TEMPERATURE: True,
|
||||
}
|
||||
|
||||
@property
|
||||
def api(self) -> AsusRouter:
|
||||
"""Return API."""
|
||||
|
||||
return self._api
|
||||
|
||||
@property
|
||||
def configuration_url(self) -> str:
|
||||
"""Return device configuration URL."""
|
||||
|
||||
return self._configuration_url
|
||||
|
||||
@property
|
||||
def connected(self) -> bool:
|
||||
"""Return connection state."""
|
||||
|
||||
return self._api.connected
|
||||
|
||||
@property
|
||||
def identifiers(self) -> set[tuple[str, str]]:
|
||||
"""Return device identifiers."""
|
||||
|
||||
return self._identifiers
|
||||
|
||||
@property
|
||||
def identity(self) -> AsusDevice | None:
|
||||
"""Return device identity."""
|
||||
|
||||
return self._identity
|
||||
|
||||
@property
|
||||
def manufacturer(self) -> str:
|
||||
"""Return device manufacturer."""
|
||||
|
||||
return self._manufacturer
|
||||
|
||||
@property
|
||||
def model(self) -> str | None:
|
||||
"""Return device model."""
|
||||
|
||||
return self._model
|
||||
|
||||
@property
|
||||
def model_id(self) -> str | None:
|
||||
"""Return device model ID."""
|
||||
|
||||
return self._model_id
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return device name."""
|
||||
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def serial_number(self) -> str | None:
|
||||
"""Return device serial number."""
|
||||
|
||||
return self._serial_number
|
||||
|
||||
@property
|
||||
def sw_version(self) -> str | None:
|
||||
"""Return device software version."""
|
||||
|
||||
return self._sw_version
|
||||
|
||||
# --------------------
|
||||
# Connection -->
|
||||
# --------------------
|
||||
|
||||
async def async_connect(self) -> None:
|
||||
"""Connect to the device."""
|
||||
|
||||
_LOGGER.debug("Connecting to the API")
|
||||
|
||||
await self.api.async_connect()
|
||||
identity = await self.api.async_get_identity()
|
||||
self._identity = identity
|
||||
|
||||
# Set properties
|
||||
self._identifiers = set()
|
||||
if identity.mac is not None:
|
||||
self._identifiers.add((DOMAIN, format_mac(identity.mac)))
|
||||
if identity.serial is not None:
|
||||
self._identifiers.add((DOMAIN, identity.serial))
|
||||
self._manufacturer = identity.brand
|
||||
self._model = identity.model
|
||||
self._model_id = identity.product_id
|
||||
self._name = identity.model or DEFAULT_IDENTITY_NAME
|
||||
self._serial_number = identity.serial
|
||||
self._sw_version = (
|
||||
str(identity.firmware) if identity.firmware else None
|
||||
)
|
||||
|
||||
async def async_disconnect(self) -> None:
|
||||
"""Disconnect from the device."""
|
||||
|
||||
_LOGGER.debug("Disconnecting from the API")
|
||||
|
||||
await self.api.async_disconnect()
|
||||
|
||||
async def async_clean(self) -> None:
|
||||
"""Cleanup."""
|
||||
|
||||
_LOGGER.debug("Cleaning up")
|
||||
|
||||
await self.api.async_cleanup()
|
||||
|
||||
# --------------------
|
||||
# <-- Connection
|
||||
# --------------------
|
||||
|
||||
async def async_cleanup_sensors(
|
||||
self, sensors: dict[str, Any]
|
||||
) -> dict[str, Any]:
|
||||
"""Cleanup sensors depending on the device mode."""
|
||||
|
||||
mode = self._configs.get(CONF_MODE, CONF_DEFAULT_MODE)
|
||||
available = MODE_SENSORS[mode]
|
||||
_LOGGER.debug("Available sensors for mode=`%s`: %s", mode, available)
|
||||
return {
|
||||
group: details
|
||||
for group, details in sensors.items()
|
||||
if group in available
|
||||
}
|
||||
|
||||
async def async_get_available_sensors(self) -> dict[str, dict[str, Any]]:
|
||||
"""Get available sensors."""
|
||||
|
||||
sensors = {
|
||||
AURA: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.AURA),
|
||||
METHOD: self._get_data_aura,
|
||||
},
|
||||
BOOTTIME: {
|
||||
SENSORS: SENSORS_BOOTTIME,
|
||||
METHOD: self._get_data_boottime,
|
||||
},
|
||||
CPU: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.CPU),
|
||||
METHOD: self._get_data_cpu,
|
||||
},
|
||||
DDNS: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.DDNS),
|
||||
METHOD: self._get_data_ddns,
|
||||
},
|
||||
DSL: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.DSL),
|
||||
METHOD: self._get_data_dsl,
|
||||
},
|
||||
FIRMWARE: {
|
||||
SENSORS: SENSORS_FIRMWARE,
|
||||
METHOD: self._get_data_firmware,
|
||||
},
|
||||
GWLAN: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.GWLAN),
|
||||
METHOD: self._get_data_gwlan,
|
||||
},
|
||||
LED: {
|
||||
SENSORS: SENSORS_LED,
|
||||
METHOD: self._get_data_led,
|
||||
},
|
||||
NETWORK: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.NETWORK),
|
||||
METHOD: self._get_data_network,
|
||||
},
|
||||
"ovpn_client": {
|
||||
SENSORS: await self._get_sensors_modern(
|
||||
AsusData.OPENVPN_CLIENT
|
||||
),
|
||||
METHOD: self._get_data_ovpn_client,
|
||||
},
|
||||
"ovpn_server": {
|
||||
SENSORS: await self._get_sensors_ovpn_server(),
|
||||
METHOD: self._get_data_ovpn_server,
|
||||
},
|
||||
PARENTAL_CONTROL: {
|
||||
SENSORS: SENSORS_PARENTAL_CONTROL,
|
||||
METHOD: self._get_data_parental_control,
|
||||
},
|
||||
PORT_FORWARDING: {
|
||||
SENSORS: SENSORS_PORT_FORWARDING,
|
||||
METHOD: self._get_data_port_forwarding,
|
||||
},
|
||||
PORTS: {
|
||||
SENSORS: await self._get_sensors_ports(),
|
||||
METHOD: self._get_data_ports,
|
||||
},
|
||||
RAM: {SENSORS: SENSORS_RAM, METHOD: self._get_data_ram},
|
||||
SYSINFO: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.SYSINFO),
|
||||
METHOD: self._get_data_sysinfo,
|
||||
},
|
||||
TEMPERATURE: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.TEMPERATURE),
|
||||
METHOD: self._get_data_temperature,
|
||||
},
|
||||
"wan": {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.WAN),
|
||||
METHOD: self._get_data_wan,
|
||||
},
|
||||
"wireguard_client": {
|
||||
SENSORS: await self._get_sensors_modern(
|
||||
AsusData.WIREGUARD_CLIENT
|
||||
),
|
||||
METHOD: self._get_data_wireguard_client,
|
||||
},
|
||||
"wireguard_server": {
|
||||
SENSORS: await self._get_sensors_modern(
|
||||
AsusData.WIREGUARD_SERVER
|
||||
),
|
||||
METHOD: self._get_data_wireguard_server,
|
||||
},
|
||||
WLAN: {
|
||||
SENSORS: await self._get_sensors_modern(AsusData.WLAN),
|
||||
METHOD: self._get_data_wlan,
|
||||
},
|
||||
}
|
||||
|
||||
# Cleanup sensors if needed
|
||||
return await self.async_cleanup_sensors(sensors)
|
||||
|
||||
# GET DATA FROM DEVICE ->
|
||||
# General method
|
||||
async def _get_data(
|
||||
self,
|
||||
datatype: AsusData,
|
||||
process: Callable[[dict[str, Any]], dict[str, Any]] | None = None,
|
||||
force: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
"""Get data from the device. This is a generic method."""
|
||||
|
||||
try:
|
||||
raw = await self.api.async_get_data(datatype, force=force)
|
||||
if raw is None:
|
||||
raw = {}
|
||||
if process is not None:
|
||||
return process(raw)
|
||||
return self._process_data(raw)
|
||||
except AsusRouterError as ex:
|
||||
raise UpdateFailed(ex) from ex
|
||||
|
||||
async def _get_data_modern(
|
||||
self,
|
||||
datatype: AsusData,
|
||||
force: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
"""Get data from the device. This is a generic method."""
|
||||
|
||||
try:
|
||||
raw = await self.api.async_get_data(datatype, force=force)
|
||||
return self._process_data_modern(raw)
|
||||
except AsusRouterError as ex:
|
||||
raise UpdateFailed(ex) from ex
|
||||
|
||||
# AiMesh nodes
|
||||
async def async_get_aimesh_nodes(self) -> dict[str, AiMeshDevice]:
|
||||
"""Get dict of AiMesh nodes."""
|
||||
|
||||
return await self._get_data(AsusData.AIMESH)
|
||||
|
||||
# Connected devices
|
||||
async def async_get_clients(self) -> dict[str, AsusClient]:
|
||||
"""Get clients."""
|
||||
|
||||
return await self._get_data(AsusData.CLIENTS, force=True)
|
||||
|
||||
# Sensor-specific methods
|
||||
async def _get_data_aura(self) -> dict[str, Any]:
|
||||
"""Get Aura data from the device."""
|
||||
|
||||
data = await self._get_data_modern(AsusData.AURA)
|
||||
|
||||
return aura_to_ha(data)
|
||||
|
||||
async def _get_data_boottime(self) -> dict[str, Any]:
|
||||
"""Get `boottime` data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.BOOTTIME)
|
||||
|
||||
async def _get_data_cpu(self) -> dict[str, Any]:
|
||||
"""Get CPU data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.CPU)
|
||||
|
||||
async def _get_data_ddns(self) -> dict[str, Any]:
|
||||
"""Get DDNS data from the device."""
|
||||
|
||||
return await self._get_data_modern(AsusData.DDNS)
|
||||
|
||||
async def _get_data_dsl(self) -> dict[str, Any]:
|
||||
"""Get DSL data from the device."""
|
||||
|
||||
return await self._get_data_modern(AsusData.DSL)
|
||||
|
||||
async def _get_data_firmware(self) -> dict[str, Any]:
|
||||
"""Get firmware data from the device."""
|
||||
|
||||
data = await self._get_data_modern(AsusData.FIRMWARE)
|
||||
|
||||
return firmware_to_ha(data)
|
||||
|
||||
async def _get_data_gwlan(self) -> dict[str, Any]:
|
||||
"""Get GWLAN data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.GWLAN)
|
||||
|
||||
async def _get_data_led(self) -> dict[str, Any]:
|
||||
"""Get light data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.LED)
|
||||
|
||||
async def _get_data_network(self) -> dict[str, Any]:
|
||||
"""Get network data from device."""
|
||||
|
||||
return await self._get_data(AsusData.NETWORK)
|
||||
|
||||
async def _get_data_ovpn_client(self) -> dict[str, Any]:
|
||||
"""Get OpenVPN client data from the device."""
|
||||
|
||||
return await self._get_data_modern(AsusData.OPENVPN_CLIENT)
|
||||
|
||||
async def _get_data_ovpn_server(self) -> dict[str, Any]:
|
||||
"""Get OpenVPN server data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.OPENVPN_SERVER)
|
||||
|
||||
async def _get_data_parental_control(self) -> dict[str, Any]:
|
||||
"""Get parental control data from the device."""
|
||||
|
||||
return await self._get_data(
|
||||
AsusData.PARENTAL_CONTROL,
|
||||
self._process_data_parental_control,
|
||||
)
|
||||
|
||||
async def _get_data_port_forwarding(self) -> dict[str, Any]:
|
||||
"""Get port forwarding data from the device."""
|
||||
|
||||
return await self._get_data(
|
||||
AsusData.PORT_FORWARDING,
|
||||
self._process_data_port_forwarding,
|
||||
)
|
||||
|
||||
async def _get_data_ports(self) -> dict[str, dict[str, int]]:
|
||||
"""Get ports data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.PORTS, self._process_data_ports)
|
||||
|
||||
async def _get_data_ram(self) -> dict[str, Any]:
|
||||
"""Get RAM data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.RAM)
|
||||
|
||||
async def _get_data_sysinfo(self) -> dict[str, Any]:
|
||||
"""Get sysinfo data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.SYSINFO)
|
||||
|
||||
async def _get_data_temperature(self) -> dict[str, Any]:
|
||||
"""Get temperarture data from the device."""
|
||||
|
||||
return await self._get_data_modern(AsusData.TEMPERATURE)
|
||||
|
||||
async def _get_data_wan(self) -> dict[str, Any]:
|
||||
"""Get WAN data from the device."""
|
||||
|
||||
return await self._get_data_modern(AsusData.WAN)
|
||||
|
||||
async def _get_data_wireguard_client(self) -> dict[str, Any]:
|
||||
"""Get WireGuard client data from the device."""
|
||||
|
||||
return await self._get_data_modern(AsusData.WIREGUARD_CLIENT)
|
||||
|
||||
async def _get_data_wireguard_server(self) -> dict[str, Any]:
|
||||
"""Get WireGuard server data from the device."""
|
||||
|
||||
return await self._get_data_modern(AsusData.WIREGUARD_SERVER)
|
||||
|
||||
async def _get_data_wlan(self) -> dict[str, Any]:
|
||||
"""Get WLAN data from the device."""
|
||||
|
||||
return await self._get_data(AsusData.WLAN)
|
||||
|
||||
# <- GET DATA FROM DEVICE
|
||||
|
||||
# PROCESS DATA ->
|
||||
@staticmethod
|
||||
def _process_data(raw: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Process data received from the device. This is a generic method."""
|
||||
|
||||
return helpers.as_dict(helpers.flatten_dict(raw))
|
||||
|
||||
@staticmethod
|
||||
def _process_data_modern(raw: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Process `ovpn_client` data."""
|
||||
|
||||
return helpers.clean_dict(convert_to_ha_data(raw))
|
||||
|
||||
@staticmethod
|
||||
def _process_data_parental_control(raw: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Process `parental control` data."""
|
||||
|
||||
rules_list = []
|
||||
rules = raw.get("rules")
|
||||
if rules is not None:
|
||||
for rule in raw["rules"]:
|
||||
device = dataclasses.asdict(raw["rules"][rule])
|
||||
device.pop("timemap")
|
||||
device["type"] = device["type"].name.lower()
|
||||
rules_list.append(device)
|
||||
|
||||
data = convert_to_ha_data(raw)
|
||||
data["list"] = rules_list.copy()
|
||||
data["block_all"] = convert_to_ha_state_bool(raw.get("block_all"))
|
||||
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def _process_data_port_forwarding(raw: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Process `port forwarding` data."""
|
||||
|
||||
data: dict[str, Any] = {}
|
||||
data[STATE] = convert_to_ha_state_bool(raw.get(STATE))
|
||||
devices = []
|
||||
rules = raw.get("rules")
|
||||
if rules is not None:
|
||||
for rule in rules:
|
||||
device = dataclasses.asdict(rule)
|
||||
devices.append(device)
|
||||
data[LIST] = devices.copy()
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def _process_data_ports(raw: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Process `ports` data."""
|
||||
|
||||
data: dict[str, Any] = {}
|
||||
|
||||
for port_type in LIST_PORTS:
|
||||
# Mark port type as disconnected
|
||||
data[port_type] = False
|
||||
# Skip if no data is provided from API
|
||||
if port_type not in raw:
|
||||
continue
|
||||
# Create ports list
|
||||
data[f"{port_type}_{LIST}"] = {}
|
||||
ports_by_type: dict[int, dict[str, Any]] = raw[port_type]
|
||||
for port_number, port_description in ports_by_type.items():
|
||||
# Mark port type connected
|
||||
if port_description.get(STATE):
|
||||
data[port_type] = True
|
||||
# Copy port data to the list
|
||||
data[f"{port_type}_{LIST}"][port_number] = port_description
|
||||
|
||||
return data
|
||||
|
||||
# <- PROCESS DATA
|
||||
|
||||
# GET SENSORS LIST ->
|
||||
async def _get_sensors(
|
||||
self,
|
||||
datatype: AsusData,
|
||||
process: Callable[[dict[str, Any]], list[str]] | None = None,
|
||||
sensor_type: str | None = None,
|
||||
defaults: bool = False,
|
||||
) -> list[str]:
|
||||
"""Get the available sensors. This is a generic method."""
|
||||
|
||||
sensors = []
|
||||
try:
|
||||
data = await self.api.async_get_data(datatype)
|
||||
_LOGGER.debug(
|
||||
"Raw `%s` sensors of type (%s): %s", datatype, type(data), data
|
||||
)
|
||||
sensors = (
|
||||
process(data)
|
||||
if process is not None
|
||||
else self._process_sensors(data)
|
||||
)
|
||||
_LOGGER.debug("Available `%s` sensors: %s", sensor_type, sensors)
|
||||
except AsusRouterError as ex:
|
||||
if sensor_type in DEFAULT_SENSORS and defaults:
|
||||
sensors = DEFAULT_SENSORS[sensor_type]
|
||||
_LOGGER.debug(
|
||||
"Cannot get available `%s` sensors with exception: %s. \
|
||||
Will use the following list: {sensors}",
|
||||
sensor_type,
|
||||
ex,
|
||||
)
|
||||
return sensors
|
||||
|
||||
async def _get_sensors_modern(self, datatype: AsusData) -> list[str]:
|
||||
"""Get the available sensors. This is a generic method."""
|
||||
|
||||
sensors = []
|
||||
try:
|
||||
data = await self.api.async_get_data(datatype)
|
||||
_LOGGER.debug(
|
||||
"Raw `%s` sensors of type (%s): %s", datatype, type(data), data
|
||||
)
|
||||
sensors = convert_to_ha_sensors(data, datatype)
|
||||
_LOGGER.debug(
|
||||
"Available `%s` sensors: %s", datatype.value, sensors
|
||||
)
|
||||
except AsusRouterError as ex:
|
||||
if datatype.value in DEFAULT_SENSORS:
|
||||
sensors = DEFAULT_SENSORS[datatype.value]
|
||||
_LOGGER.debug(
|
||||
"Cannot get available `%s` sensors with exception: %s. \
|
||||
Will use the following list: {sensors}",
|
||||
datatype.value,
|
||||
ex,
|
||||
)
|
||||
return sensors
|
||||
|
||||
async def _get_sensors_ovpn_server(self) -> list[str]:
|
||||
"""Get the available OpenVPN server sensors."""
|
||||
|
||||
return await self._get_sensors(
|
||||
AsusData.OPENVPN_SERVER,
|
||||
self._process_sensors_ovpn_server,
|
||||
sensor_type="ovpn_server",
|
||||
)
|
||||
|
||||
async def _get_sensors_ports(self) -> list[str]:
|
||||
"""Get the available ports sensors."""
|
||||
|
||||
return await self._get_sensors(
|
||||
AsusData.PORTS,
|
||||
self._process_sensors_ports,
|
||||
sensor_type=PORTS,
|
||||
)
|
||||
|
||||
# <- GET SENSORS LIST
|
||||
|
||||
# PROCESS SENSORS LIST->
|
||||
@staticmethod
|
||||
def _process_sensors(raw: dict[str, Any]) -> list[str]:
|
||||
"""Process sensors from the backend library. This is a generic method.
|
||||
|
||||
For the most of sensors which are returned as nested dicts
|
||||
and only the top level keys are the one we are looking for.
|
||||
"""
|
||||
|
||||
flat = helpers.as_dict(helpers.flatten_dict(raw))
|
||||
return helpers.list_from_dict(flat)
|
||||
|
||||
@staticmethod
|
||||
def _process_sensors_ports(raw: dict[str, Any]) -> list[str]:
|
||||
"""Process ports sensors."""
|
||||
|
||||
sensors = []
|
||||
|
||||
for port_type in LIST_PORTS:
|
||||
sensors.append(port_type)
|
||||
sensors.append(f"{port_type}_{LIST}")
|
||||
|
||||
return sensors
|
||||
|
||||
@staticmethod
|
||||
def _process_sensors_ovpn_server(raw: dict[str, Any]) -> list[str]:
|
||||
"""Process OpenVPN server sensors."""
|
||||
|
||||
return convert_to_ha_sensors(raw, AsusData.OPENVPN_SERVER)
|
||||
|
||||
# <- PROCESS SENSORS LIST
|
||||
|
||||
# --------------------
|
||||
# Services -->
|
||||
# --------------------
|
||||
|
||||
def _pc_device2rule(
|
||||
self, device: dict[str, Any], rule_type: PCRuleType
|
||||
) -> ParentalControlRule | None:
|
||||
"""Convert device to parental control rule."""
|
||||
|
||||
mac = device.get("mac")
|
||||
|
||||
if mac is None:
|
||||
return None
|
||||
|
||||
return ParentalControlRule(
|
||||
mac=mac.upper(),
|
||||
name=device.get("name", ""),
|
||||
type=rule_type,
|
||||
)
|
||||
|
||||
async def async_pc_rule(self, **kwargs: Any) -> bool: # noqa: C901, PLR0912
|
||||
"""Change parental control rule(s)."""
|
||||
|
||||
# Get the passed data
|
||||
raw = kwargs.get("raw")
|
||||
|
||||
# Abort if no data is passed
|
||||
if raw is None:
|
||||
return False
|
||||
|
||||
# Get the state to set
|
||||
state = raw.get("state", None)
|
||||
match state:
|
||||
case a if a in ("disable", "allow"):
|
||||
rule_type = PCRuleType.DISABLE
|
||||
case "block":
|
||||
rule_type = PCRuleType.BLOCK
|
||||
case "remove":
|
||||
rule_type = PCRuleType.REMOVE
|
||||
case _:
|
||||
_LOGGER.warning("Unknown parental control state: %s", state)
|
||||
return False
|
||||
|
||||
# Get the targets to set
|
||||
devices = raw.get("devices", [])
|
||||
entities = raw.get("entities", [])
|
||||
|
||||
# Prepare the rules list
|
||||
rules_to_set = []
|
||||
|
||||
# Process entities if any
|
||||
if len(entities) > 0:
|
||||
entity_reg = er.async_get(self.hass)
|
||||
for entity in entities:
|
||||
reg_value = entity_reg.async_get(entity)
|
||||
if not isinstance(reg_value, er.RegistryEntry):
|
||||
continue
|
||||
capabilities: dict[str, Any] = helpers.as_dict(
|
||||
reg_value.capabilities
|
||||
)
|
||||
devices.append(capabilities)
|
||||
|
||||
# Convert devices to rules
|
||||
for device in devices:
|
||||
rule = self._pc_device2rule(device, rule_type)
|
||||
if rule is not None:
|
||||
rules_to_set.append(rule)
|
||||
|
||||
# Set the rules
|
||||
for rule in rules_to_set:
|
||||
result = await self.api.async_set_state(rule)
|
||||
if result is True:
|
||||
_LOGGER.debug("Parental control rule set: %s", rule)
|
||||
else:
|
||||
_LOGGER.warning("Cannot set parental control rule: %s", rule)
|
||||
|
||||
return True
|
||||
|
||||
# --------------------
|
||||
# <-- Services
|
||||
# --------------------
|
||||
# --------------------
|
||||
@@ -0,0 +1,108 @@
|
||||
"""AsusRouter button module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.state import AsusState
|
||||
from homeassistant.components.button import ButtonEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import (
|
||||
ASUSROUTER,
|
||||
CONF_MODE,
|
||||
DOMAIN,
|
||||
ROUTER,
|
||||
STATIC_BUTTONS,
|
||||
STATIC_BUTTONS_OPTIONAL,
|
||||
)
|
||||
from .dataclass import ARButtonDescription
|
||||
from .helpers import to_unique_id
|
||||
from .router import ARDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AsusRouter buttons."""
|
||||
|
||||
buttons = STATIC_BUTTONS.copy()
|
||||
|
||||
router: ARDevice = hass.data[DOMAIN][config_entry.entry_id][ASUSROUTER]
|
||||
entities = []
|
||||
|
||||
if config_entry.options.get(CONF_MODE) == ROUTER:
|
||||
buttons.extend(STATIC_BUTTONS_OPTIONAL)
|
||||
|
||||
for button in buttons:
|
||||
try:
|
||||
entities.append(ARButton(router, button))
|
||||
except Exception as ex: # noqa: BLE001
|
||||
_LOGGER.warning(ex)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class ARButton(ButtonEntity):
|
||||
"""AsusRouter button."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
router: ARDevice,
|
||||
description: ARButtonDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter button."""
|
||||
|
||||
self.router = router
|
||||
self.api = router.bridge.api
|
||||
|
||||
self._attr_device_info = router.device_info
|
||||
self._attr_name = f"{router._conf_name} {description.name}"
|
||||
self._attr_unique_id = to_unique_id(f"{router.mac}_{description.name}")
|
||||
self._attr_capability_attributes = description.capabilities
|
||||
|
||||
self._state = description.state
|
||||
self._state_args = description.state_args
|
||||
self._state_expect_modify = description.state_expect_modify
|
||||
|
||||
if description.icon:
|
||||
self._attr_icon = description.icon
|
||||
|
||||
async def async_press(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Press button."""
|
||||
|
||||
kwargs = self._state_args if self._state_args is not None else {}
|
||||
|
||||
await self._set_state(
|
||||
state=self._state,
|
||||
expect_modify=self._state_expect_modify,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
async def _set_state(
|
||||
self,
|
||||
state: AsusState,
|
||||
expect_modify: bool = False,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Set switch state."""
|
||||
|
||||
try:
|
||||
_LOGGER.debug("Pressing %s", state)
|
||||
result = await self.api.async_set_state(
|
||||
state=state, expect_modify=expect_modify, **kwargs
|
||||
)
|
||||
if not result:
|
||||
_LOGGER.debug("Didn't manage to press %s", state)
|
||||
except Exception as ex: # noqa: BLE001
|
||||
_LOGGER.error("Pressing %s caused an exception: %s", state, ex)
|
||||
@@ -0,0 +1,214 @@
|
||||
"""AsusRouter Client module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from datetime import UTC, datetime
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.client import (
|
||||
AsusClient,
|
||||
AsusClientConnection,
|
||||
AsusClientConnectionWlan,
|
||||
AsusClientDescription,
|
||||
)
|
||||
from asusrouter.modules.connection import ConnectionState, ConnectionType
|
||||
from asusrouter.modules.homeassistant import convert_to_ha_state_bool
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
|
||||
from .helpers import clean_dict
|
||||
|
||||
|
||||
class ARClient:
|
||||
"""AsussRouter Client class."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
mac: str,
|
||||
name: str | None = None,
|
||||
):
|
||||
"""Initialize the client."""
|
||||
|
||||
self._mac = mac
|
||||
self._name = name
|
||||
|
||||
self.device: bool = False
|
||||
|
||||
# To be recieved from the device
|
||||
# Client description
|
||||
self.description: AsusClientDescription | None = None
|
||||
# Connection description -
|
||||
# AsusClientConnection / AsusClientConnectionWlan
|
||||
self.connection: AsusClientConnection | None = None
|
||||
|
||||
# To be generated for other parts of the integration
|
||||
self._identity: dict[str, Any] | None = None
|
||||
self._extra_state_attributes: dict[str, Any] = {}
|
||||
|
||||
# Connection state
|
||||
self._state: ConnectionState = ConnectionState.UNKNOWN
|
||||
self._connection_type: ConnectionType = ConnectionType.DISCONNECTED
|
||||
self._guest: bool = False
|
||||
self._guest_id: int = 0
|
||||
|
||||
# Device last active
|
||||
self._last_activity: datetime | None = None
|
||||
|
||||
@callback
|
||||
def update(
|
||||
self,
|
||||
client_info: AsusClient | None = None,
|
||||
consider_home: int = 0,
|
||||
event_call: Callable[[str, dict[str, Any] | None], None] | None = None,
|
||||
) -> None:
|
||||
"""Update client information."""
|
||||
|
||||
utc_now: datetime = datetime.now(UTC)
|
||||
|
||||
state: ConnectionState | None = None
|
||||
|
||||
# If client information is provided
|
||||
if client_info is not None:
|
||||
# Description
|
||||
self.description = client_info.description
|
||||
|
||||
# Connection
|
||||
self.connection = client_info.connection
|
||||
|
||||
# Connected state
|
||||
state = client_info.state
|
||||
|
||||
self._identity = self.generate_identity(state)
|
||||
self._extra_state_attributes = self.generate_extra_state_attributes()
|
||||
|
||||
# If is connected
|
||||
if state is ConnectionState.CONNECTED:
|
||||
# Update last activity
|
||||
self._last_activity = utc_now
|
||||
|
||||
# Device was disconnected, now it has reconnected
|
||||
# Fire event and connected callback
|
||||
if (
|
||||
self._state is ConnectionState.DISCONNECTED
|
||||
and event_call is not None
|
||||
):
|
||||
event_call("device_reconnected", self.identity)
|
||||
|
||||
# Update connection status
|
||||
self._state = ConnectionState.CONNECTED
|
||||
|
||||
# If was connected, check if it's time to mark it as disconnected
|
||||
# when we are above the consider home time
|
||||
elif (
|
||||
self._state is ConnectionState.CONNECTED
|
||||
and self._last_activity is not None
|
||||
and (utc_now - self._last_activity).total_seconds() > consider_home
|
||||
):
|
||||
# Update connection status
|
||||
self._state = ConnectionState.DISCONNECTED
|
||||
|
||||
# Fire event
|
||||
if event_call is not None:
|
||||
event_call(
|
||||
"device_disconnected",
|
||||
self.identity,
|
||||
)
|
||||
|
||||
def generate_identity(
|
||||
self, state: ConnectionState | None
|
||||
) -> dict[str, Any]:
|
||||
"""Generate client identity."""
|
||||
|
||||
identity: dict[str, Any] = {
|
||||
"mac": self.mac_address,
|
||||
"ip": self.ip_address,
|
||||
"name": self.name,
|
||||
}
|
||||
|
||||
if isinstance(self.connection, AsusClientConnection):
|
||||
# Rewrite guest from last known state if needed
|
||||
if state == ConnectionState.DISCONNECTED:
|
||||
identity["guest"] = self._guest
|
||||
identity["guest_id"] = self._guest_id
|
||||
if self.connection.type != ConnectionType.DISCONNECTED:
|
||||
self._connection_type = self.connection.type
|
||||
identity["connection_type"] = self._connection_type
|
||||
identity["node"] = (
|
||||
format_mac(self.connection.node)
|
||||
if self.connection.node
|
||||
else None
|
||||
)
|
||||
|
||||
if isinstance(self.connection, AsusClientConnectionWlan):
|
||||
identity["guest"] = self._guest = self.connection.guest
|
||||
identity["guest_id"] = self._guest_id = self.connection.guest_id
|
||||
identity["connected"] = self.connection.since
|
||||
|
||||
return clean_dict(identity)
|
||||
|
||||
def generate_extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Generate extra state attributes."""
|
||||
|
||||
attributes: dict[str, Any] = (
|
||||
self._identity.copy() if self._identity else {}
|
||||
)
|
||||
|
||||
attributes["last_activity"] = self._last_activity
|
||||
|
||||
if isinstance(self.description, AsusClientDescription):
|
||||
attributes["vendor"] = self.description.vendor
|
||||
|
||||
if isinstance(self.connection, AsusClientConnection):
|
||||
attributes["ip_type"] = self.connection.ip_method
|
||||
attributes["internet_mode"] = self.connection.internet_mode
|
||||
attributes["internet"] = self.connection.internet_state
|
||||
|
||||
if isinstance(self.connection, AsusClientConnectionWlan):
|
||||
attributes["rssi"] = self.connection.rssi
|
||||
attributes["rx_speed"] = self.connection.rx_speed
|
||||
attributes["tx_speed"] = self.connection.tx_speed
|
||||
|
||||
return clean_dict(attributes)
|
||||
|
||||
@property
|
||||
def state(self) -> bool | None:
|
||||
"""Return if the device is connected."""
|
||||
|
||||
return convert_to_ha_state_bool(self._state)
|
||||
|
||||
@property
|
||||
def ip_address(self) -> str | None:
|
||||
"""Return IP address."""
|
||||
|
||||
return (
|
||||
self.connection.ip_address if self.connection is not None else None
|
||||
)
|
||||
|
||||
@property
|
||||
def mac_address(self) -> str:
|
||||
"""Return MAC address."""
|
||||
|
||||
return self._mac
|
||||
|
||||
@property
|
||||
def name(self) -> str | None:
|
||||
"""Return name."""
|
||||
|
||||
return (
|
||||
self.description.name
|
||||
if self.description is not None
|
||||
else self._name
|
||||
)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return extra state attributes."""
|
||||
|
||||
return self._extra_state_attributes
|
||||
|
||||
@property
|
||||
def identity(self) -> dict[str, Any] | None:
|
||||
"""Return identity."""
|
||||
|
||||
return self._identity
|
||||
@@ -0,0 +1,58 @@
|
||||
"""AsusRouter compilers module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from .const import (
|
||||
CONF_LABELS_INTERFACES,
|
||||
MAP_NETWORK_TEMP,
|
||||
NAME,
|
||||
NETWORK,
|
||||
SENSORS_PARAM_NETWORK,
|
||||
)
|
||||
from .dataclass import ARSensorDescription
|
||||
|
||||
|
||||
def list_sensors_network(
|
||||
interfaces: list[str] | None = None,
|
||||
) -> list[ARSensorDescription]:
|
||||
"""Compile a list of network sensors."""
|
||||
|
||||
sensors: list[ARSensorDescription] = []
|
||||
|
||||
if not interfaces or len(interfaces) < 1:
|
||||
return sensors
|
||||
|
||||
for intf in interfaces:
|
||||
interface = MAP_NETWORK_TEMP.get(intf, intf)
|
||||
for sensor_type, data in SENSORS_PARAM_NETWORK.items():
|
||||
key = f"{interface}_{sensor_type}"
|
||||
sensors.append(
|
||||
ARSensorDescription(
|
||||
key=key,
|
||||
key_group=NETWORK,
|
||||
name=f"{CONF_LABELS_INTERFACES.get(interface, interface)} "
|
||||
f"{data[NAME]}"
|
||||
or None,
|
||||
icon=data["icon"] or None,
|
||||
state_class=data["state_class"] or None,
|
||||
device_class=data["device_class"] or None,
|
||||
native_unit_of_measurement=data[
|
||||
"native_unit_of_measurement"
|
||||
]
|
||||
or None,
|
||||
suggested_unit_of_measurement=data[
|
||||
"suggested_unit_of_measurement"
|
||||
]
|
||||
or None,
|
||||
suggested_display_precision=data[
|
||||
"suggested_display_precision"
|
||||
]
|
||||
or None,
|
||||
entity_registry_enabled_default=data[
|
||||
"entity_registry_enabled_default"
|
||||
]
|
||||
or True,
|
||||
)
|
||||
)
|
||||
|
||||
return sensors
|
||||
@@ -0,0 +1,8 @@
|
||||
"""AsusRouter constants module / v1."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Final
|
||||
|
||||
DEFAULT_IDENTITY_BRAND: Final = "ASUSTek"
|
||||
DEFAULT_IDENTITY_NAME: Final = "AsusRouter"
|
||||
@@ -0,0 +1,85 @@
|
||||
"""AsusRouter dataclass module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.state import AsusState, AsusStateNone
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.components.button import ButtonEntityDescription
|
||||
from homeassistant.components.light import LightEntityDescription
|
||||
from homeassistant.components.sensor import SensorEntityDescription
|
||||
from homeassistant.components.switch import SwitchEntityDescription
|
||||
from homeassistant.components.update import UpdateEntityDescription
|
||||
from homeassistant.helpers.entity import EntityDescription
|
||||
|
||||
|
||||
@dataclass
|
||||
class AREntityDescription(EntityDescription):
|
||||
"""Describe AsusRouter entity."""
|
||||
|
||||
capabilities: dict[str, Any] | None = None
|
||||
key_group: str = ""
|
||||
value: Callable[[Any], Any] = lambda val: val
|
||||
extra_state_attributes: dict[str, Any] | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ARBinaryDescription(AREntityDescription, BinarySensorEntityDescription):
|
||||
"""Describe AsusRouter binary entity."""
|
||||
|
||||
icon_on: str | None = None
|
||||
icon_off: str | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ARSensorDescription(AREntityDescription, SensorEntityDescription):
|
||||
"""Describe AsusRouter sensor."""
|
||||
|
||||
factor: int | None = None
|
||||
precision: int = 3
|
||||
|
||||
|
||||
@dataclass
|
||||
class ARBinarySensorDescription(
|
||||
ARBinaryDescription, BinarySensorEntityDescription
|
||||
):
|
||||
"""Describe AsusRouter sensor."""
|
||||
|
||||
|
||||
@dataclass
|
||||
class ARLightDescription(ARBinaryDescription, LightEntityDescription):
|
||||
"""Describe AsusRouter light."""
|
||||
|
||||
|
||||
@dataclass
|
||||
class ARSwitchDescription(AREntityDescription, SwitchEntityDescription):
|
||||
"""Describe AsusRouter switch."""
|
||||
|
||||
icon_on: str | None = None
|
||||
icon_off: str | None = None
|
||||
|
||||
state_on: AsusState = AsusStateNone.NONE
|
||||
state_on_args: dict[str, Any] | None = None
|
||||
state_off: AsusState = AsusStateNone.NONE
|
||||
state_off_args: dict[str, Any] | None = None
|
||||
|
||||
state_expect_modify: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ARButtonDescription(AREntityDescription, ButtonEntityDescription):
|
||||
"""Describe AsusRouter button."""
|
||||
|
||||
state: AsusState = AsusStateNone.NONE
|
||||
state_args: dict[str, Any] | None = None
|
||||
state_expect_modify: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class ARUpdateDescription(AREntityDescription, UpdateEntityDescription):
|
||||
"""Describe AsusRouter update."""
|
||||
@@ -0,0 +1,194 @@
|
||||
"""AsusRouter device tracker module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.device_tracker import SourceType
|
||||
from homeassistant.components.device_tracker.config_entry import ScannerEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .client import ARClient
|
||||
from .const import (
|
||||
ASUSROUTER,
|
||||
CONF_DEFAULT_TRACK_DEVICES,
|
||||
CONF_TRACK_DEVICES,
|
||||
DEFAULT_DEVICE_NAME,
|
||||
DOMAIN,
|
||||
)
|
||||
from .router import ARDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up device tracker for AsusRouter component."""
|
||||
|
||||
# If device tracking is disabled
|
||||
if (
|
||||
config_entry.options.get(
|
||||
CONF_TRACK_DEVICES, CONF_DEFAULT_TRACK_DEVICES
|
||||
)
|
||||
is False
|
||||
):
|
||||
return
|
||||
|
||||
router = hass.data[DOMAIN][config_entry.entry_id][ASUSROUTER]
|
||||
tracked: set = set()
|
||||
|
||||
@callback
|
||||
def update_router():
|
||||
"""Update the values of the router."""
|
||||
|
||||
add_entities(router, async_add_entities, tracked)
|
||||
|
||||
router.async_on_close(
|
||||
async_dispatcher_connect(hass, router.signal_device_new, update_router)
|
||||
)
|
||||
|
||||
update_router()
|
||||
|
||||
|
||||
@callback
|
||||
def add_entities(
|
||||
router: ARDevice,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
tracked: set[str],
|
||||
) -> None:
|
||||
"""Add new tracker entities from the router."""
|
||||
|
||||
new_tracked = []
|
||||
|
||||
for mac, device in router.devices.items():
|
||||
if mac in tracked:
|
||||
continue
|
||||
|
||||
new_tracked.append(ARDeviceEntity(router, device))
|
||||
tracked.add(mac)
|
||||
|
||||
if new_tracked:
|
||||
async_add_entities(new_tracked)
|
||||
|
||||
|
||||
class ARDeviceEntity(ScannerEntity):
|
||||
"""Connected device class."""
|
||||
|
||||
_attr_should_poll = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
router: ARDevice,
|
||||
client: ARClient,
|
||||
) -> None:
|
||||
"""Initialize connected device."""
|
||||
|
||||
self._router = router
|
||||
self._client = client
|
||||
self._attr_unique_id = f"{router.mac}_{client.mac_address}"
|
||||
self._attr_name = client.name or DEFAULT_DEVICE_NAME
|
||||
self._attr_capability_attributes = {
|
||||
"mac": client.mac_address,
|
||||
"name": self._attr_name,
|
||||
}
|
||||
|
||||
# Assign device info if set up
|
||||
if router.client_device is True and client.device is True:
|
||||
self._attr_device_info = self._compile_device_info(
|
||||
client.mac_address, client.name
|
||||
)
|
||||
|
||||
def _compile_device_info(
|
||||
self, mac_address: str, name: str | None
|
||||
) -> DeviceInfo:
|
||||
"""Compile device info."""
|
||||
|
||||
return DeviceInfo(
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, mac_address)},
|
||||
default_name=name,
|
||||
via_device=(DOMAIN, self._router.mac),
|
||||
)
|
||||
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
"""Return device info."""
|
||||
|
||||
return self._attr_device_info
|
||||
|
||||
@property
|
||||
def source_type(self) -> SourceType:
|
||||
"""Source type."""
|
||||
|
||||
return SourceType.ROUTER
|
||||
|
||||
@property
|
||||
def is_connected(self) -> bool | None:
|
||||
"""Device status."""
|
||||
|
||||
return self._client.state
|
||||
|
||||
@property
|
||||
def ip_address(self) -> str | None:
|
||||
"""Device IP address."""
|
||||
|
||||
return self._client.ip_address
|
||||
|
||||
@property
|
||||
def mac_address(self) -> str:
|
||||
"""Device MAC address."""
|
||||
|
||||
return self._client.mac_address
|
||||
|
||||
@property
|
||||
def hostname(self) -> str | None:
|
||||
"""Device hostname."""
|
||||
|
||||
return self._client.name
|
||||
|
||||
@property
|
||||
def icon(self) -> str:
|
||||
"""Device icon."""
|
||||
|
||||
return (
|
||||
"mdi:lan-connect" if self._client.state else "mdi:lan-disconnect"
|
||||
)
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str | None:
|
||||
"""Return unique ID of the entity."""
|
||||
|
||||
return self._attr_unique_id
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return extra state attributes."""
|
||||
|
||||
return dict(sorted(self._client.extra_state_attributes.items())) or {}
|
||||
|
||||
@callback
|
||||
def async_on_demand_update(self) -> None:
|
||||
"""Update the state."""
|
||||
|
||||
if self._client.mac_address in self._router.devices:
|
||||
self._client = self._router.devices[self._client.mac_address]
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register state update callback."""
|
||||
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
self._router.signal_device_update,
|
||||
self.async_on_demand_update,
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,92 @@
|
||||
"""AsusRouter diagnostics module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from .const import (
|
||||
ASUSROUTER,
|
||||
DEVICE_ATTRIBUTE_LAST_ACTIVITY,
|
||||
DOMAIN,
|
||||
TO_REDACT,
|
||||
TO_REDACT_ATTRS,
|
||||
TO_REDACT_DEV,
|
||||
TO_REDACT_STATE,
|
||||
)
|
||||
from .router import ARDevice
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
) -> dict[str, dict[str, Any]]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
|
||||
data = {"entry": async_redact_data(entry.as_dict(), TO_REDACT)}
|
||||
|
||||
router: ARDevice = hass.data[DOMAIN][entry.entry_id][ASUSROUTER]
|
||||
|
||||
# Gather information how this device is represented in Home Assistant
|
||||
device_registry = dr.async_get(hass)
|
||||
entity_registry = er.async_get(hass)
|
||||
hass_device = device_registry.async_get_device(
|
||||
identifiers=router.device_info["identifiers"]
|
||||
)
|
||||
if not hass_device:
|
||||
return data
|
||||
|
||||
data["device"] = {
|
||||
**async_redact_data(hass_device.dict_repr, TO_REDACT_DEV),
|
||||
"entities": {},
|
||||
"tracked_devices": [],
|
||||
}
|
||||
|
||||
hass_entities = er.async_entries_for_device(
|
||||
entity_registry,
|
||||
device_id=hass_device.id,
|
||||
include_disabled_entities=True,
|
||||
)
|
||||
|
||||
for entity_entry in hass_entities:
|
||||
state = hass.states.get(entity_entry.entity_id)
|
||||
state_dict = None
|
||||
if state:
|
||||
state_dict = dict(state.as_dict())
|
||||
# The entity_id is already provided at root level.
|
||||
state_dict.pop("entity_id", None)
|
||||
# The context doesn't provide useful information in this case.
|
||||
state_dict.pop("context", None)
|
||||
# Remove sensitive info from attributes.
|
||||
if "attributes" in state_dict:
|
||||
state_dict["attributes"] = async_redact_data(
|
||||
dict(state_dict["attributes"]), TO_REDACT_ATTRS
|
||||
)
|
||||
# Remove sensitive info from sensors states.
|
||||
if entity_entry.original_name in TO_REDACT_STATE:
|
||||
state_dict = async_redact_data(state_dict, "state")
|
||||
|
||||
data["device"]["entities"][entity_entry.entity_id] = {
|
||||
**async_redact_data(
|
||||
entity_entry.as_partial_dict,
|
||||
TO_REDACT,
|
||||
),
|
||||
"state": state_dict,
|
||||
}
|
||||
|
||||
for device in router.devices.values():
|
||||
data["device"]["tracked_devices"].append(
|
||||
{
|
||||
"name": device.name,
|
||||
"ip_address": device.ip_address,
|
||||
"last_activity": device.extra_state_attributes.get(
|
||||
DEVICE_ATTRIBUTE_LAST_ACTIVITY, None
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
return data
|
||||
@@ -0,0 +1,192 @@
|
||||
"""AsusRouter entity module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.homeassistant import convert_to_ha_state_bool
|
||||
from asusrouter.modules.state import AsusState
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import (
|
||||
CoordinatorEntity,
|
||||
DataUpdateCoordinator,
|
||||
)
|
||||
|
||||
from .const import ASUSROUTER, COORDINATOR, DOMAIN
|
||||
from .dataclass import (
|
||||
ARBinaryDescription,
|
||||
AREntityDescription,
|
||||
ARSwitchDescription,
|
||||
)
|
||||
from .helpers import to_unique_id
|
||||
from .router import ARDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_ar_entry( # noqa: PLR0913
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
sensors: list[AREntityDescription],
|
||||
sensor_class: type[AREntity],
|
||||
hide: list[str] | None = None,
|
||||
) -> None:
|
||||
"""Set up AsusRouter entities."""
|
||||
|
||||
router: ARDevice = hass.data[DOMAIN][config_entry.entry_id][ASUSROUTER]
|
||||
entities = []
|
||||
|
||||
if not hide:
|
||||
hide = []
|
||||
|
||||
for sensor_data in router.sensor_coordinator.values():
|
||||
coordinator = sensor_data[COORDINATOR]
|
||||
for sensor_description in sensors:
|
||||
try:
|
||||
sensor_type = sensor_description.key_group
|
||||
|
||||
# Make sure extra state attributes are dict
|
||||
if not sensor_description.extra_state_attributes:
|
||||
sensor_description.extra_state_attributes = {}
|
||||
|
||||
if (
|
||||
sensor_type in sensor_data
|
||||
and sensor_description.key in sensor_data[sensor_type]
|
||||
):
|
||||
# Hide protected values
|
||||
sensor_description.extra_state_attributes = {
|
||||
key: value
|
||||
for key, value in sensor_description.extra_state_attributes.items() # noqa: E501
|
||||
if value not in hide
|
||||
}
|
||||
|
||||
entities.append(
|
||||
sensor_class(coordinator, router, sensor_description)
|
||||
)
|
||||
except Exception as ex: # noqa: BLE001
|
||||
_LOGGER.warning(
|
||||
"Got an exception when creating entities: %s. "
|
||||
"Please, report this. Sensor description: %s",
|
||||
ex,
|
||||
sensor_description,
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class AREntity(CoordinatorEntity):
|
||||
"""AsusRouter entity."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
router: ARDevice,
|
||||
description: AREntityDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter entity."""
|
||||
|
||||
super().__init__(coordinator)
|
||||
self.router = router
|
||||
self.api = router.bridge.api
|
||||
self.coordinator = coordinator
|
||||
|
||||
self._attr_name = f"{router._conf_name} {description.name}"
|
||||
self._attr_unique_id = to_unique_id(f"{router.mac}_{description.name}")
|
||||
self._attr_device_info = router.device_info
|
||||
self._attr_capability_attributes = description.capabilities
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return extra state attributes."""
|
||||
|
||||
# Check if description is of the needed class
|
||||
if not isinstance(self.entity_description, AREntityDescription):
|
||||
return {}
|
||||
|
||||
description = self.entity_description
|
||||
_attributes = description.extra_state_attributes
|
||||
if not _attributes:
|
||||
return {}
|
||||
|
||||
# Mask attributes
|
||||
attrs_to_mask = self.router.sensor_filters.get(
|
||||
(description.key_group, description.key),
|
||||
[],
|
||||
)
|
||||
for attr in attrs_to_mask:
|
||||
if attr in _attributes:
|
||||
_attributes.pop(attr, None)
|
||||
|
||||
attributes = {}
|
||||
|
||||
for attr in _attributes:
|
||||
if attr in self.coordinator.data:
|
||||
attributes[_attributes[attr]] = self.coordinator.data[attr]
|
||||
|
||||
return dict(sorted(attributes.items())) or {}
|
||||
|
||||
|
||||
class ARBinaryEntity(AREntity):
|
||||
"""AsusRouter binary entity."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
router: ARDevice,
|
||||
description: AREntityDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter binary entity."""
|
||||
|
||||
super().__init__(coordinator, router, description)
|
||||
if isinstance(description, ARBinaryDescription | ARSwitchDescription):
|
||||
self._icon_onoff = bool(
|
||||
description.icon_on and description.icon_off
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool | None:
|
||||
"""Get the state."""
|
||||
|
||||
return convert_to_ha_state_bool(
|
||||
self.coordinator.data.get(self.entity_description.key)
|
||||
)
|
||||
|
||||
@property
|
||||
def icon(self) -> str | None:
|
||||
"""Get the icon."""
|
||||
|
||||
if (
|
||||
isinstance(
|
||||
self.entity_description,
|
||||
ARBinaryDescription | ARSwitchDescription,
|
||||
)
|
||||
and self._icon_onoff
|
||||
):
|
||||
if self.is_on:
|
||||
return self.entity_description.icon_on
|
||||
return self.entity_description.icon_off
|
||||
if self.entity_description.icon:
|
||||
return self.entity_description.icon
|
||||
return None
|
||||
|
||||
async def _set_state(
|
||||
self,
|
||||
state: AsusState,
|
||||
expect_modify: bool = False,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Set switch state."""
|
||||
try:
|
||||
_LOGGER.debug("Setting state to %s", state)
|
||||
result = await self.api.async_set_state(
|
||||
state=state, expect_modify=expect_modify, **kwargs
|
||||
)
|
||||
await self.coordinator.async_request_refresh()
|
||||
if not result:
|
||||
_LOGGER.debug("State was not set!")
|
||||
except Exception as ex: # noqa: BLE001
|
||||
_LOGGER.error("Unable to set state with an exception: %s", ex)
|
||||
@@ -0,0 +1,52 @@
|
||||
"""AsusRouter helpers module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
|
||||
def clean_dict(raw: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Clean dictionary from None values."""
|
||||
|
||||
return {
|
||||
k: v for k, v in raw.items() if v is not None or k.endswith("state")
|
||||
}
|
||||
|
||||
|
||||
def flatten_dict(obj: Any, keystring: str = "", delimiter: str = "_"):
|
||||
"""Flatten dictionary."""
|
||||
|
||||
if isinstance(obj, dict):
|
||||
keystring = keystring + delimiter if keystring else keystring
|
||||
for key in obj:
|
||||
yield from flatten_dict(obj[key], keystring + str(key))
|
||||
else:
|
||||
yield keystring, obj
|
||||
|
||||
|
||||
def as_dict(pyobj):
|
||||
"""Return generator object as dictionary."""
|
||||
|
||||
return dict(pyobj)
|
||||
|
||||
|
||||
def list_from_dict(raw: dict[str, Any]) -> list[str]:
|
||||
"""Return dictionary keys as list."""
|
||||
|
||||
return list(raw.keys())
|
||||
|
||||
|
||||
def to_unique_id(raw: str):
|
||||
"""Convert string to unique_id."""
|
||||
|
||||
string = (
|
||||
re.sub(r"(?<=[a-z0-9:_])(?=[A-Z])|[^a-zA-Z0-9:_]", " ", raw)
|
||||
.strip()
|
||||
.replace(" ", "_")
|
||||
)
|
||||
result = "".join(string.lower())
|
||||
while "__" in result:
|
||||
result = result.replace("__", "_")
|
||||
|
||||
return result
|
||||
@@ -0,0 +1,190 @@
|
||||
"""AsusRouter light module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.aura import AsusAura
|
||||
from asusrouter.modules.color import ColorRGB, scale_value_int
|
||||
from asusrouter.modules.led import AsusLED
|
||||
from homeassistant.components.light import (
|
||||
ColorMode,
|
||||
LightEntity,
|
||||
LightEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
from .const import ASUSROUTER, DOMAIN, STATIC_AURA, STATIC_LIGHTS
|
||||
from .dataclass import ARLightDescription
|
||||
from .entity import ARBinaryEntity, async_setup_ar_entry
|
||||
from .modules.aura import AURA_EFFECTS, AURA_NO_EFFECT, per_zone_light
|
||||
from .router import ARDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
EFFECT = "effect"
|
||||
RGB_COLOR = "rgb_color"
|
||||
BRIGHTNESS = "brightness"
|
||||
COLOR_MODE = "color_mode"
|
||||
ZONE_ID = "zone_id"
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AsusRouter lights."""
|
||||
|
||||
leds = STATIC_LIGHTS.copy()
|
||||
if (
|
||||
hass.data[DOMAIN][config_entry.entry_id][
|
||||
ASUSROUTER
|
||||
].bridge.identity.led
|
||||
is True
|
||||
):
|
||||
await async_setup_ar_entry(
|
||||
hass, config_entry, async_add_entities, leds, ARLightLED
|
||||
)
|
||||
|
||||
auras = STATIC_AURA.copy()
|
||||
if (
|
||||
hass.data[DOMAIN][config_entry.entry_id][
|
||||
ASUSROUTER
|
||||
].bridge.identity.aura
|
||||
is True
|
||||
):
|
||||
# Create per-zone lights
|
||||
auras.extend(
|
||||
per_zone_light(
|
||||
hass.data[DOMAIN][config_entry.entry_id][
|
||||
ASUSROUTER
|
||||
].bridge.identity.aura_zone
|
||||
)
|
||||
)
|
||||
|
||||
await async_setup_ar_entry(
|
||||
hass, config_entry, async_add_entities, auras, ARLightAura
|
||||
)
|
||||
|
||||
|
||||
class ARLightLED(ARBinaryEntity, LightEntity):
|
||||
"""AsusRouter LED light."""
|
||||
|
||||
_attr_color_mode = ColorMode.ONOFF
|
||||
_attr_supported_color_modes = {ColorMode.ONOFF}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
router: ARDevice,
|
||||
description: ARLightDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter LED light."""
|
||||
|
||||
super().__init__(coordinator, router, description)
|
||||
self.entity_description: ARLightDescription = description
|
||||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn on LED."""
|
||||
|
||||
await self._set_state(AsusLED.ON)
|
||||
|
||||
async def async_turn_off(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn off LED."""
|
||||
|
||||
await self._set_state(AsusLED.OFF)
|
||||
|
||||
|
||||
class ARLightAura(ARBinaryEntity, LightEntity):
|
||||
"""AsusRouter Aura light."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
router: ARDevice,
|
||||
description: ARLightDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter Aura light."""
|
||||
|
||||
self._attr_supported_features = LightEntityFeature.EFFECT
|
||||
self._attr_effect_list = AURA_EFFECTS
|
||||
|
||||
super().__init__(coordinator, router, description)
|
||||
self.entity_description: ARLightDescription = description
|
||||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn on Aura."""
|
||||
|
||||
effect = AsusAura.ON
|
||||
if "effect" in kwargs:
|
||||
effect = AsusAura.__members__.get(
|
||||
kwargs["effect"].upper(), AsusAura.ON
|
||||
)
|
||||
|
||||
color = None
|
||||
if "rgb_color" in kwargs:
|
||||
rgb = kwargs["rgb_color"]
|
||||
color = ColorRGB(rgb[0], rgb[1], rgb[2], scale=255)
|
||||
|
||||
brightness = None
|
||||
if "brightness" in kwargs:
|
||||
brightness = scale_value_int(kwargs["brightness"], 128, 255)
|
||||
|
||||
zone_id = (
|
||||
self.entity_description.capabilities.get("zone_id", None)
|
||||
if self.entity_description.capabilities
|
||||
else None
|
||||
)
|
||||
|
||||
await self._set_state(
|
||||
effect,
|
||||
color=color,
|
||||
brightness=brightness,
|
||||
zone=zone_id,
|
||||
)
|
||||
|
||||
async def async_turn_off(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn off Aura."""
|
||||
|
||||
await self._set_state(AsusAura.OFF)
|
||||
|
||||
@property
|
||||
def effect(self) -> str | None:
|
||||
"""Return the current effect."""
|
||||
|
||||
return self.coordinator.data.get("effect", AURA_NO_EFFECT)
|
||||
|
||||
@property
|
||||
def supported_color_modes(self) -> set[str] | None:
|
||||
"""Return the supported color modes."""
|
||||
|
||||
# This is a workaround to avoid a bug in HA
|
||||
# which does not hide the color picker and brightness slider
|
||||
# even when the current color mode is set to ONOFF only
|
||||
_supported_color_modes = self.coordinator.data.get(
|
||||
"color_mode", ColorMode.RGB
|
||||
)
|
||||
return {_supported_color_modes}
|
||||
|
||||
@property
|
||||
def color_mode(self) -> ColorMode | str | None:
|
||||
"""Return the color mode."""
|
||||
|
||||
return self.coordinator.data.get("color_mode", ColorMode.RGB)
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"domain": "asusrouter",
|
||||
"name": "AsusRouter",
|
||||
"codeowners": ["@vaskivskyi"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://asusrouter.vaskivskyi.com",
|
||||
"integration_type": "hub",
|
||||
"iot_class": "local_polling",
|
||||
"issue_tracker": "https://github.com/Vaskivskyi/ha-asusrouter/issues",
|
||||
"loggers": ["asusrouter"],
|
||||
"requirements": ["asusrouter>=1.21.0"],
|
||||
"version": "0.40.1"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
"""Complex modules for AsusRouter integration."""
|
||||
@@ -0,0 +1,131 @@
|
||||
"""Aura RGB module for AsusRouter integration.
|
||||
|
||||
This module allows converting AsusRouter Aura data to the
|
||||
Home Assistant format. This is required due to the complex
|
||||
data structure and effect handling by Home Assistant.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.color import ColorRGBB
|
||||
from asusrouter.tools.converters import scale_value_int
|
||||
from homeassistant.components.light import ColorMode
|
||||
from homeassistant.const import EntityCategory
|
||||
|
||||
from ..const import ICON_LIGHT_OFF, ICON_LIGHT_ON
|
||||
from ..dataclass import AREntityDescription, ARLightDescription
|
||||
|
||||
AURA_NO_EFFECT = "EFFECT_OFF"
|
||||
AURA_FALLBACK_BRIGHTNESS = 128
|
||||
AURA_FALLBACK_COLOR = ColorRGBB(
|
||||
(128, 128, 128),
|
||||
AURA_FALLBACK_BRIGHTNESS,
|
||||
scale=128,
|
||||
)
|
||||
|
||||
AURA_EFFECTS = [
|
||||
"Gradient",
|
||||
"Static",
|
||||
"Breathing",
|
||||
"Evolution",
|
||||
"Rainbow",
|
||||
"Wave",
|
||||
"Marquee",
|
||||
]
|
||||
|
||||
AURA_EFFECTS_MAP = {
|
||||
0: AURA_NO_EFFECT,
|
||||
1: "Gradient",
|
||||
2: "Static",
|
||||
3: "Breathing",
|
||||
4: "Evolution",
|
||||
5: "Rainbow",
|
||||
6: "Wave",
|
||||
7: "Marquee",
|
||||
}
|
||||
|
||||
SUPPORTED_COLOR_MODES = {
|
||||
0: ColorMode.ONOFF,
|
||||
1: ColorMode.RGB,
|
||||
2: ColorMode.RGB,
|
||||
3: ColorMode.RGB,
|
||||
4: ColorMode.ONOFF,
|
||||
5: ColorMode.ONOFF,
|
||||
6: ColorMode.ONOFF,
|
||||
7: ColorMode.RGB,
|
||||
}
|
||||
|
||||
ACTIVE_BRIGHTNESS = "active_brightness"
|
||||
ACTIVE_COLOR = "active_color"
|
||||
BRIGHTNESS = "brightness"
|
||||
RGB_COLOR = "rgb_color"
|
||||
SCHEME = "scheme"
|
||||
STATE = "state"
|
||||
ZONES = "zones"
|
||||
|
||||
|
||||
def aura_to_ha(data: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Convert AsusRouter Aura data to Home Assistant format."""
|
||||
|
||||
result = {
|
||||
STATE: data.get(STATE, False),
|
||||
ZONES: data.get(ZONES, 0),
|
||||
}
|
||||
|
||||
# Current active effect
|
||||
_effect = data.get(SCHEME, 0)
|
||||
result["effect"] = AURA_EFFECTS_MAP.get(_effect, AURA_NO_EFFECT)
|
||||
|
||||
# Colors
|
||||
if ACTIVE_COLOR in data:
|
||||
result[RGB_COLOR] = ColorRGBB(data[ACTIVE_COLOR], scale=255).as_tuple()
|
||||
if ACTIVE_BRIGHTNESS in data:
|
||||
result[BRIGHTNESS] = scale_value_int(
|
||||
data.get(ACTIVE_BRIGHTNESS, AURA_FALLBACK_BRIGHTNESS),
|
||||
255,
|
||||
128,
|
||||
)
|
||||
|
||||
for i in range(result["zones"]):
|
||||
color_key = f"active_{i}_color"
|
||||
brightness_key = f"active_{i}_brightness"
|
||||
if color_key in data:
|
||||
result[f"{RGB_COLOR}_{i}"] = ColorRGBB(
|
||||
data.get(color_key, AURA_FALLBACK_COLOR),
|
||||
scale=255,
|
||||
).as_tuple()
|
||||
if brightness_key in data:
|
||||
result[f"{BRIGHTNESS}_{i}"] = scale_value_int(
|
||||
data.get(brightness_key, AURA_FALLBACK_BRIGHTNESS),
|
||||
255,
|
||||
128,
|
||||
)
|
||||
|
||||
# Color mode support
|
||||
result["color_mode"] = SUPPORTED_COLOR_MODES.get(_effect, ColorMode.ONOFF)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def per_zone_light(zones: int = 3) -> list[AREntityDescription]:
|
||||
"""Create a per-zone light entity descriptions."""
|
||||
|
||||
return [
|
||||
ARLightDescription(
|
||||
key=STATE,
|
||||
key_group="aura",
|
||||
name=f"AURA Zone {i + 1}",
|
||||
icon_on=ICON_LIGHT_ON,
|
||||
icon_off=ICON_LIGHT_OFF,
|
||||
capabilities={"zone_id": i},
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
entity_registry_enabled_default=False,
|
||||
extra_state_attributes={
|
||||
f"{BRIGHTNESS}_{i}": BRIGHTNESS,
|
||||
f"{RGB_COLOR}_{i}": RGB_COLOR,
|
||||
},
|
||||
)
|
||||
for i in range(zones)
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
"""Firmware module for AsusRouter integration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
|
||||
def to_ha(data: dict[str, Any] | None) -> dict[str, Any]:
|
||||
"""Convert AsusRouter firmware data to Home Assistant format."""
|
||||
|
||||
if not data:
|
||||
return {}
|
||||
|
||||
# Current firmware
|
||||
_current = data.get("current")
|
||||
_current = str(_current) if _current else None
|
||||
|
||||
# Available stable firmware
|
||||
_latest = data.get("available")
|
||||
_latest = str(_latest) if _latest else _current
|
||||
|
||||
# Available beta firmware
|
||||
_latest_beta = data.get("available_beta")
|
||||
_latest_beta = str(_latest_beta) if _latest_beta else _current
|
||||
|
||||
return {
|
||||
"current": _current,
|
||||
"latest": _latest,
|
||||
"latest_beta": _latest_beta,
|
||||
"release_note": data.get("release_note"),
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
"""AsusRouter sensor module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
from .compilers import list_sensors_network
|
||||
from .const import CONF_INTERFACES, STATIC_SENSORS
|
||||
from .dataclass import ARSensorDescription
|
||||
from .entity import AREntity, async_setup_ar_entry
|
||||
from .router import ARDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AsusRouter sensors."""
|
||||
|
||||
sensors = STATIC_SENSORS.copy()
|
||||
|
||||
interfaces = config_entry.options.get(CONF_INTERFACES, [])
|
||||
if len(interfaces) > 0:
|
||||
_LOGGER.debug(
|
||||
"Interfaces selected: %s. Initializing sensors", interfaces
|
||||
)
|
||||
sensors.extend(
|
||||
list_sensors_network(
|
||||
config_entry.options[CONF_INTERFACES],
|
||||
)
|
||||
)
|
||||
|
||||
await async_setup_ar_entry(
|
||||
hass, config_entry, async_add_entities, sensors, ARSensor
|
||||
)
|
||||
|
||||
|
||||
class ARSensor(AREntity, SensorEntity):
|
||||
"""AsusRouter sensor."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
router: ARDevice,
|
||||
description: ARSensorDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter sensor."""
|
||||
|
||||
super().__init__(coordinator, router, description)
|
||||
self.entity_description: ARSensorDescription = description
|
||||
|
||||
@property
|
||||
def native_value(
|
||||
self,
|
||||
) -> float | str | None:
|
||||
"""Return state."""
|
||||
|
||||
description = self.entity_description
|
||||
return self.coordinator.data.get(description.key)
|
||||
@@ -0,0 +1,32 @@
|
||||
device_internet_access:
|
||||
fields:
|
||||
entities:
|
||||
required: false
|
||||
selector:
|
||||
entity:
|
||||
integration: asusrouter
|
||||
domain: device_tracker
|
||||
multiple: true
|
||||
state:
|
||||
required: true
|
||||
selector:
|
||||
select:
|
||||
translation_key: set_pc_rule
|
||||
mode: dropdown
|
||||
options:
|
||||
- "block"
|
||||
- "allow"
|
||||
- "remove"
|
||||
remove_trackers:
|
||||
name: Remove device trackers
|
||||
description: This service allows removing device_tracker entities. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.
|
||||
fields:
|
||||
entities:
|
||||
name: Entities
|
||||
description: Entities to remove
|
||||
required: true
|
||||
selector:
|
||||
entity:
|
||||
integration: asusrouter
|
||||
domain: device_tracker
|
||||
multiple: true
|
||||
@@ -0,0 +1,269 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Device location",
|
||||
"description": "How to find your device",
|
||||
"data": {
|
||||
"host": "Hostname / IP address"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"description": "The same as for the device web panel",
|
||||
"data": {
|
||||
"username": "[%key:common::config_flow::data::username%]",
|
||||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"port": "Port (0 to use default value)",
|
||||
"ssl": "Use SSL connection"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Operation mode",
|
||||
"data": {
|
||||
"mode": "Device mode",
|
||||
"enable_control": "Enable device control",
|
||||
"split_intervals": "Enable per-sensor update intervals"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "Additional options",
|
||||
"menu_options": {
|
||||
"connected_devices": "Connected devices",
|
||||
"intervals": "Update intervals",
|
||||
"interfaces": "Interfaces to monitor",
|
||||
"events": "Home Assistant events",
|
||||
"security": "Security options",
|
||||
"finish": "Save and finish"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Enable device trackers",
|
||||
"client_device": "Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "Filter clients",
|
||||
"client_filter_list": "List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "Force clients update",
|
||||
"force_clients_waittime": "Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Number of latest connected devices to store",
|
||||
"interval_devices": "Devices / AiMesh update",
|
||||
"consider_home": "Consider device at home for (after last 'online' state)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Update intervals",
|
||||
"description": "Values are in seconds",
|
||||
"data": {
|
||||
"cache_time": "Caching time",
|
||||
"scan_interval": "Entities update",
|
||||
"interval_cpu": "CPU data",
|
||||
"interval_firmware": "Firmware data",
|
||||
"interval_gwlan": "GWLAN interval",
|
||||
"interval_light": "Light data",
|
||||
"interval_misc": "Misc data",
|
||||
"interval_network": "Network stat data",
|
||||
"interval_parental_control": "Parental control data",
|
||||
"interval_ports": "Ports data",
|
||||
"interval_ram": "RAM data",
|
||||
"interval_sysinfo": "Sysinfo data",
|
||||
"interval_temperature": "Temperature data",
|
||||
"interval_vpn": "VPN data",
|
||||
"interval_wan": "WAN data",
|
||||
"interval_wlan": "WLAN data"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces to monitor",
|
||||
"data": {
|
||||
"interfaces": "Select network interfaces to monitor",
|
||||
"units_speed": "Units for speed",
|
||||
"units_traffic": "Units for traffic"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Events",
|
||||
"description": "Which events should be raised",
|
||||
"data": {
|
||||
"device_connected": "Device connected (the device was not tracked before)",
|
||||
"device_disconnected": "Device disconnected",
|
||||
"device_reconnected": "Device reconnected (this device was already tracked before)",
|
||||
"node_connected": "AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "AiMesh node disconnected",
|
||||
"node_reconnected": "AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Security",
|
||||
"data": {
|
||||
"hide_passwords": "Hide passwords from sensors and attributes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Cannot resolve hostname. Try with the IP address",
|
||||
"connection_error": "Connection error. Refer to the log for details",
|
||||
"connection_refused": "Connection refused",
|
||||
"error": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"login_blocked": "Login is blocked by the device. Please, wait",
|
||||
"password_missing": "Password is missing",
|
||||
"timeout": "Timeout error",
|
||||
"unknown": "Unknown error",
|
||||
"wrong_credentials": "Wrong credentials"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"no_serial": "This device does not provide serial number. Discovery aborted",
|
||||
"not_router": "Not an Asus router. Cannot be configured"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Configurations to change",
|
||||
"menu_options": {
|
||||
"credentials": "Credentials and connection",
|
||||
"operation": "Operation mode",
|
||||
"connected_devices": "Connected devices",
|
||||
"intervals": "Update intervals",
|
||||
"interfaces": "Interfaces to monitor",
|
||||
"events": "Home Assistant events",
|
||||
"security": "Security options",
|
||||
"finish": "Save and finish"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"description": "The same as for the device web panel",
|
||||
"data": {
|
||||
"username": "[%key:common::config_flow::data::username%]",
|
||||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"port": "Port (0 to use default value)",
|
||||
"ssl": "Use SSL connection"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Operation mode",
|
||||
"data": {
|
||||
"mode": "Device mode",
|
||||
"enable_control": "Enable device control",
|
||||
"split_intervals": "Enable per-sensor update intervals"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Enable device trackers",
|
||||
"client_device": "Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "Filter clients",
|
||||
"client_filter_list": "List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "Force clients update",
|
||||
"force_clients_waittime": "Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Number of latest connected devices to store",
|
||||
"interval_devices": "Devices / AiMesh update",
|
||||
"consider_home": "Consider device at home for (after last 'online' state)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Update intervals",
|
||||
"description": "Values are in seconds",
|
||||
"data": {
|
||||
"cache_time": "Caching time",
|
||||
"scan_interval": "Entities update",
|
||||
"interval_cpu": "CPU data",
|
||||
"interval_firmware": "Firmware data",
|
||||
"interval_gwlan": "GWLAN interval",
|
||||
"interval_light": "Light data",
|
||||
"interval_misc": "Misc data",
|
||||
"interval_network": "Network stat data",
|
||||
"interval_parental_control": "Parental control data",
|
||||
"interval_ports": "Ports data",
|
||||
"interval_ram": "RAM data",
|
||||
"interval_sysinfo": "Sysinfo data",
|
||||
"interval_temperature": "Temperature data",
|
||||
"interval_vpn": "VPN data",
|
||||
"interval_wan": "WAN data",
|
||||
"interval_wlan": "WLAN data"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces to monitor",
|
||||
"data": {
|
||||
"interfaces": "Select network interfaces to monitor",
|
||||
"units_speed": "Units for speed",
|
||||
"units_traffic": "Units for traffic"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Events",
|
||||
"description": "Which events should be raised",
|
||||
"data": {
|
||||
"device_connected": "Device connected (the device was not tracked before)",
|
||||
"device_disconnected": "Device disconnected",
|
||||
"device_reconnected": "Device reconnected (this device was already tracked before)",
|
||||
"node_connected": "AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "AiMesh node disconnected",
|
||||
"node_reconnected": "AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Security",
|
||||
"data": {
|
||||
"hide_passwords": "Hide passwords from sensors and attributes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "Access error. Refer to the log for details",
|
||||
"connection_error": "Connection error. Refer to the log for details",
|
||||
"connection_refused": "Connection refused",
|
||||
"error": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"login_blocked": "Login is blocked by the device. Please, wait",
|
||||
"not_confirmed": "You have to confirm",
|
||||
"timeout": "Timeout error",
|
||||
"unknown": "Unknown error",
|
||||
"wrong_credentials": "Wrong credentials"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
"""AsusRouter switch module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.parental_control import ParentalControlRule, PCRuleType
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
from .const import (
|
||||
ASUSROUTER,
|
||||
CONF_DEFAULT_HIDE_PASSWORDS,
|
||||
CONF_HIDE_PASSWORDS,
|
||||
DOMAIN,
|
||||
ICON_INTERNET_ACCESS_OFF,
|
||||
ICON_INTERNET_ACCESS_ON,
|
||||
STATIC_SWITCHES,
|
||||
)
|
||||
from .dataclass import ARSwitchDescription
|
||||
from .entity import ARBinaryEntity, async_setup_ar_entry
|
||||
from .helpers import to_unique_id
|
||||
from .router import ARDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AsusRouter switches."""
|
||||
|
||||
switches = STATIC_SWITCHES.copy()
|
||||
|
||||
hide = []
|
||||
if config_entry.options.get(
|
||||
CONF_HIDE_PASSWORDS, CONF_DEFAULT_HIDE_PASSWORDS
|
||||
):
|
||||
hide.extend(["password", "private_key", "psk"])
|
||||
|
||||
await async_setup_ar_entry(
|
||||
hass, config_entry, async_add_entities, switches, ARSwitch, hide
|
||||
)
|
||||
|
||||
router = hass.data[DOMAIN][config_entry.entry_id][ASUSROUTER]
|
||||
tracked: set = set()
|
||||
|
||||
@callback
|
||||
def update_router():
|
||||
"""Update the values of the router."""
|
||||
|
||||
add_entities(router, async_add_entities, tracked)
|
||||
|
||||
router.async_on_close(
|
||||
async_dispatcher_connect(
|
||||
hass, router.signal_pc_rules_new, update_router
|
||||
)
|
||||
)
|
||||
|
||||
update_router()
|
||||
|
||||
|
||||
@callback
|
||||
def add_entities(
|
||||
router: ARDevice,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
tracked: set[str],
|
||||
) -> None:
|
||||
"""Add new tracker entities from the router."""
|
||||
|
||||
new_tracked = []
|
||||
|
||||
for mac, rule in router.pc_rules.items():
|
||||
if mac in tracked:
|
||||
continue
|
||||
|
||||
new_tracked.append(ClientInternetSwitch(router, rule))
|
||||
tracked.add(mac)
|
||||
|
||||
if new_tracked:
|
||||
async_add_entities(new_tracked)
|
||||
|
||||
|
||||
class ARSwitch(ARBinaryEntity, SwitchEntity):
|
||||
"""AsusRouter switch."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
router: ARDevice,
|
||||
description: ARSwitchDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter switch."""
|
||||
|
||||
super().__init__(coordinator, router, description)
|
||||
self.entity_description: ARSwitchDescription = description
|
||||
|
||||
# State on
|
||||
self._state_on = description.state_on
|
||||
self._state_on_args = description.state_on_args
|
||||
# State off
|
||||
self._state_off = description.state_off
|
||||
self._state_off_args = description.state_off_args
|
||||
# Expect modify
|
||||
self._state_expect_modify = description.state_expect_modify
|
||||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn on switch."""
|
||||
|
||||
kwargs = self._state_on_args if self._state_on_args is not None else {}
|
||||
|
||||
await self._set_state(
|
||||
state=self._state_on,
|
||||
expect_modify=self._state_expect_modify,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
async def async_turn_off(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn off switch."""
|
||||
|
||||
kwargs = (
|
||||
self._state_off_args if self._state_off_args is not None else {}
|
||||
)
|
||||
|
||||
await self._set_state(
|
||||
state=self._state_off,
|
||||
expect_modify=self._state_expect_modify,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
class ClientInternetSwitch(SwitchEntity):
|
||||
"""Client internet switch."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
router: ARDevice,
|
||||
rule: ParentalControlRule,
|
||||
):
|
||||
"""Initialize client switch."""
|
||||
|
||||
self._router = router
|
||||
self._rule = rule
|
||||
self._mac = dr.format_mac(rule.mac)
|
||||
self._attr_unique_id = to_unique_id(
|
||||
f"{router.mac}_{self._mac}_block_internet"
|
||||
)
|
||||
self._attr_name = f"{rule.name} Block Internet"
|
||||
|
||||
# Assign device info if set up
|
||||
if router.create_devices is True:
|
||||
self._attr_device_info = self._compile_device_info()
|
||||
|
||||
def _compile_device_info(self) -> DeviceInfo:
|
||||
"""Compile device info."""
|
||||
|
||||
return DeviceInfo(
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, self._mac)},
|
||||
default_name=self._rule.name,
|
||||
via_device=(DOMAIN, self._router.mac),
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool | None:
|
||||
"""Get the state."""
|
||||
|
||||
match self._rule.type:
|
||||
case PCRuleType.BLOCK:
|
||||
return True
|
||||
case PCRuleType.DISABLE:
|
||||
return False
|
||||
case _:
|
||||
return None
|
||||
|
||||
@property
|
||||
def icon(self) -> str | None:
|
||||
"""Get the icon."""
|
||||
|
||||
if self.is_on:
|
||||
return ICON_INTERNET_ACCESS_OFF
|
||||
return ICON_INTERNET_ACCESS_ON
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return extra state attributes."""
|
||||
|
||||
return {
|
||||
"mac": self._mac,
|
||||
}
|
||||
|
||||
async def _set_state(
|
||||
self,
|
||||
state: ParentalControlRule,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Set state."""
|
||||
|
||||
try:
|
||||
_LOGGER.debug("Changing PC rule to %s", state)
|
||||
result = await self._router.bridge.api.async_set_state(
|
||||
state=state, **kwargs
|
||||
)
|
||||
self._rule = state
|
||||
if not result:
|
||||
_LOGGER.debug("State was not set!")
|
||||
except Exception as ex: # noqa: BLE001
|
||||
_LOGGER.error("Unable to set state with an exception: %s", ex)
|
||||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn on block."""
|
||||
|
||||
await self._set_state(
|
||||
state=ParentalControlRule(
|
||||
mac=self._rule.mac,
|
||||
name=self._rule.name,
|
||||
type=PCRuleType.BLOCK,
|
||||
),
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
async def async_turn_off(
|
||||
self,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn off block."""
|
||||
|
||||
await self._set_state(
|
||||
state=ParentalControlRule(
|
||||
mac=self._rule.mac,
|
||||
name=self._rule.name,
|
||||
type=PCRuleType.DISABLE,
|
||||
),
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_on_demand_update(self) -> None:
|
||||
"""Update the state."""
|
||||
|
||||
if self._rule.mac in self._router.pc_rules:
|
||||
self._rule = self._router.pc_rules[self._rule.mac]
|
||||
self.async_write_ha_state()
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register state update callback."""
|
||||
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
self._router.signal_pc_rules_update,
|
||||
self.async_on_demand_update,
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Přidat zařízení",
|
||||
"description": "Jak přidat své zařízení",
|
||||
"data": {
|
||||
"host": "Hostitel / IP addresa"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Přihlašovací údaje",
|
||||
"description": "Stejné jako pro webový panel zařízení",
|
||||
"data": {
|
||||
"username": "Uživatelské jméno",
|
||||
"password": "Heslo",
|
||||
"port": "Port (0 pro použití výchozí hodnoty)",
|
||||
"ssl": "Použít připojení SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Provozní režim",
|
||||
"data": {
|
||||
"mode": "[NT] Device mode",
|
||||
"enable_control": "Povolit ovládání zařízení",
|
||||
"split_intervals": "Povolit intervaly aktualizace pro každý senzor"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "[NT] Additional options",
|
||||
"menu_options": {
|
||||
"connected_devices": "[NT] Connected devices",
|
||||
"intervals": "Intervaly aktualizace",
|
||||
"interfaces": "Rozhraní ke sledování",
|
||||
"events": "Události Home Assistant",
|
||||
"security": "Možnosti zabezpečení",
|
||||
"finish": "[NT] Save and finish"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Povolit sledování zařízení",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Počet nejnovějších připojených zařízení k uložení",
|
||||
"interval_devices": "[NT] Devices / AiMesh update",
|
||||
"consider_home": "Považovat zařízení že je doma (po posledním 'online' stavu)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervaly aktualizace",
|
||||
"description": "Hodnoty jsou v sekundách",
|
||||
"data": {
|
||||
"cache_time": "Čas mezipaměti",
|
||||
"scan_interval": "Aktualizace entit",
|
||||
"interval_cpu": "Data CPU",
|
||||
"interval_firmware": "Data firmwaru",
|
||||
"interval_gwlan": "Interval GWLAN",
|
||||
"interval_light": "Lehká aktualizace dat",
|
||||
"interval_misc": "Různá data",
|
||||
"interval_network": "Údaje o statistikách sítě",
|
||||
"interval_parental_control": "Data rodičovské kontroly",
|
||||
"interval_ports": "Data portů",
|
||||
"interval_ram": "Data RAM",
|
||||
"interval_sysinfo": "Data systém info",
|
||||
"interval_temperature": "Údaje o teplotě",
|
||||
"interval_vpn": "Data VPN",
|
||||
"interval_wan": "Data WAN",
|
||||
"interval_wlan": "Data WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Rozhraní ke sledování",
|
||||
"data": {
|
||||
"interfaces": "Vyberte síťová rozhraní ke sledování",
|
||||
"units_speed": "Jednotky pro rychlost",
|
||||
"units_traffic": "Jednotky pro provoz"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Události",
|
||||
"description": "Které události by měly být oznámeny",
|
||||
"data": {
|
||||
"device_connected": "Zařízení připojeno (zařízení nebylo dříve sledováno)",
|
||||
"device_disconnected": "Zařízení odpojeno",
|
||||
"device_reconnected": "Zařízení bylo znovu připojeno (toto zařízení již bylo sledováno dříve)",
|
||||
"node_connected": "[NT] AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "[NT] AiMesh node disconnected",
|
||||
"node_reconnected": "[NT] AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Zabezpečení",
|
||||
"data": {
|
||||
"hide_passwords": "Skrýt hesla ze senzorů a atributů"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Nelze přeložit název hostitele. Zkuste použít IP adresu",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Připojení odmítnuto",
|
||||
"error": "Nepodařilo se připojit",
|
||||
"login_blocked": "Přihlášení je blokováno zařízením. Čekejte prosím",
|
||||
"password_missing": "Chybí heslo",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Neznámá chyba",
|
||||
"wrong_credentials": "Chybné přihlašovací údaje"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[NT] Device is already configured",
|
||||
"no_serial": "[NT] This device does not provide serial number. Discovery aborted",
|
||||
"not_router": "[NT] Not an Asus router. Cannot be configured"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Změnit konfiguraci",
|
||||
"menu_options": {
|
||||
"credentials": "Přihlašovací údaje a nastavení připojení",
|
||||
"operation": "Provozní režim",
|
||||
"connected_devices": "[NT] Connected devices",
|
||||
"intervals": "Intervaly aktualizace",
|
||||
"interfaces": "Rozhraní ke sledování",
|
||||
"events": "Události Home Assistant",
|
||||
"security": "Možnosti zabezpečení",
|
||||
"finish": "[NT] Save and finish",
|
||||
"device": "Identifikační a spojovací parametry"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Přihlašovací údaje",
|
||||
"description": "Stejné jako pro webový panel zařízení",
|
||||
"data": {
|
||||
"username": "Uživatelské jméno",
|
||||
"password": "Heslo",
|
||||
"port": "Port (0 pro použití výchozí hodnoty)",
|
||||
"ssl": "Použít připojení SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Provozní režim",
|
||||
"data": {
|
||||
"mode": "[NT] Device mode",
|
||||
"enable_control": "Povolit ovládání zařízení",
|
||||
"split_intervals": "Povolit intervaly aktualizace pro každý senzor"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Povolit sledování zařízení",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Počet nejnovějších připojených zařízení k uložení",
|
||||
"interval_devices": "[NT] Devices / AiMesh update",
|
||||
"consider_home": "Považovat zařízení že je doma (po posledním 'online' stavu)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervaly aktualizace",
|
||||
"description": "Hodnoty jsou v sekundách",
|
||||
"data": {
|
||||
"cache_time": "Čas mezipaměti",
|
||||
"scan_interval": "Aktualizace entit",
|
||||
"interval_cpu": "Data CPU",
|
||||
"interval_firmware": "Data firmwaru",
|
||||
"interval_gwlan": "Interval GWLAN",
|
||||
"interval_light": "Lehká aktualizace dat",
|
||||
"interval_misc": "Různá data",
|
||||
"interval_network": "Údaje o statistikách sítě",
|
||||
"interval_parental_control": "Data rodičovské kontroly",
|
||||
"interval_ports": "Data portů",
|
||||
"interval_ram": "Data RAM",
|
||||
"interval_sysinfo": "Data systém info",
|
||||
"interval_temperature": "Údaje o teplotě",
|
||||
"interval_vpn": "Data VPN",
|
||||
"interval_wan": "Data WAN",
|
||||
"interval_wlan": "Data WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Rozhraní ke sledování",
|
||||
"data": {
|
||||
"interfaces": "Vyberte síťová rozhraní ke sledování",
|
||||
"units_speed": "Jednotky pro rychlost",
|
||||
"units_traffic": "Jednotky pro provoz"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Události",
|
||||
"description": "Které události by měly být oznámeny",
|
||||
"data": {
|
||||
"device_connected": "Zařízení připojeno (zařízení nebylo dříve sledováno)",
|
||||
"device_disconnected": "Zařízení odpojeno",
|
||||
"device_reconnected": "Zařízení bylo znovu připojeno (toto zařízení již bylo sledováno dříve)",
|
||||
"node_connected": "[NT] AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "[NT] AiMesh node disconnected",
|
||||
"node_reconnected": "[NT] AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Zabezpečení",
|
||||
"data": {
|
||||
"hide_passwords": "Skrýt hesla ze senzorů a atributů"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Připojení odmítnuto",
|
||||
"error": "Nepodařilo se připojit",
|
||||
"login_blocked": "Přihlášení je blokováno zařízením. Čekejte prosím",
|
||||
"not_confirmed": "Nepotvrzeno",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Neznámá chyba",
|
||||
"wrong_credentials": "Chybné přihlašovací údaje"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Gerätestandort",
|
||||
"description": "So finden Sie Ihr Gerät",
|
||||
"data": {
|
||||
"host": "Hostname / IP-Adresse"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Referenzen",
|
||||
"description": "Dasselbe wie für das Geräte-Webpanel",
|
||||
"data": {
|
||||
"username": "Nutzername",
|
||||
"password": "Passwort",
|
||||
"port": "Port (0, um den Standardwert zu verwenden)",
|
||||
"ssl": "Verwenden Sie eine SSL-Verbindung"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Betriebsmodus",
|
||||
"data": {
|
||||
"mode": "Gerätemodus",
|
||||
"enable_control": "Aktivieren Sie die Gerätesteuerung",
|
||||
"split_intervals": "Aktivieren Sie Aktualisierungsintervalle pro Sensor"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "Zusatzoptionen",
|
||||
"menu_options": {
|
||||
"connected_devices": "Verbundene Geräte",
|
||||
"intervals": "Aktualisierungsintervalle",
|
||||
"interfaces": "Zu überwachende Schnittstellen",
|
||||
"events": "Home Assistant-Ereignisse",
|
||||
"security": "Sicherheitsoptionen",
|
||||
"finish": "Speichern und fertig"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Verbundene Geräte",
|
||||
"data": {
|
||||
"track_devices": "Geräte-Tracker aktivieren",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Anzahl der zuletzt verbundenen Geräte, die gespeichert werden sollen",
|
||||
"interval_devices": "Geräte / AiMesh-Update",
|
||||
"consider_home": "Betrachten Sie das Gerät zu Hause für (nach dem letzten „Online“-Zustand)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Aktualisierungsintervalle",
|
||||
"description": "Die Werte sind in Sekunden",
|
||||
"data": {
|
||||
"cache_time": "Caching-Zeit",
|
||||
"scan_interval": "Aktualisierung der Entitäten",
|
||||
"interval_cpu": "CPU-Daten",
|
||||
"interval_firmware": "Firmware-Daten",
|
||||
"interval_gwlan": "GWLAN-Intervall",
|
||||
"interval_light": "Lichtdaten",
|
||||
"interval_misc": "Verschiedene Daten",
|
||||
"interval_network": "Netzwerkstatistikdaten",
|
||||
"interval_parental_control": "Daten der Kindersicherung",
|
||||
"interval_ports": "Portdaten",
|
||||
"interval_ram": "RAM-Daten",
|
||||
"interval_sysinfo": "Sysinfo-Daten",
|
||||
"interval_temperature": "Temperaturdaten",
|
||||
"interval_vpn": "VPN-Daten",
|
||||
"interval_wan": "WAN-Daten",
|
||||
"interval_wlan": "WLAN-Daten"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Zu überwachende Schnittstellen",
|
||||
"data": {
|
||||
"interfaces": "Wählen Sie die zu überwachenden Netzwerkschnittstellen aus",
|
||||
"units_speed": "Einheiten für Geschwindigkeit",
|
||||
"units_traffic": "Einheiten für den Verkehr"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Events",
|
||||
"description": "Welche Ereignisse sollten ausgelöst werden",
|
||||
"data": {
|
||||
"device_connected": "Gerät verbunden (das Gerät wurde zuvor nicht getrackt)",
|
||||
"device_disconnected": "Gerät getrennt",
|
||||
"device_reconnected": "Gerät neu verbunden (dieses Gerät wurde bereits zuvor getrackt)",
|
||||
"node_connected": "AiMesh-Knoten verbunden (noch nie zuvor gesehen)",
|
||||
"node_disconnected": "AiMesh-Knoten getrennt",
|
||||
"node_reconnected": "AiMesh-Knoten wieder verbunden"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Sicherheit",
|
||||
"data": {
|
||||
"hide_passwords": "Passwörter vor Sensoren und Attributen verbergen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Kann den Hostnamen nicht auflösen. Versuchen Sie es mit der IP-Adresse",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Verbindung abgelehnt",
|
||||
"error": "Verbindung nicht möglich",
|
||||
"login_blocked": "Die Anmeldung wird vom Gerät blockiert. Warten Sie",
|
||||
"password_missing": "Passwort fehlt",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Unbekannter Fehler",
|
||||
"wrong_credentials": "Falsche Anmeldeinformationen"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "Gerät ist bereits konfiguriert",
|
||||
"no_serial": "Dieses Gerät gibt keine Seriennummer an. Erkennung abgebrochen",
|
||||
"not_router": "Kein Asus-Router. Kann nicht konfiguriert werden"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Konfigurationen zu ändern",
|
||||
"menu_options": {
|
||||
"credentials": "Anmeldeinformationen und Verbindung",
|
||||
"operation": "Betriebsmodus",
|
||||
"connected_devices": "Verbundene Geräte",
|
||||
"intervals": "Aktualisierungsintervalle",
|
||||
"interfaces": "Zu überwachende Schnittstellen",
|
||||
"events": "Home Assistant-Ereignisse",
|
||||
"security": "Sicherheitsoptionen",
|
||||
"finish": "Speichern und fertig",
|
||||
"device": "Identifikations- und Verbindungsparameter"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Referenzen",
|
||||
"description": "Dasselbe wie für das Geräte-Webpanel",
|
||||
"data": {
|
||||
"username": "Nutzername",
|
||||
"password": "Passwort",
|
||||
"port": "Port (0, um den Standardwert zu verwenden)",
|
||||
"ssl": "Verwenden Sie eine SSL-Verbindung"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Betriebsmodus",
|
||||
"data": {
|
||||
"mode": "Gerätemodus",
|
||||
"enable_control": "Aktivieren Sie die Gerätesteuerung",
|
||||
"split_intervals": "Aktivieren Sie Aktualisierungsintervalle pro Sensor"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Verbundene Geräte",
|
||||
"data": {
|
||||
"track_devices": "Geräte-Tracker aktivieren",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Anzahl der zuletzt verbundenen Geräte, die gespeichert werden sollen",
|
||||
"interval_devices": "Geräte / AiMesh-Update",
|
||||
"consider_home": "Betrachten Sie das Gerät zu Hause für (nach dem letzten „Online“-Zustand)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Aktualisierungsintervalle",
|
||||
"description": "Die Werte sind in Sekunden",
|
||||
"data": {
|
||||
"cache_time": "Caching-Zeit",
|
||||
"scan_interval": "Aktualisierung der Entitäten",
|
||||
"interval_cpu": "CPU-Daten",
|
||||
"interval_firmware": "Firmware-Daten",
|
||||
"interval_gwlan": "GWLAN-Intervall",
|
||||
"interval_light": "Lichtdaten",
|
||||
"interval_misc": "Verschiedene Daten",
|
||||
"interval_network": "Netzwerkstatistikdaten",
|
||||
"interval_wlan": "WLAN-Daten",
|
||||
"interval_wan": "WAN-Daten",
|
||||
"interval_vpn": "VPN-Daten",
|
||||
"interval_temperature": "Temperaturdaten",
|
||||
"interval_sysinfo": "Sysinfo-Daten",
|
||||
"interval_ram": "RAM-Daten",
|
||||
"interval_ports": "Portdaten",
|
||||
"interval_parental_control": "Daten der Kindersicherung"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"data": {
|
||||
"interfaces": "Wählen Sie die zu überwachenden Netzwerkschnittstellen aus",
|
||||
"units_speed": "Einheiten für Geschwindigkeit",
|
||||
"units_traffic": "Einheiten für den Verkehr"
|
||||
},
|
||||
"title": "Zu überwachende Schnittstellen"
|
||||
},
|
||||
"events": {
|
||||
"title": "Veranstaltungen",
|
||||
"description": "Welche Ereignisse sollten ausgelöst werden",
|
||||
"data": {
|
||||
"device_connected": "Gerät verbunden (das Gerät wurde zuvor nicht getrackt)",
|
||||
"device_disconnected": "Gerät getrennt",
|
||||
"device_reconnected": "Gerät neu verbunden (dieses Gerät wurde bereits zuvor getrackt)",
|
||||
"node_connected": "AiMesh-Knoten verbunden (noch nie zuvor gesehen)",
|
||||
"node_disconnected": "AiMesh-Knoten getrennt",
|
||||
"node_reconnected": "AiMesh-Knoten wieder verbunden"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Sicherheit",
|
||||
"data": {
|
||||
"hide_passwords": "Passwörter vor Sensoren und Attributen verbergen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Verbindung abgelehnt",
|
||||
"error": "Verbindung nicht möglich",
|
||||
"login_blocked": "Die Anmeldung wird vom Gerät blockiert. Warten Sie mal",
|
||||
"not_confirmed": "Sie müssen bestätigen",
|
||||
"timeout": "[NT] Timeout error"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Device location",
|
||||
"description": "How to find your device",
|
||||
"data": {
|
||||
"host": "Hostname / IP address"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"description": "The same as for the device web panel",
|
||||
"data": {
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"port": "Port (0 to use default value)",
|
||||
"ssl": "Use SSL connection"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Operation mode",
|
||||
"data": {
|
||||
"mode": "Device mode",
|
||||
"enable_control": "Enable device control",
|
||||
"split_intervals": "Enable per-sensor update intervals"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "Additional options",
|
||||
"menu_options": {
|
||||
"connected_devices": "Connected devices",
|
||||
"intervals": "Update intervals",
|
||||
"interfaces": "Interfaces to monitor",
|
||||
"events": "Home Assistant events",
|
||||
"security": "Security options",
|
||||
"finish": "Save and finish"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Enable device trackers",
|
||||
"client_device": "Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "Filter clients",
|
||||
"client_filter_list": "List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "Force clients update",
|
||||
"force_clients_waittime": "Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Number of latest connected devices to store",
|
||||
"interval_devices": "Devices / AiMesh update",
|
||||
"consider_home": "Consider device at home for (after last 'online' state)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Update intervals",
|
||||
"description": "Values are in seconds",
|
||||
"data": {
|
||||
"cache_time": "Caching time",
|
||||
"scan_interval": "Entities update",
|
||||
"interval_cpu": "CPU data",
|
||||
"interval_firmware": "Firmware data",
|
||||
"interval_gwlan": "GWLAN interval",
|
||||
"interval_light": "Light data",
|
||||
"interval_misc": "Misc data",
|
||||
"interval_network": "Network stat data",
|
||||
"interval_parental_control": "Parental control data",
|
||||
"interval_ports": "Ports data",
|
||||
"interval_ram": "RAM data",
|
||||
"interval_sysinfo": "Sysinfo data",
|
||||
"interval_temperature": "Temperature data",
|
||||
"interval_vpn": "VPN data",
|
||||
"interval_wan": "WAN data",
|
||||
"interval_wlan": "WLAN data"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces to monitor",
|
||||
"data": {
|
||||
"interfaces": "Select network interfaces to monitor",
|
||||
"units_speed": "Units for speed",
|
||||
"units_traffic": "Units for traffic"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Events",
|
||||
"description": "Which events should be raised",
|
||||
"data": {
|
||||
"device_connected": "Device connected (the device was not tracked before)",
|
||||
"device_disconnected": "Device disconnected",
|
||||
"device_reconnected": "Device reconnected (this device was already tracked before)",
|
||||
"node_connected": "AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "AiMesh node disconnected",
|
||||
"node_reconnected": "AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Security",
|
||||
"data": {
|
||||
"hide_passwords": "Hide passwords from sensors and attributes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Cannot resolve hostname. Try with the IP address",
|
||||
"connection_error": "Connection error. Refer to the log for details",
|
||||
"connection_refused": "Connection refused",
|
||||
"error": "Failed to connect",
|
||||
"login_blocked": "Login is blocked by the device. Please, wait",
|
||||
"password_missing": "Password is missing",
|
||||
"timeout": "Timeout error",
|
||||
"unknown": "Unknown error",
|
||||
"wrong_credentials": "Wrong credentials"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "Device is already configured",
|
||||
"no_serial": "This device does not provide serial number. Discovery aborted",
|
||||
"not_router": "Not an Asus router. Cannot be configured"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Configurations to change",
|
||||
"menu_options": {
|
||||
"credentials": "Credentials and connection",
|
||||
"operation": "Operation mode",
|
||||
"connected_devices": "Connected devices",
|
||||
"intervals": "Update intervals",
|
||||
"interfaces": "Interfaces to monitor",
|
||||
"events": "Home Assistant events",
|
||||
"security": "Security options",
|
||||
"finish": "Save and finish",
|
||||
"device": "Identification and connection parameters"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credentials",
|
||||
"description": "The same as for the device web panel",
|
||||
"data": {
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"port": "Port (0 to use default value)",
|
||||
"ssl": "Use SSL connection"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Operation mode",
|
||||
"data": {
|
||||
"mode": "Device mode",
|
||||
"enable_control": "Enable device control",
|
||||
"split_intervals": "Enable per-sensor update intervals"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Enable device trackers",
|
||||
"client_device": "Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "Filter clients",
|
||||
"client_filter_list": "List of clients to filter",
|
||||
"force_clients": "Force clients update",
|
||||
"force_clients_waittime": "Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Number of latest connected devices to store",
|
||||
"interval_devices": "Devices / AiMesh update",
|
||||
"consider_home": "Consider device at home for (after last 'online' state)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Update intervals",
|
||||
"description": "Values are in seconds",
|
||||
"data": {
|
||||
"cache_time": "Caching time",
|
||||
"scan_interval": "Entities update",
|
||||
"interval_cpu": "CPU data",
|
||||
"interval_firmware": "Firmware data",
|
||||
"interval_gwlan": "GWLAN interval",
|
||||
"interval_light": "Light data",
|
||||
"interval_misc": "Misc data",
|
||||
"interval_network": "Network stat data",
|
||||
"interval_parental_control": "Parental control data",
|
||||
"interval_ports": "Ports data",
|
||||
"interval_ram": "RAM data",
|
||||
"interval_sysinfo": "Sysinfo data",
|
||||
"interval_temperature": "Temperature data",
|
||||
"interval_vpn": "VPN data",
|
||||
"interval_wan": "WAN data",
|
||||
"interval_wlan": "WLAN data"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces to monitor",
|
||||
"data": {
|
||||
"interfaces": "Select network interfaces to monitor",
|
||||
"units_speed": "Units for speed",
|
||||
"units_traffic": "Units for traffic"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Events",
|
||||
"description": "Which events should be raised",
|
||||
"data": {
|
||||
"device_connected": "Device connected (the device was not tracked before)",
|
||||
"device_disconnected": "Device disconnected",
|
||||
"device_reconnected": "Device reconnected (this device was already tracked before)",
|
||||
"node_connected": "AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "AiMesh node disconnected",
|
||||
"node_reconnected": "AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Security",
|
||||
"data": {
|
||||
"hide_passwords": "Hide passwords from sensors and attributes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "Access error. Refer to the log for details",
|
||||
"connection_error": "Connection error. Refer to the log for details",
|
||||
"connection_refused": "Connection refused",
|
||||
"error": "Failed to connect",
|
||||
"login_blocked": "Login is blocked by the device. Please, wait",
|
||||
"not_confirmed": "You have to confirm",
|
||||
"timeout": "Timeout error",
|
||||
"unknown": "Unknown error",
|
||||
"wrong_credentials": "Wrong credentials"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Localizar dispositivo",
|
||||
"description": "Cómo encontrar tu dispositivo",
|
||||
"data": {
|
||||
"host": "Nombre de equipo / Dirección IP"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credenciales",
|
||||
"description": "Los mismos que en la interfaz Web",
|
||||
"data": {
|
||||
"username": "Usuario",
|
||||
"password": "Contraseña",
|
||||
"port": "Puerto (0 para usar el valor por defecto)",
|
||||
"ssl": "Usar conexión SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Modo de funcionamiento",
|
||||
"data": {
|
||||
"mode": "Modo de dispositivo",
|
||||
"enable_control": "Habilitar control del dispositivo",
|
||||
"split_intervals": "Habilitar intervalos de actualización por sensor"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "Opciones adicionales",
|
||||
"menu_options": {
|
||||
"connected_devices": "Dispositivos conectados",
|
||||
"intervals": "Intervalos de actualización",
|
||||
"interfaces": "Interfaces a monitorizar",
|
||||
"events": "Eventos Home Assistant",
|
||||
"security": "Opciones de seguridad",
|
||||
"finish": "Guardar y finalizar"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Dispositivos conectados",
|
||||
"data": {
|
||||
"track_devices": "Habilitar rastreadores de dispositivo",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Número de dispositivos más recientes a almacenar",
|
||||
"interval_devices": "Actualización del dispositivo / AiMesh",
|
||||
"consider_home": "Considerar dispositivo en casa durante (tras el último estado 'online')",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervalos de actualización",
|
||||
"description": "Los valores se indican en segundos",
|
||||
"data": {
|
||||
"cache_time": "Tiempo de caché para los datos del dispositivo",
|
||||
"scan_interval": "Intervalo para actualizar entidades",
|
||||
"interval_cpu": "Datos CPU",
|
||||
"interval_firmware": "Datos firmware",
|
||||
"interval_gwlan": "Datos GWLAN",
|
||||
"interval_light": "Datos luces",
|
||||
"interval_misc": "Datos miscelánea",
|
||||
"interval_network": "Datos estadísticas de red",
|
||||
"interval_parental_control": "Datos de control parental",
|
||||
"interval_ports": "Datos de puertos",
|
||||
"interval_ram": "Datos RAM",
|
||||
"interval_sysinfo": "Datos de sistema",
|
||||
"interval_temperature": "Datos de temperatura",
|
||||
"interval_vpn": "Datos VPN",
|
||||
"interval_wan": "Datos WAN",
|
||||
"interval_wlan": "Datos WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces a monitorizar",
|
||||
"data": {
|
||||
"interfaces": "Seleccionar interfaces de red para monitorizar",
|
||||
"units_speed": "Unidad de velocidad",
|
||||
"units_traffic": "Unidad de tráfico"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Eventos",
|
||||
"description": "Qué eventos deben ser disparados",
|
||||
"data": {
|
||||
"device_connected": "Dispositivo conectado (el dispositivo no fue rastreado previamente)",
|
||||
"device_disconnected": "Dispositivo desconectado",
|
||||
"device_reconnected": "Dispositivo reconectado (el dispositivo ya fue rastreado previamente)",
|
||||
"node_connected": "Nodo AiMesh conectado (el dispositivo no fue rastreado previamente)",
|
||||
"node_disconnected": "Nodo AiMesh desconectado",
|
||||
"node_reconnected": "Nodo AiMesh reconectado"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Seguridad",
|
||||
"data": {
|
||||
"hide_passwords": "Ocultar contraseñas de sensores y atributos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "No se puede encontrar el nombre del equipo. Intenta con la dirección IP",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Conexión rechazada",
|
||||
"error": "Fallo al conectar",
|
||||
"login_blocked": "Login bloqueado por el dispositivo. Por favor, espera",
|
||||
"password_missing": "Falta la contraseña",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Error desconocido",
|
||||
"wrong_credentials": "Credenciales inválidos"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "El dispositivo ya está configurado",
|
||||
"no_serial": "Este dispositivo no provee un número de serie. Cancelado descubrimiento",
|
||||
"not_router": "No es un router Asus. No puede ser configurado"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Opciones a cambiar",
|
||||
"menu_options": {
|
||||
"credentials": "Credenciales y configuración de conexión",
|
||||
"operation": "Modo de funcionamiento",
|
||||
"connected_devices": "Dispositivos conectados",
|
||||
"intervals": "Intervalos de actualización",
|
||||
"interfaces": "Interfaces a monitorizar",
|
||||
"events": "Eventos Home Assistant",
|
||||
"security": "Opciones de seguridad",
|
||||
"finish": "Guardar y finalizar",
|
||||
"device": "Parámetros de identificación y conexión"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credenciales",
|
||||
"description": "Los mismos que en la interfaz Web",
|
||||
"data": {
|
||||
"username": "Usuario",
|
||||
"password": "Contraseña",
|
||||
"port": "Puerto (0 para usar el valor por defecto)",
|
||||
"ssl": "Usar conexión SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Modo de funcionamiento",
|
||||
"data": {
|
||||
"mode": "Modo de dispositivo",
|
||||
"enable_control": "Habilitar control del dispositivo",
|
||||
"split_intervals": "Habilitar intervalos de actualización por sensor"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Habilitar rastreadores de dispositivo",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Número de dispositivos más recientes a almacenar",
|
||||
"interval_devices": "Actualización del dispositivo / AiMesh",
|
||||
"consider_home": "Considerar dispositivo en casa durante (tras el último estado 'online')",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervalos de actualización",
|
||||
"description": "Los valores se indican en segundos",
|
||||
"data": {
|
||||
"cache_time": "Tiempo de caché para los datos del dispositivo",
|
||||
"scan_interval": "Intervalo para actualizar entidades",
|
||||
"interval_cpu": "Datos CPU",
|
||||
"interval_firmware": "Datos firmware",
|
||||
"interval_gwlan": "Datos GWLAN",
|
||||
"interval_light": "Datos luces",
|
||||
"interval_misc": "Datos miscelánea",
|
||||
"interval_network": "Datos estadísticas de red",
|
||||
"interval_parental_control": "Datos de control parental",
|
||||
"interval_ports": "Datos de puertos",
|
||||
"interval_ram": "Datos RAM",
|
||||
"interval_sysinfo": "Datos de sistema",
|
||||
"interval_temperature": "Datos de temperatura",
|
||||
"interval_vpn": "Datos VPN",
|
||||
"interval_wan": "Datos WAN",
|
||||
"interval_wlan": "Datos WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces a monitorizar",
|
||||
"data": {
|
||||
"interfaces": "Seleccionar interfaces de red para monitorizar",
|
||||
"units_speed": "Unidad de velocidad",
|
||||
"units_traffic": "Unidad de tráfico"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Eventos",
|
||||
"description": "Qué eventos deben ser disparados",
|
||||
"data": {
|
||||
"device_connected": "Dispositivo conectado (el dispositivo no fue rastreado previamente)",
|
||||
"device_disconnected": "Dispositivo desconectado",
|
||||
"device_reconnected": "Dispositivo reconectado (el dispositivo ya fue rastreado previamente)",
|
||||
"node_connected": "Nodo AiMesh conectado (el dispositivo no fue rastreado previamente)",
|
||||
"node_disconnected": "Nodo AiMesh desconectado",
|
||||
"node_reconnected": "Nodo AiMesh reconectado"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Seguridad",
|
||||
"data": {
|
||||
"hide_passwords": "Ocultar contraseñas de sensores y atributos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Conexión rechazada",
|
||||
"error": "Fallo al conectar",
|
||||
"login_blocked": "Login bloqueado por el dispositivo. Por favor, espera",
|
||||
"not_confirmed": "Tienes que confirmar",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Error desconocido",
|
||||
"wrong_credentials": "Credenciales inválidos"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Emplacement de l'appareil",
|
||||
"description": "Comment retrouver votre appareil",
|
||||
"data": {
|
||||
"host": "Nom d'hôte / Addresse IP "
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Identifiants",
|
||||
"description": "Les même que sur l'interface de gestion du routeur",
|
||||
"data": {
|
||||
"username": "Nom d'utilisateur",
|
||||
"password": "Mot de pass",
|
||||
"port": "Port (0 pour utiliser la valeur par défaut)",
|
||||
"ssl": "Utiliser une connexion SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Mode de fonctionnement",
|
||||
"data": {
|
||||
"mode": "Mode de l'appareil",
|
||||
"enable_control": "Activer le contrôle des périphériques",
|
||||
"split_intervals": "Activer les intervalles de mise à jour par capteur"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "[NT] Additional options",
|
||||
"menu_options": {
|
||||
"connected_devices": "[NT] Connected devices",
|
||||
"intervals": "Intervalles d'actualisation",
|
||||
"interfaces": "Interfaces à monitorer",
|
||||
"events": "Événements de Home Assistant",
|
||||
"security": "Options de sécurité",
|
||||
"finish": "[NT] Save and finish"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Activer le suivis des périphériques",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Nombre d'appareils connectés les plus récents à stocker",
|
||||
"interval_devices": "[NT] Devices / AiMesh update",
|
||||
"consider_home": "Considérez l'appareil à la maison pour (après le dernier état « en ligne »)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervalles d'actualisation",
|
||||
"description": "Les valeurs sont en secondes",
|
||||
"data": {
|
||||
"cache_time": "Temps de mise en cache",
|
||||
"scan_interval": "Intervalles d'actualisation des entités",
|
||||
"interval_cpu": "Données CPU",
|
||||
"interval_firmware": "Données du micrologiciel",
|
||||
"interval_gwlan": "Intervalle GWLAN",
|
||||
"interval_light": "État des LED",
|
||||
"interval_misc": "Réglages divers",
|
||||
"interval_network": "Données statistiques du réseau",
|
||||
"interval_parental_control": "Données de contrôle parental",
|
||||
"interval_ports": "Données des Ports",
|
||||
"interval_ram": "Données RAM",
|
||||
"interval_sysinfo": "Données Sysinfo",
|
||||
"interval_temperature": "Température",
|
||||
"interval_vpn": "Données VPN",
|
||||
"interval_wan": "Données WAN",
|
||||
"interval_wlan": "Données WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces à monitorer",
|
||||
"data": {
|
||||
"interfaces": "Sélection des interfaces réseau à monitorer",
|
||||
"units_speed": "Unités de mesure de vitesse",
|
||||
"units_traffic": "Unités de mesure du trafic"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Événements",
|
||||
"description": "Quels événements doivent être déclenchés ?",
|
||||
"data": {
|
||||
"device_connected": "Périphérique connecté (l'appareil n'a pas été suivi auparavant)",
|
||||
"device_disconnected": "Périphérique déconnecté",
|
||||
"device_reconnected": "Périphérique reconnecté (cet appareil était déjà suivi auparavant)",
|
||||
"node_connected": "Node AiMesh connecté (l'appareil n'a pas été suivi auparavant)",
|
||||
"node_disconnected": "Node AiMesh déconnecté",
|
||||
"node_reconnected": "Node AiMesh reconnecté"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Securitée",
|
||||
"data": {
|
||||
"hide_passwords": "Masquer les mots de passe des capteurs et attributs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Impossible de résoudre le nom d'hôte. Essayez avec l'adresse IP",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Connexion rejetée",
|
||||
"error": "Échec de connexion",
|
||||
"login_blocked": "La connexion est bloquée par le routeur. Veuillez patienter",
|
||||
"password_missing": "Mot de passe manquant",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Erreur inconnue",
|
||||
"wrong_credentials": "Identifiants erronés"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[NT] Device is already configured",
|
||||
"no_serial": "[NT] This device does not provide serial number. Discovery aborted",
|
||||
"not_router": "[NT] Not an Asus router. Cannot be configured"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Paramétrages à changer",
|
||||
"menu_options": {
|
||||
"device": "Paramètres d'identification et de connexion",
|
||||
"operation": "Mode de fonctionnement",
|
||||
"connected_devices": "[NT] Connected devices",
|
||||
"intervals": "Intervalles d'actualisation",
|
||||
"interfaces": "Interfaces à monitorer",
|
||||
"events": "Événements de Home Assistant",
|
||||
"security": "Options de sécurité",
|
||||
"finish": "[NT] Save and finish",
|
||||
"credentials": "Identifiants et connexion"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Identifiants",
|
||||
"description": "Les même que sur l'interface de gestion du routeur",
|
||||
"data": {
|
||||
"username": "Nom d'utilisateur",
|
||||
"password": "Mot de pass",
|
||||
"port": "Port (0 pour utiliser la valeur par défaut)",
|
||||
"ssl": "Utiliser une connexion SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Mode de fonctionnement",
|
||||
"data": {
|
||||
"mode": "Mode de l'appareil",
|
||||
"enable_control": "Activer le contrôle des périphériques",
|
||||
"split_intervals": "Activer les intervalles de mise à jour par capteur"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Activer le suivis des périphériques",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Nombre d'appareils connectés les plus récents à stocker",
|
||||
"interval_devices": "[NT] Devices / AiMesh update",
|
||||
"consider_home": "Considérez l'appareil à la maison pour (après le dernier état « en ligne »)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervalles d'actualisation",
|
||||
"description": "Les valeurs sont en secondes",
|
||||
"data": {
|
||||
"cache_time": "Temps de mise en cache",
|
||||
"scan_interval": "Intervalles d'actualisation des entités",
|
||||
"interval_cpu": "Données CPU",
|
||||
"interval_firmware": "Données du micrologiciel",
|
||||
"interval_gwlan": "Intervalle GWLAN",
|
||||
"interval_light": "État des LED",
|
||||
"interval_misc": "Réglages divers",
|
||||
"interval_network": "Données statistiques du réseau",
|
||||
"interval_parental_control": "Données de contrôle parental",
|
||||
"interval_ports": "Données des Ports",
|
||||
"interval_ram": "Données RAM",
|
||||
"interval_sysinfo": "Données Sysinfo",
|
||||
"interval_temperature": "Température",
|
||||
"interval_vpn": "Données VPN",
|
||||
"interval_wan": "Données WAN",
|
||||
"interval_wlan": "Données WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces à monitorer",
|
||||
"data": {
|
||||
"interfaces": "Sélection des interfaces réseau à monitorer",
|
||||
"units_speed": "Unités de mesure de vitesse",
|
||||
"units_traffic": "Unités de mesure du trafic"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Événements",
|
||||
"description": "Quels événements doivent être déclenchés ?",
|
||||
"data": {
|
||||
"device_connected": "Périphérique connecté (l'appareil n'a pas été suivi auparavant)",
|
||||
"device_disconnected": "Périphérique déconnecté",
|
||||
"device_reconnected": "Périphérique reconnecté (cet appareil était déjà suivi auparavant)",
|
||||
"node_connected": "Node AiMesh connecté (l'appareil n'a pas été suivi auparavant)",
|
||||
"node_disconnected": "Node AiMesh déconnecté",
|
||||
"node_reconnected": "Node AiMesh reconnecté"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Securitée",
|
||||
"data": {
|
||||
"hide_passwords": "Masquer les mots de passe des capteurs et des attributs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Connexion rejetée",
|
||||
"error": "Échec de connexion",
|
||||
"login_blocked": "La connexion est bloquée par le routeur, merci de patienter",
|
||||
"not_confirmed": "Vous devez confirmer",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Erreur inconnue",
|
||||
"wrong_credentials": "Identifiants erronés"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Az eszköz helye",
|
||||
"description": "Hogyan található meg készüléke",
|
||||
"data": {
|
||||
"host": "Gazdanév / IP-cím"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Hitelesítő adatok",
|
||||
"description": "Ugyanaz, mint az eszköz webes felületén",
|
||||
"data": {
|
||||
"username": "Felhasználónév",
|
||||
"password": "Jelszó",
|
||||
"port": "Port (0 az alapértelmezett érték használatához)",
|
||||
"ssl": "SSL kapcsolat használata"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Üzemmód",
|
||||
"data": {
|
||||
"mode": "Eszköz mód",
|
||||
"enable_control": "Eszközvezérlés engedélyezése",
|
||||
"split_intervals": "Érzékelőnkénti frissítési időközök engedélyezése"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "További beállítások",
|
||||
"menu_options": {
|
||||
"connected_devices": "Csatlakoztatott eszközök",
|
||||
"intervals": "Frissítési időközök",
|
||||
"interfaces": "Interfészek a monitorozáshoz",
|
||||
"events": "Home Assistant események",
|
||||
"security": "Biztonsági beállítások",
|
||||
"finish": "Mentés és bezárás"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Csatlakoztatott eszközök",
|
||||
"data": {
|
||||
"track_devices": "Eszközkövetők engedélyezése",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "A legutóbb csatlakoztatott eszközök tárolásának maximális száma",
|
||||
"interval_devices": "Eszközök / AiMesh frissítés",
|
||||
"consider_home": "Otthon van az eszköz (az utolsó „online” állapot utáni megállapítás)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Frissítési időközök",
|
||||
"description": "Az értékek másodpercben vannak megadva",
|
||||
"data": {
|
||||
"cache_time": "Gyorsítótárazási idő",
|
||||
"scan_interval": "Az entitások frissítése",
|
||||
"interval_cpu": "CPU adatok",
|
||||
"interval_firmware": "Firmware adatok",
|
||||
"interval_gwlan": "GWLAN intervallum",
|
||||
"interval_light": "LED adatok",
|
||||
"interval_misc": "Egyéb adatok",
|
||||
"interval_network": "Hálózati statisztikai adatok",
|
||||
"interval_parental_control": "Szülői felügyeleti adatok",
|
||||
"interval_ports": "Portok adatai",
|
||||
"interval_ram": "RAM adatok",
|
||||
"interval_sysinfo": "Rendszerinfo adatok",
|
||||
"interval_temperature": "Hőmérséklet adatok",
|
||||
"interval_vpn": "VPN adat",
|
||||
"interval_wan": "WAN adat",
|
||||
"interval_wlan": "WLAN adat"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfészek a monitorozáshoz",
|
||||
"data": {
|
||||
"interfaces": "Válassza ki a figyelni kívánt hálózati interfészeket",
|
||||
"units_speed": "Sebesség mértékegységei",
|
||||
"units_traffic": "Egységek a forgalom számára"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Események",
|
||||
"description": "Milyen eseményeket kell felvetni",
|
||||
"data": {
|
||||
"device_connected": "Eszköz csatlakoztatva (új eszköz)",
|
||||
"device_disconnected": "Az eszköz leválasztva",
|
||||
"device_reconnected": "Az eszköz újracsatlakozva",
|
||||
"node_connected": "AiMesh csomópont csatlakoztatva (új eszköz)",
|
||||
"node_disconnected": "Az AiMesh csomópont nem csatlakozik",
|
||||
"node_reconnected": "Az AiMesh csomópont újracsatlakozva"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Biztonság",
|
||||
"data": {
|
||||
"hide_passwords": "Jelszavak elrejtése az érzékelők és attribútumok elől"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Nem lehet sikerült hálózati nevévvel. Próbálja meg IP címmel",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Kapcsolódás elutasítva",
|
||||
"error": "Nem sikerült csatlakozni",
|
||||
"login_blocked": "A bejelentkezést az eszköz blokkolja. Kérlek várjon",
|
||||
"password_missing": "Hiányzó jelszó",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Ismeretlen hiba",
|
||||
"wrong_credentials": "Nem megfelelő hitelesítő adatok"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "Az eszköz már konfigurálva van",
|
||||
"no_serial": "Ez a készülék nem közölt sorozatszámot. A felfedezés megszakadt",
|
||||
"not_router": "Nem Asus router, az eszköz nem konfigurálható."
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "A módosítandó konfigurációk",
|
||||
"menu_options": {
|
||||
"credentials": "Hitelesítési adatok és kapcsolat",
|
||||
"operation": "Üzemmód",
|
||||
"connected_devices": "Csatlakoztatott eszközök",
|
||||
"intervals": "Frissítési időközök",
|
||||
"interfaces": "Interfészek a monitorozáshoz",
|
||||
"events": "Home Assistant események",
|
||||
"security": "Biztonsági beállítások",
|
||||
"finish": "Mentés és bezárás"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Hitelesítő adatok",
|
||||
"description": "Ugyanaz, mint az eszköz webpaneljénél",
|
||||
"data": {
|
||||
"username": "Felhasználónév",
|
||||
"password": "Jelszó",
|
||||
"port": "Port (0 az alapértelmezett érték használatához)",
|
||||
"ssl": "SSL kapcsolat használata"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Üzemmód",
|
||||
"data": {
|
||||
"mode": "Eszköz mód",
|
||||
"enable_control": "Eszközvezérlés engedélyezése",
|
||||
"split_intervals": "Érzékelőnkénti frissítési időközök engedélyezése"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Csatlakoztatott eszközök",
|
||||
"data": {
|
||||
"track_devices": "Eszközkövetők engedélyezése",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "A legutóbb tárolandó csatlakoztatott eszközök száma",
|
||||
"interval_devices": "Eszközök / AiMesh frissítés",
|
||||
"consider_home": "Otthon van az eszköz (az utolsó „online” állapot utáni megállapítás)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Frissítési időközök",
|
||||
"description": "Az értékeket másodpercben adja meg",
|
||||
"data": {
|
||||
"cache_time": "Gyorsítótárazási idő",
|
||||
"scan_interval": "Az entitások frissítése",
|
||||
"interval_cpu": "CPU adatok",
|
||||
"interval_firmware": "Firmware adatok",
|
||||
"interval_gwlan": "GWLAN intervallum",
|
||||
"interval_light": "LED adatok",
|
||||
"interval_misc": "Egyéb adatok",
|
||||
"interval_network": "Hálózati statisztikai adatok",
|
||||
"interval_parental_control": "Szülői felügyeleti adatok",
|
||||
"interval_ports": "Portok adatai",
|
||||
"interval_ram": "RAM adatok",
|
||||
"interval_sysinfo": "Rendszerinfó adatok",
|
||||
"interval_temperature": "Hőmérséklet adatok",
|
||||
"interval_vpn": "VPN adatok",
|
||||
"interval_wan": "WAN adatok",
|
||||
"interval_wlan": "WLAN adatok"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfészek a monitorozáshoz",
|
||||
"data": {
|
||||
"interfaces": "Válassza ki a figyelni kívánt hálózati interfészeket",
|
||||
"units_speed": "Sebesség mértékegységei",
|
||||
"units_traffic": "Egységek a forgalom számára"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Események",
|
||||
"description": "Milyen eseményeket kell felvetni",
|
||||
"data": {
|
||||
"device_connected": "Eszköz csatlakoztatva (új eszköz)",
|
||||
"device_disconnected": "Az eszköz leválasztva",
|
||||
"device_reconnected": "Az eszköz újracsatlakozva",
|
||||
"node_connected": "AiMesh csomópont csatlakoztatva (új eszköz)",
|
||||
"node_disconnected": "Az AiMesh csomópont nem csatlakozik",
|
||||
"node_reconnected": "Az AiMesh csomópont újracsatlakozva"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Biztonság",
|
||||
"data": {
|
||||
"hide_passwords": "Jelszavak elrejtése az érzékelők és attribútumok elől"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Kapcsolódás elutasítva",
|
||||
"error": "Nem sikerült csatlakozni",
|
||||
"login_blocked": "A bejelentkezést az eszköz blokkolja. Kérlek várjon",
|
||||
"not_confirmed": "Meg kell erősíteni",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Ismeretlen hiba",
|
||||
"wrong_credentials": "Nem megfelelő hitelesítő adatok"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Device locatie",
|
||||
"description": "Hoe vind je jou device",
|
||||
"data": {
|
||||
"host": "Hostnaam / IP adres"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Login gegevens",
|
||||
"description": "Dezelfde als die van je router web paneel",
|
||||
"data": {
|
||||
"username": "Gebruikersnaam",
|
||||
"password": "Wachtwoord",
|
||||
"port": "Poort (0 voor standaard waarde)",
|
||||
"ssl": "Gebruik SSL verbinding"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Operatie mode",
|
||||
"data": {
|
||||
"mode": "[NT] Device mode",
|
||||
"enable_control": "Activeer apparaat controle",
|
||||
"split_intervals": "Activeer per-sensor update interval"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "[NT] Additional options",
|
||||
"menu_options": {
|
||||
"connected_devices": "[NT] Connected devices",
|
||||
"intervals": "Update interval",
|
||||
"interfaces": "Interfaces voor monitoring",
|
||||
"events": "Home Assistant events",
|
||||
"security": "Beveiliging opties",
|
||||
"finish": "[NT] Save and finish"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Activeer apparaat trackers",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Nummer van laatst verbonden apparaat opslaan?",
|
||||
"interval_devices": "[NT] Devices / AiMesh update",
|
||||
"consider_home": "Overweeg apparaat als thuis voor (na laatste 'online' staat)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Update interval",
|
||||
"description": "Waarde in secondes",
|
||||
"data": {
|
||||
"cache_time": "Caching tijd",
|
||||
"scan_interval": "Entities update",
|
||||
"interval_cpu": "CPU data",
|
||||
"interval_firmware": "Firmware data",
|
||||
"interval_gwlan": "GWLAN interval",
|
||||
"interval_light": "Kicht data",
|
||||
"interval_misc": "Overige data",
|
||||
"interval_network": "Network statestieken data",
|
||||
"interval_parental_control": "Ouders controlle data",
|
||||
"interval_ports": "Poorten data",
|
||||
"interval_ram": "RAM data",
|
||||
"interval_sysinfo": "Sysinfo data",
|
||||
"interval_temperature": "Temperstuur data",
|
||||
"interval_vpn": "VPN data",
|
||||
"interval_wan": "WAN data",
|
||||
"interval_wlan": "WLAN data"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interface voor monitoring",
|
||||
"data": {
|
||||
"interfaces": "Selecteer netwerk interfaces voor monitoring",
|
||||
"units_speed": "Eenheden per snelheid",
|
||||
"units_traffic": "Eenhenden for verkeer"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Gebeurtenis",
|
||||
"description": "Welke gebeurtenis moet meer prioriteit krijgen?",
|
||||
"data": {
|
||||
"device_connected": "Apparaat verbonden (het apparaat was niet eerder gevolgt)",
|
||||
"device_disconnected": "Apparaat verbroken",
|
||||
"device_reconnected": "Apparaat opnieuw verbonden (Het apparaart is al eens gevolgt)",
|
||||
"node_connected": "[NT] AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "[NT] AiMesh node disconnected",
|
||||
"node_reconnected": "[NT] AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Beveiliging",
|
||||
"data": {
|
||||
"hide_passwords": "Verberg wachtwoorden voor sensoren en accessoires"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Kan hostnaam niet herleiden. Probeer met IP adres",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Connectie afgewezen",
|
||||
"error": "Problemen met connectie",
|
||||
"login_blocked": "Inloggen is geblokkeerd door device. Wacht aub",
|
||||
"password_missing": "Wachtwoord mist",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Onbekende fout",
|
||||
"wrong_credentials": "Verkeerde login gegevens"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[NT] Device is already configured",
|
||||
"no_serial": "[NT] This device does not provide serial number. Discovery aborted",
|
||||
"not_router": "[NT] Not an Asus router. Cannot be configured"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Verander configuratie",
|
||||
"menu_options": {
|
||||
"credentials": "Login gegevens en connectie instellingen",
|
||||
"operation": "Operatie modus",
|
||||
"connected_devices": "[NT] Connected devices",
|
||||
"intervals": "Update interval",
|
||||
"interfaces": "Interfaces voor monitoring",
|
||||
"events": "Home Assistant events",
|
||||
"security": "Beveiliging opties",
|
||||
"finish": "[NT] Save and finish",
|
||||
"device": "Identificatie- en verbindingsparameters"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Login gegevens",
|
||||
"description": "Dezelfde als die van je router web paneel",
|
||||
"data": {
|
||||
"username": "Gebruikersnaam",
|
||||
"password": "Wachtwoord",
|
||||
"port": "Poort (0 voor standaard waarde)",
|
||||
"ssl": "Gebruik SSL verbinding"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Operation mode",
|
||||
"data": {
|
||||
"mode": "[NT] Device mode",
|
||||
"enable_control": "Activeer apparaat controle",
|
||||
"split_intervals": "Activeer per-sensor update interval"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Activeer apparaat trackers",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Nummer van laatst verbonden apparaat opslaan?",
|
||||
"interval_devices": "[NT] Devices / AiMesh update",
|
||||
"consider_home": "Overweeg apparaat als thuis voor (na laatste 'online' staat)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Update intervals",
|
||||
"description": "Waardes zijn in secondes",
|
||||
"data": {
|
||||
"cache_time": "Caching tijd",
|
||||
"scan_interval": "Entities update",
|
||||
"interval_cpu": "CPU data",
|
||||
"interval_firmware": "Firmware data",
|
||||
"interval_gwlan": "GWLAN interval",
|
||||
"interval_light": "Kicht data",
|
||||
"interval_misc": "Overige data",
|
||||
"interval_network": "Network stat data",
|
||||
"interval_parental_control": "Ouders controlle data",
|
||||
"interval_ports": "Poorten data",
|
||||
"interval_ram": "RAM data",
|
||||
"interval_sysinfo": "Sysinfo data",
|
||||
"interval_temperature": "Temperstuur data",
|
||||
"interval_vpn": "VPN data",
|
||||
"interval_wan": "WAN data",
|
||||
"interval_wlan": "WLAN data"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces to monitor",
|
||||
"data": {
|
||||
"interfaces": "Selecteer netwerk interfaces voor monitoring",
|
||||
"units_speed": "Eenheden per snelheid",
|
||||
"units_traffic": "Eenhenden for verkeer"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Gebeurtenis",
|
||||
"description": "Welke gebeurtenis moet meer prioriteit krijgen?",
|
||||
"data": {
|
||||
"device_connected": "Apparaat verbonden (het apparaat was niet eerder gevolgt)",
|
||||
"device_disconnected": "Apparaat verbroken",
|
||||
"device_reconnected": "Apparaat opnieuw verbonden (Het apparaart is al eens gevolgt)",
|
||||
"node_connected": "[NT] AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "[NT] AiMesh node disconnected",
|
||||
"node_reconnected": "[NT] AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Security",
|
||||
"data": {
|
||||
"hide_passwords": "Verberg wachtwoorden voor sensoren en accessoires"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Connectie afgewezen",
|
||||
"error": "Problemen met connectie",
|
||||
"login_blocked": "Inloggen is geblokkeerd door device. Wacht aub",
|
||||
"not_confirmed": "U dient te bevestigen",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Onbekende fout",
|
||||
"wrong_credentials": "Verkeerde login gegevens"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Localizar dispositivo",
|
||||
"description": "Como encontrar seu dispositivo",
|
||||
"data": {
|
||||
"host": "Nome de rede / Endereço IP"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credenciais",
|
||||
"description": "As mesmas do painel da web do dispositivo",
|
||||
"data": {
|
||||
"username": "Nome de usuário",
|
||||
"password": "Senha",
|
||||
"port": "Porta (0 para usar o valor padrão)",
|
||||
"ssl": "Usar conexão SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Modo de operação",
|
||||
"data": {
|
||||
"mode": "Modo do dispositivo",
|
||||
"enable_control": "Ativar o controle do dispositivo",
|
||||
"split_intervals": "Habilitar intervalos de atualização por sensor"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "Opções adicionais",
|
||||
"menu_options": {
|
||||
"connected_devices": "Dispositivos conectados",
|
||||
"intervals": "Intervalos de atualização",
|
||||
"interfaces": "Interfaces para monitorar",
|
||||
"events": "Eventos do Home Assistant",
|
||||
"security": "Opções de segurança",
|
||||
"finish": "Guardar e finalizar"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Habilitar rastreadores de dispositivos",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Número de dispositivos conectatos recentemente a armazenar",
|
||||
"interval_devices": "Atualização de dispositivos / AiMesh",
|
||||
"consider_home": "Considere um dispositivo em casa após (desde o último estado 'online')",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervalos de atualização",
|
||||
"description": "Valores indicados em segundos",
|
||||
"data": {
|
||||
"cache_time": "Tempo de cache para os dados do dispositivo",
|
||||
"scan_interval": "Intervalo para atualizar entidades",
|
||||
"interval_cpu": "Dados de CPU",
|
||||
"interval_firmware": "Dados do firmware",
|
||||
"interval_gwlan": "Dados GWLAN",
|
||||
"interval_light": "Dados dos LEDs",
|
||||
"interval_misc": "Dados diversos",
|
||||
"interval_network": "Dados de estatística de rede",
|
||||
"interval_parental_control": "Dados do controle dos pais",
|
||||
"interval_ports": "Dados de portas",
|
||||
"interval_ram": "Dados da RAM",
|
||||
"interval_sysinfo": "Dados do sistema",
|
||||
"interval_temperature": "Dados de temperatura",
|
||||
"interval_vpn": "Dados de VPN",
|
||||
"interval_wan": "Dados da WAN",
|
||||
"interval_wlan": "Dados da WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces para monitorar",
|
||||
"data": {
|
||||
"interfaces": "Selecione interfaces de rede para monitorar",
|
||||
"units_speed": "Unidades de velocidade",
|
||||
"units_traffic": "Unidades de tráfego"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Eventos",
|
||||
"description": "Quais eventos devem ser disparados",
|
||||
"data": {
|
||||
"device_connected": "Dispositivo conectato (o dispositivo não foi rastreado anteriormente)",
|
||||
"device_disconnected": "Dispositivo desconectato",
|
||||
"device_reconnected": "Dispositivo reconectado (o dispositivo já foi rastreado anteriormente)",
|
||||
"node_connected": "Nó AiMesh conectado (o dispositivo não foi rastreado anteriormente)",
|
||||
"node_disconnected": "Nó AiMesh desconectado",
|
||||
"node_reconnected": "Nó AiMesh reconectado"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Segurança",
|
||||
"data": {
|
||||
"hide_passwords": "Ocultar senhas de sensores e atributos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Não foi possível resolver o nome do host. Tente usar o endereço IP",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Conexão recusada",
|
||||
"error": "Falhou ao conectar",
|
||||
"login_blocked": "O login foi bloqueado pelo dispositivo. Por favor, espere",
|
||||
"password_missing": "Falta a senha",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Erro desconhecido",
|
||||
"wrong_credentials": "Credenciais inválidas"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "Dispositivo já configurado",
|
||||
"no_serial": "Este dispositivo não fornece um número de série. Descobrimento abortado.",
|
||||
"not_router": "Não é um roteador ASUS. Não é possível configurar."
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Configurações a alterar",
|
||||
"menu_options": {
|
||||
"credentials": "Credenciais e configurações de conexão",
|
||||
"operation": "Modo de operação",
|
||||
"connected_devices": "Dispositivos conectados",
|
||||
"intervals": "Intervalos de atualização",
|
||||
"interfaces": "Interfaces para monitorar",
|
||||
"events": "Eventos do Home Assistant",
|
||||
"security": "Opções de segurança",
|
||||
"finish": "Guardar e finalizar",
|
||||
"device": "Parâmetros de identificação e conexão"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credenciais",
|
||||
"description": "As mesmas do painel da web do dispositivo",
|
||||
"data": {
|
||||
"username": "Nome de usuário",
|
||||
"password": "Senha",
|
||||
"port": "Porta (0 para usar o valor padrão)",
|
||||
"ssl": "Usar conexão SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Modo de operação",
|
||||
"data": {
|
||||
"mode": "Modo do dispositivo",
|
||||
"enable_control": "Ativar o controle do dispositivo",
|
||||
"split_intervals": "Habilitar intervalos por sensor"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Habilitar rastreadores de dispositivos",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Número de dispositivos conectatos recentemente a armazenar",
|
||||
"interval_devices": "Atualização de dispositivos / AiMesh",
|
||||
"consider_home": "Considere um dispositivo em casa após (desde o último estado 'online')",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervalos de atualização",
|
||||
"description": "Valores indicados em segundos",
|
||||
"data": {
|
||||
"cache_time": "Tempo de cache para os dados do dispositivo",
|
||||
"scan_interval": "Intervalo para atualizar entidades",
|
||||
"interval_cpu": "Dados de CPU",
|
||||
"interval_firmware": "Dados do firmware",
|
||||
"interval_gwlan": "Dados GWLAN",
|
||||
"interval_light": "Dados dos LEDs",
|
||||
"interval_misc": "Dados diversos",
|
||||
"interval_network": "Dados de estatística da rede",
|
||||
"interval_parental_control": "Dados do controle dos pais",
|
||||
"interval_ports": "Dados de portas",
|
||||
"interval_ram": "Dados de RAM",
|
||||
"interval_sysinfo": "Dados do sistema",
|
||||
"interval_temperature": "Dados de temperatura",
|
||||
"interval_vpn": "Dados de VPN",
|
||||
"interval_wan": "Dados da WAN",
|
||||
"interval_wlan": "Dados da WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces para monitorar",
|
||||
"data": {
|
||||
"interfaces": "Selecione interfaces de rede para monitorar",
|
||||
"units_speed": "Unidades para velocidade",
|
||||
"units_traffic": "Unidades para tráfego"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Eventos",
|
||||
"description": "Quais eventos devem ser disparados",
|
||||
"data": {
|
||||
"device_connected": "Dispositivo conectato (o dispositivo não foi rastreado anteriormente)",
|
||||
"device_disconnected": "Dispositivo desconectato",
|
||||
"device_reconnected": "Dispositivo reconectado (o dispositivo já foi rastreado anteriormente)",
|
||||
"node_connected": "Nó AiMesh conectado (o dispositivo não foi rastreado anteriormente)",
|
||||
"node_disconnected": "Nó AiMesh desconectado",
|
||||
"node_reconnected": "Nó AiMesh reconectado"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Segurança",
|
||||
"data": {
|
||||
"hide_passwords": "Ocultar senhas de sensores e atributos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Conexão recusada",
|
||||
"error": "Falha ao conectar",
|
||||
"login_blocked": "O login foi bloqueado pelo dispositivo. Por favor, espere",
|
||||
"not_confirmed": "Você tem que confirmar",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Erro desconhecido",
|
||||
"wrong_credentials": "Credenciais erradas"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Localização do dispositivo",
|
||||
"description": "Como encontrar o seu dispositivo",
|
||||
"data": {
|
||||
"host": "Nome do host / Endereço IP"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credenciais",
|
||||
"description": "As mesmas utilizadas no painel web do dispositivo",
|
||||
"data": {
|
||||
"username": "Nome de utilizador",
|
||||
"password": "Palavra-passe",
|
||||
"port": "Porta (0 para usar o valor padrão)",
|
||||
"ssl": "Usar ligação SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Modo de operação",
|
||||
"data": {
|
||||
"mode": "Modo do dispositivo",
|
||||
"enable_control": "Ativar controlo do dispositivo",
|
||||
"split_intervals": "Ativar intervalos de atualização por sensor"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "Opções adicionais",
|
||||
"menu_options": {
|
||||
"connected_devices": "Dispositivos ligados",
|
||||
"intervals": "Intervalos de atualização",
|
||||
"interfaces": "Interfaces a monitorizar",
|
||||
"events": "Eventos do Home Assistant",
|
||||
"security": "Opções de segurança",
|
||||
"finish": "Guardar e finalizar"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Dispositivos ligados",
|
||||
"data": {
|
||||
"track_devices": "Ativar rastreadores de dispositivos",
|
||||
"client_device": "Criar um dispositivo quando ativar a entidade device_tracker",
|
||||
"clients_in_attr": "Guardar a lista de clientes nos atributos do sensor de dispositivos ligados",
|
||||
"client_filter": "Filtrar clientes",
|
||||
"client_filter_list": "Lista de clientes a filtrar (ativo apenas se o filtro estiver ativado)",
|
||||
"force_clients": "Forçar atualização de clientes",
|
||||
"force_clients_waittime": "Tempo de espera (forçar atualização -> verificar) (segundos)",
|
||||
"latest_connected": "Número de últimos dispositivos ligados a guardar",
|
||||
"interval_devices": "Atualização de dispositivos / AiMesh",
|
||||
"consider_home": "Considerar dispositivo em casa durante (após o último estado 'online')",
|
||||
"create_devices": "Criar dispositivos no HA ao criar entidades de clientes"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervalos de atualização",
|
||||
"description": "Valores em segundos",
|
||||
"data": {
|
||||
"cache_time": "Tempo de cache",
|
||||
"scan_interval": "Atualização de entidades",
|
||||
"interval_cpu": "Dados da CPU",
|
||||
"interval_firmware": "Dados de firmware",
|
||||
"interval_gwlan": "Intervalo GWLAN",
|
||||
"interval_light": "Dados de luz",
|
||||
"interval_misc": "Dados diversos",
|
||||
"interval_network": "Dados de estatísticas de rede",
|
||||
"interval_parental_control": "Dados de controlo parental",
|
||||
"interval_ports": "Dados de portas",
|
||||
"interval_ram": "Dados de RAM",
|
||||
"interval_sysinfo": "Dados de informações do sistema",
|
||||
"interval_temperature": "Dados de temperatura",
|
||||
"interval_vpn": "Dados de VPN",
|
||||
"interval_wan": "Dados de WAN",
|
||||
"interval_wlan": "Dados de WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Interfaces a monitorizar",
|
||||
"data": {
|
||||
"interfaces": "Selecione as interfaces de rede a monitorizar",
|
||||
"units_speed": "Unidades para velocidade",
|
||||
"units_traffic": "Unidades para tráfego"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Eventos",
|
||||
"description": "Que eventos devem ser gerados",
|
||||
"data": {
|
||||
"device_connected": "Dispositivo ligado (o dispositivo não era rastreado anteriormente)",
|
||||
"device_disconnected": "Dispositivo desligado",
|
||||
"device_reconnected": "Dispositivo reconectado (este dispositivo já estava a ser rastreado anteriormente)",
|
||||
"node_connected": "Nó AiMesh ligado (não visto antes)",
|
||||
"node_disconnected": "Nó AiMesh desligado",
|
||||
"node_reconnected": "Nó AiMesh reconectado"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Segurança",
|
||||
"data": {
|
||||
"hide_passwords": "Ocultar palavras-passe de sensores e atributos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Não foi possível resolver o nome do host. Experimente com o endereço IP",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Ligação recusada",
|
||||
"error": "Falha ao ligar",
|
||||
"login_blocked": "A autenticação foi bloqueada pelo dispositivo. Aguarde, por favor",
|
||||
"password_missing": "Palavra-passe em falta",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Erro desconhecido",
|
||||
"wrong_credentials": "Credenciais incorretas"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "O dispositivo já está configurado",
|
||||
"no_serial": "Este dispositivo não fornece número de série. A descoberta foi abortada",
|
||||
"not_router": "Não é um router Asus. Não pode ser configurado"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Configurações a alterar",
|
||||
"menu_options": {
|
||||
"credentials": "Credenciais e ligação",
|
||||
"operation": "Modo de operação",
|
||||
"connected_devices": "Dispositivos ligados",
|
||||
"intervals": "Intervalos de atualização",
|
||||
"interfaces": "Interfaces a monitorizar",
|
||||
"events": "Eventos do Home Assistant",
|
||||
"security": "Opções de segurança",
|
||||
"finish": "Guardar e finalizar",
|
||||
"device": "Identificação e parâmetros de ligação"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Credenciais",
|
||||
"description": "As mesmas utilizadas no painel web do dispositivo",
|
||||
"data": {
|
||||
"username": "Nome de utilizador",
|
||||
"password": "Palavra-passe",
|
||||
"port": "Porta (0 para usar o valor padrão)",
|
||||
"ssl": "Usar ligação SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Modo de operação",
|
||||
"data": {
|
||||
"mode": "Modo do dispositivo",
|
||||
"enable_control": "Ativar controlo do dispositivo",
|
||||
"split_intervals": "Ativar intervalos de atualização por sensor"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Controlo de acesso à Internet do dispositivo",
|
||||
"description": "Alterar o acesso à Internet do dispositivo utilizando a funcionalidade de controlo parental do router. Consulte a documentação para obter mais parâmetros possíveis",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entidades",
|
||||
"description": "Selecione os dispositivos para alterar as definições de acesso à Internet"
|
||||
},
|
||||
"state": {
|
||||
"name": "Estado",
|
||||
"description": "Defina o estado para os dispositivos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remover rastreadores de dispositivos",
|
||||
"description": "Remover rastreadores de dispositivos do registo do dispositivo. Note que, ao executar, o serviço removerá os rastreadores selecionados e permitirá remover manualmente as entidades.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entidades",
|
||||
"description": "Selecione os dispositivos para remover do registo do dispositivo"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Permitir acesso",
|
||||
"block": "Bloquear acesso",
|
||||
"remove": "Remover regra da lista"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Местоположение устройства",
|
||||
"description": "Как найти свое устройство",
|
||||
"data": {
|
||||
"host": "Имя хоста / IP-адрес"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Учетные данные",
|
||||
"description": "Те же, что и для веб-интерфейса устройства",
|
||||
"data": {
|
||||
"username": "Имя пользователя",
|
||||
"password": "Пароль",
|
||||
"port": "Порт (0 - использовать значение по умолчанию)",
|
||||
"ssl": "Использовать SSL-соединение"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Режим работы",
|
||||
"data": {
|
||||
"mode": "Режим работы устройства",
|
||||
"enable_control": "Включить управление устройством",
|
||||
"split_intervals": "Включить настройки частоты обновлений для каждого сенсора"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "Дополнительные параметры",
|
||||
"menu_options": {
|
||||
"connected_devices": "Подключенные устройства",
|
||||
"intervals": "Частота обновлений",
|
||||
"interfaces": "Мониторинг интерфейсов",
|
||||
"events": "События Home Assistant",
|
||||
"security": "Параметры безопасности",
|
||||
"finish": "Сохранить и завершить"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Подключенные устройства",
|
||||
"data": {
|
||||
"track_devices": "Включить отслеживание устройств",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Количество последних подключенных устройств для сохранения",
|
||||
"interval_devices": "Обновление устройств / AiMesh",
|
||||
"consider_home": "Считать 'дома' в течение (после последнего состояния 'онлайн')",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Частота обновлений",
|
||||
"description": "Значения указываются в секундах",
|
||||
"data": {
|
||||
"cache_time": "Время кэширования",
|
||||
"scan_interval": "Обновление объектов",
|
||||
"interval_cpu": "Данные процессора",
|
||||
"interval_firmware": "Данные прошивки",
|
||||
"interval_gwlan": "Интервал GWLAN",
|
||||
"interval_light": "Данные LED-подсветки",
|
||||
"interval_misc": "Прочие данные",
|
||||
"interval_network": "Данные о состоянии сети",
|
||||
"interval_parental_control": "Данные родительского контроля",
|
||||
"interval_ports": "Данные портов",
|
||||
"interval_ram": "Данные RAM",
|
||||
"interval_sysinfo": "Информация о системе",
|
||||
"interval_temperature": "Данные о температуре",
|
||||
"interval_vpn": "Данные VPN",
|
||||
"interval_wan": "Данные WAN",
|
||||
"interval_wlan": "Данные WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Мониторинг интерфейсов",
|
||||
"data": {
|
||||
"interfaces": "Выберите сетевые интерфейсы для мониторинга",
|
||||
"units_speed": "Единицы измерения скорости",
|
||||
"units_traffic": "Единицы измерения трафика"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "События",
|
||||
"description": "Какие события необходимо вызывать",
|
||||
"data": {
|
||||
"device_connected": "Устройство подключено (устройство ранее не отслеживалось)",
|
||||
"device_disconnected": "Устройство отключено",
|
||||
"device_reconnected": "Устройство повторно подключено (это устройство уже отслеживалось ранее)",
|
||||
"node_connected": "Узел AiMesh подключен (не отслеживался ранее)",
|
||||
"node_disconnected": "Узел AiMesh отключен",
|
||||
"node_reconnected": "Узел AiMesh повторно подключен"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Безопасность",
|
||||
"data": {
|
||||
"hide_passwords": "Скрыть пароли от сенсоров и атрибутов"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Не удается разрешить имя хоста. Попробуйте использовать IP-адрес",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Отказ в подключении",
|
||||
"error": "Не удалось подключиться",
|
||||
"login_blocked": "Вход заблокирован устройством. Пожалуйста, подождите",
|
||||
"password_missing": "Отсутствует пароль",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Неизвестная ошибка",
|
||||
"wrong_credentials": "Неверные учетные данные"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "Устройство уже настроено",
|
||||
"no_serial": "Это устройство не предоставляет серийный номер. Обнаружение прервано",
|
||||
"not_router": "Не является маршрутизатором Asus. Настройка невозможна"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Изменение конфигурации",
|
||||
"menu_options": {
|
||||
"credentials": "Учетные данные и подключение",
|
||||
"operation": "Режим работы",
|
||||
"connected_devices": "Подключенные устройства",
|
||||
"intervals": "Частота обновлений",
|
||||
"interfaces": "Мониторинг интерфейсов",
|
||||
"events": "События Home Assistant",
|
||||
"security": "Параметры безопасности",
|
||||
"finish": "Сохранить и завершить"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Учетные данные",
|
||||
"description": "Те же, что и для веб-интерфейса устройства",
|
||||
"data": {
|
||||
"username": "Имя пользователя",
|
||||
"password": "Пароль",
|
||||
"port": "Порт (0 - использовать значение по умолчанию)",
|
||||
"ssl": "Использовать SSL-соединение"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Режим работы",
|
||||
"data": {
|
||||
"mode": "Режим работы устройства",
|
||||
"enable_control": "Включить управление устройством",
|
||||
"split_intervals": "Включить настройки частоты обновлений для каждого сенсора"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Подключенные устройства",
|
||||
"data": {
|
||||
"track_devices": "Включить отслеживание устройств",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Количество последних подключенных устройств для сохранения",
|
||||
"interval_devices": "Обновление устройств / AiMesh",
|
||||
"consider_home": "Считать 'дома' в течение (после последнего состояния 'онлайн')",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Частота обновлений",
|
||||
"description": "Значения указываются в секундах",
|
||||
"data": {
|
||||
"cache_time": "Время кэширования",
|
||||
"scan_interval": "Обновление объектов",
|
||||
"interval_cpu": "Данные процессора",
|
||||
"interval_firmware": "Данные прошивки",
|
||||
"interval_gwlan": "Интервал GWLAN",
|
||||
"interval_light": "Данные LED-подсветки",
|
||||
"interval_misc": "Прочие данные",
|
||||
"interval_network": "Данные о состоянии сети",
|
||||
"interval_parental_control": "Данные родительского контроля",
|
||||
"interval_ports": "Данные портов",
|
||||
"interval_ram": "Данные RAM",
|
||||
"interval_sysinfo": "Информация о системе",
|
||||
"interval_temperature": "Данные о температуре",
|
||||
"interval_vpn": "Данные VPN",
|
||||
"interval_wan": "Данные WAN",
|
||||
"interval_wlan": "Данные WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Мониторинг интерфейсов",
|
||||
"data": {
|
||||
"interfaces": "Выберите сетевые интерфейсы для мониторинга",
|
||||
"units_speed": "Единицы измерения скорости",
|
||||
"units_traffic": "Единицы измерения трафика"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "События",
|
||||
"description": "Какие события необходимо вызывать",
|
||||
"data": {
|
||||
"device_connected": "Устройство подключено (устройство ранее не отслеживалось)",
|
||||
"device_disconnected": "Устройство отключено",
|
||||
"device_reconnected": "Устройство повторно подключено (это устройство уже отслеживалось ранее)",
|
||||
"node_connected": "Узел AiMesh подключен (не отслеживался ранее)",
|
||||
"node_disconnected": "Узел AiMesh отключен",
|
||||
"node_reconnected": "Узел AiMesh повторно подключен"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Безопасность",
|
||||
"data": {
|
||||
"hide_passwords": "Скрыть пароли от сенсоров и атрибутов"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Отказ в подключении",
|
||||
"error": "Не удалось подключиться",
|
||||
"login_blocked": "Вход заблокирован устройством. Пожалуйста, подождите",
|
||||
"not_confirmed": "Подтвердите",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Неизвестная ошибка",
|
||||
"wrong_credentials": "Неверные учетные данные"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Pridať zariadenie",
|
||||
"description": "Ako pridať svoje zariadenie",
|
||||
"data": {
|
||||
"host": "Hostiteľ / IP adresa"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Prihlasovacie údaje",
|
||||
"description": "Rovnaké ako pre webový panel zariadenia",
|
||||
"data": {
|
||||
"username": "Uživateľské meno",
|
||||
"password": "Heslo",
|
||||
"port": "Port (0 pre použitie východzej hodnoty)",
|
||||
"ssl": "Použiť pripojenie SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Prevádzkový režim",
|
||||
"data": {
|
||||
"mode": "[NT] Device mode",
|
||||
"enable_control": "Povoliť ovládanie zariadenia",
|
||||
"split_intervals": "Povoliť intervaly aktualizáce pre každý senzor"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "[NT] Additional options",
|
||||
"menu_options": {
|
||||
"connected_devices": "[NT] Connected devices",
|
||||
"intervals": "Intervaly aktualizácie",
|
||||
"interfaces": "Rozhrania sledovania",
|
||||
"events": "Udalosti Home Assistant",
|
||||
"security": "Možnosti zabezpečenia",
|
||||
"finish": "[NT] Save and finish"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Povoliť sledovanie zariadení",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Počet najnovších pripojených zariadení pre uloženie",
|
||||
"interval_devices": "[NT] Devices / AiMesh update",
|
||||
"consider_home": "Považovať zariadenie že je doma (po poslednom 'online' stave)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervaly aktualizácie",
|
||||
"description": "Hodnoty sú v sekundách",
|
||||
"data": {
|
||||
"cache_time": "Čas medzipamäti",
|
||||
"scan_interval": "Aktualizácia entít",
|
||||
"interval_cpu": "Údaje CPU",
|
||||
"interval_firmware": "Údaje firmwaru",
|
||||
"interval_gwlan": "Interval GWLAN",
|
||||
"interval_light": "Stav LED",
|
||||
"interval_misc": "Rôzne údaje",
|
||||
"interval_network": "Údaje o štatistikách siete",
|
||||
"interval_parental_control": "Údaje rodičovskej kontroly",
|
||||
"interval_ports": "Údaje portov",
|
||||
"interval_ram": "Údaje RAM",
|
||||
"interval_sysinfo": "Údaje systémové info",
|
||||
"interval_temperature": "Údaje o teplote",
|
||||
"interval_vpn": "Údaje VPN",
|
||||
"interval_wan": "Údaje WAN",
|
||||
"interval_wlan": "Údaje WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Rozhranie sledovania",
|
||||
"data": {
|
||||
"interfaces": "Vyberte sieťové rozhranie sledovania",
|
||||
"units_speed": "Jednotky pre rýchlost",
|
||||
"units_traffic": "Jednotky pre sieťovú prevádzku"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Udalosti",
|
||||
"description": "Ktoré udalosti sa majú oznamovať",
|
||||
"data": {
|
||||
"device_connected": "Zariadenie pripojené (zariadenie nebolo predtým sledované)",
|
||||
"device_disconnected": "Zariadenie odpojené",
|
||||
"device_reconnected": "Zariadenie bolo znovu pripojené (toto zariadenie už bolo sledované)",
|
||||
"node_connected": "[NT] AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "[NT] AiMesh node disconnected",
|
||||
"node_reconnected": "[NT] AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Zabezpečenie",
|
||||
"data": {
|
||||
"hide_passwords": "Skryť heslá zo senzorov a atribútov"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"cannot_resolve_host": "Nedá sa rozpoznať názov hostiteľa. Skúste použiť IP adresu",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Pripojenie odmietnuté",
|
||||
"error": "Nepodarilo se pripojiť",
|
||||
"login_blocked": "Prihlásenie je blokované zariadením. Počkajte prosím",
|
||||
"password_missing": "Chýba heslo",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Neznáma chyba",
|
||||
"wrong_credentials": "Chybné prihlasovacie údaje"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[NT] Device is already configured",
|
||||
"no_serial": "[NT] This device does not provide serial number. Discovery aborted",
|
||||
"not_router": "[NT] Not an Asus router. Cannot be configured"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Zmena konfigurácií",
|
||||
"menu_options": {
|
||||
"credentials": "Prihlasovacie údaje a nastavenie pripojenia",
|
||||
"operation": "Prevádzkový režim",
|
||||
"connected_devices": "[NT] Connected devices",
|
||||
"intervals": "Intervaly aktualizácie",
|
||||
"interfaces": "Rozhrania sledovania",
|
||||
"events": "Udalosti Home Assistant",
|
||||
"security": "Možnosti zabezpečenia",
|
||||
"finish": "[NT] Save and finish",
|
||||
"device": "Parametre identifikácie a pripojenia"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Prihlasovacie údaje",
|
||||
"description": "Rovnaké ako pre webový panel zariadenia",
|
||||
"data": {
|
||||
"username": "Uživateľské meno",
|
||||
"password": "Heslo",
|
||||
"port": "Port (0 pre použitie východzej hodnoty)",
|
||||
"ssl": "Použiť pripojenie SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Prevádzkový režim",
|
||||
"data": {
|
||||
"mode": "[NT] Device mode",
|
||||
"enable_control": "Povoliť ovladanie zariadenia",
|
||||
"split_intervals": "Povoliť intervaly aktualizácie pre každý senzor"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Connected devices",
|
||||
"data": {
|
||||
"track_devices": "Povoliť sledovanie zariadení",
|
||||
"client_device": "[NT] Create a device when I enable device_tracker entity",
|
||||
"clients_in_attr": "[NT] Store clients list in attributes of the connected devices sensor",
|
||||
"client_filter": "[NT] Filter clients",
|
||||
"client_filter_list": "[NT] List of clients to filter (only active if filter is enabled)",
|
||||
"force_clients": "[NT] Force clients update",
|
||||
"force_clients_waittime": "[NT] Wait time (force update -> check) (seconds)",
|
||||
"latest_connected": "Počet najnovších pripojených zariadení pre uloženie",
|
||||
"interval_devices": "[NT] Devices / AiMesh update",
|
||||
"consider_home": "Považovať zariadenie že je doma (po poslednom 'online' stave)",
|
||||
"create_devices": "Create HA devices when creating clients entities"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Intervaly aktualizáce",
|
||||
"description": "Hodnoty sú v sekundách",
|
||||
"data": {
|
||||
"cache_time": "Čas mezipamäte",
|
||||
"scan_interval": "Aktualizácia entít",
|
||||
"interval_cpu": "Údaje CPU",
|
||||
"interval_firmware": "Údaje firmwaru",
|
||||
"interval_gwlan": "Interval GWLAN",
|
||||
"interval_light": "Stav LED",
|
||||
"interval_misc": "Rôzne údaje",
|
||||
"interval_network": "Údaje o statistikách siete",
|
||||
"interval_parental_control": "Údaje rodičovskej kontroly",
|
||||
"interval_ports": "Údaje portov",
|
||||
"interval_ram": "Údaje RAM",
|
||||
"interval_sysinfo": "Údaje systémové info",
|
||||
"interval_temperature": "Údaje o teplote",
|
||||
"interval_vpn": "Údaje VPN",
|
||||
"interval_wan": "Údaje WAN",
|
||||
"interval_wlan": "Údaje WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Rozhranie sledovania",
|
||||
"data": {
|
||||
"interfaces": "Vyberte sieťové rozhranie sledovania",
|
||||
"units_speed": "Jednotky pre rýchlosť",
|
||||
"units_traffic": "Jednotky pre sieťovú prevádzku"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Udalosti",
|
||||
"description": "Ktoré udalosti sa majú oznamovať",
|
||||
"data": {
|
||||
"device_connected": "Zariadenie pripojené (zariadenie nebolo predtým sledované)",
|
||||
"device_disconnected": "Zariadenie odpojené",
|
||||
"device_reconnected": "Zariadenie bolo znovu pripojené (toto zariadenie už bolo sledované)",
|
||||
"node_connected": "[NT] AiMesh node connected (not seen before)",
|
||||
"node_disconnected": "[NT] AiMesh node disconnected",
|
||||
"node_reconnected": "[NT] AiMesh node reconnected"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Zabezpečenie",
|
||||
"data": {
|
||||
"hide_passwords": "Skryť heslá zo senzorov a atribútov"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "[NT] Access error. Refer to the log for details",
|
||||
"connection_error": "[NT] Connection error. Refer to the log for details",
|
||||
"connection_refused": "Pripojenie odmietnuté",
|
||||
"error": "Nepodarilo se pripojiť",
|
||||
"login_blocked": "Prihlásenie je blokované zariadením. Čakaje prosím",
|
||||
"not_confirmed": "Nepotvrdené",
|
||||
"timeout": "[NT] Timeout error",
|
||||
"unknown": "Neznámá chyba",
|
||||
"wrong_credentials": "Chybné prihlasovacie údaje"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Device internet access control",
|
||||
"description": "Change device internet access using parental control feature of the router. Please, refer to the documentation for the additional possible parameters",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to change internet access settings"
|
||||
},
|
||||
"state": {
|
||||
"name": "State",
|
||||
"description": "Set the state for the device(s)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Remove device trackers",
|
||||
"description": "Remove device trackers from the device registry. Please, keep in mind, when run, the service will remove selected trackers from watching and will allow you to remove the entities manually.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Entities",
|
||||
"description": "Select device(s) to remove from the device registry"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Allow access",
|
||||
"block": "Block access",
|
||||
"remove": "Remove rule from the list"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{name} ({host})",
|
||||
"step": {
|
||||
"find": {
|
||||
"title": "Розташування пристрою",
|
||||
"description": "Де шукати ваш пристрій",
|
||||
"data": {
|
||||
"host": "Ім'я хоста / IP адреса"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Параметри для входу",
|
||||
"description": "Такі самі, як для веб-панелі пристрою",
|
||||
"data": {
|
||||
"username": "Ім'я користувача",
|
||||
"password": "Пароль",
|
||||
"port": "Порт (0 щоб використати стандартне значення)",
|
||||
"ssl": "Використовувати SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Режим роботи",
|
||||
"data": {
|
||||
"mode": "Режим роботи",
|
||||
"enable_control": "Увімкнути контроль пристрою",
|
||||
"split_intervals": "Незалежне налаштування інтервалу оновлення сенсорів"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"title": "Додаткові налаштування",
|
||||
"menu_options": {
|
||||
"connected_devices": "Підключені пристрої",
|
||||
"intervals": "Інтервали оновлення",
|
||||
"interfaces": "Інтерфейси для відслідковування",
|
||||
"events": "Події Home Assistant",
|
||||
"security": "Налаштування безпеки",
|
||||
"finish": "Зберегти і завершити"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Підключені пристрої",
|
||||
"data": {
|
||||
"track_devices": "Увімкнути трекінг клієнтів",
|
||||
"client_device": "Створювати пристрій, коли я активую device_tracker запис",
|
||||
"clients_in_attr": "Зберігати повний список клієнтів у атрибутах до connected devices сенсору",
|
||||
"client_filter": "Фільтрувати клієнтів",
|
||||
"client_filter_list": "Список клієнтів для фільтру (лише якщо фільтр увімкнено)",
|
||||
"force_clients": "Примусово оновлювати список клієнтів",
|
||||
"force_clients_waittime": "Час очікування (примусове оновлення -> перевірка) (секунд)",
|
||||
"latest_connected": "Кількість останніх підключених пристроїв для зберігання",
|
||||
"interval_devices": "Оновлення клієнтів / AiMesh",
|
||||
"consider_home": "Вважати клієнта 'вдома' протягом (після останнього значення 'online')",
|
||||
"create_devices": "Створювати пристрої при створення записів для окремих клієнтів"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Інтервали оновлення",
|
||||
"description": "Значення в секундах",
|
||||
"data": {
|
||||
"cache_time": "Час кешування",
|
||||
"scan_interval": "Інтервал оновлення",
|
||||
"interval_cpu": "Оновлення даних CPU",
|
||||
"interval_firmware": "Оновлення даних прошивки",
|
||||
"interval_gwlan": "Оновлення даних гостьових WLAN",
|
||||
"interval_light": "Оновлення даних light",
|
||||
"interval_misc": "Оновлення даних misc",
|
||||
"interval_network": "Оновлення даних network stat",
|
||||
"interval_parental_control": "Оновлення даних parental control",
|
||||
"interval_ports": "Оновлення даних ports",
|
||||
"interval_ram": "Оновлення даних RAM",
|
||||
"interval_sysinfo": "Оновлення даних sysinfo",
|
||||
"interval_temperature": "Оновлення даних temperature",
|
||||
"interval_vpn": "Оновлення даних VPN",
|
||||
"interval_wan": "Оновлення даних WAN",
|
||||
"interval_wlan": "Оновлення даних WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Інтерфейси для відслідковування",
|
||||
"data": {
|
||||
"interfaces": "Виберіть інтерфейси для відслідковування",
|
||||
"units_speed": "Одиниці вимірювання швидкості",
|
||||
"units_traffic": "Одиниці вимірювання трафіку"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Події",
|
||||
"description": "Які події повинні викликатися",
|
||||
"data": {
|
||||
"device_connected": "Пристрій підключено (цей пристрій раніше не відслідковувався)",
|
||||
"device_disconnected": "Пристрій відключено",
|
||||
"device_reconnected": "Пристрій знов підключено (цей пристрій вже відслідковувався)",
|
||||
"node_connected": "AiMesh нода підключена (підключено вперше)",
|
||||
"node_disconnected": "AiMesh нода відключена",
|
||||
"node_reconnected": "AiMesh нода знов підключена"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Безпека",
|
||||
"data": {
|
||||
"hide_passwords": "Приховати паролі з сенсорів та атрибутів"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "Помилка доступу. Перевірте деталі в журналі",
|
||||
"cannot_resolve_host": "Неможливо знайти ім'я хоста. Спробуйте використати IP адресу",
|
||||
"connection_error": "Помилка підключення. Перевірти деталі в журналі подій",
|
||||
"connection_refused": "З'єднання відхилено",
|
||||
"error": "Не вдалося підключитися",
|
||||
"login_blocked": "Вхід заблоковано пристроєм. Будь ласка, зачекайте",
|
||||
"password_missing": "Пароль відсутній",
|
||||
"timeout": "Таймаут підключення",
|
||||
"unknown": "Невідома помилка",
|
||||
"wrong_credentials": "Неправильні облікові дані"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "Пристрій вже налаштовано",
|
||||
"no_serial": "Пристрій не надає серійний номер. Налаштування скасоване",
|
||||
"not_router": "Пристрій не є роутером Asus. Налаштування неможливе"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"options": {
|
||||
"title": "Зміна налаштувань",
|
||||
"menu_options": {
|
||||
"credentials": "Облікові дані та підключення",
|
||||
"operation": "Режим роботи",
|
||||
"connected_devices": "Підключені пристрої",
|
||||
"intervals": "Інтервали оновлення",
|
||||
"interfaces": "Інтерфейси для відслідковування",
|
||||
"events": "Події Home Assistant",
|
||||
"security": "Налаштування безпеки",
|
||||
"finish": "Зберегти і завершити",
|
||||
"device": "Параметри ідентифікації та підключення"
|
||||
}
|
||||
},
|
||||
"credentials": {
|
||||
"title": "Параметри для входу",
|
||||
"description": "Такі самі, як для веб-панелі пристрою",
|
||||
"data": {
|
||||
"username": "Ім'я користувача",
|
||||
"password": "Пароль",
|
||||
"port": "Порт (0 щоб використати стандартне значення)",
|
||||
"ssl": "Використовувати SSL"
|
||||
}
|
||||
},
|
||||
"operation": {
|
||||
"title": "Режим роботи",
|
||||
"data": {
|
||||
"mode": "Режим роботи",
|
||||
"enable_control": "Увімкнути контроль пристрою",
|
||||
"split_intervals": "Незалежне налаштування інтервалу оновлення сенсорів"
|
||||
}
|
||||
},
|
||||
"connected_devices": {
|
||||
"title": "Підключені пристрої",
|
||||
"data": {
|
||||
"track_devices": "Увімкнути трекінг клієнтів",
|
||||
"client_device": "Створювати пристрій, коли я активую device_tracker запис",
|
||||
"clients_in_attr": "Зберігати повний список клієнтів у атрибутах до connected devices сенсору",
|
||||
"client_filter": "Фільтрувати клієнтів",
|
||||
"client_filter_list": "Список клієнтів для фільтру (лише якщо фільтр увімкнено)",
|
||||
"force_clients": "Примусово оновлювати список клієнтів",
|
||||
"force_clients_waittime": "Час очікування (примусове оновлення -> перевірка) (секунд)",
|
||||
"latest_connected": "Кількість останніх підключених пристроїв для зберігання",
|
||||
"interval_devices": "Оновлення клієнтів / AiMesh",
|
||||
"consider_home": "Вважати клієнта 'вдома' протягом (після останнього значення 'online')",
|
||||
"create_devices": "Створювати пристрої при створення записів для окремих клієнтів"
|
||||
}
|
||||
},
|
||||
"intervals": {
|
||||
"title": "Інтервали оновлення",
|
||||
"description": "Значення в секундах",
|
||||
"data": {
|
||||
"cache_time": "Час кешування",
|
||||
"scan_interval": "Інтервал оновлення",
|
||||
"interval_cpu": "Оновлення даних CPU",
|
||||
"interval_firmware": "Оновлення даних прошивки",
|
||||
"interval_gwlan": "Оновлення даних гостьових WLAN",
|
||||
"interval_light": "Оновлення даних light",
|
||||
"interval_misc": "Оновлення даних misc",
|
||||
"interval_network": "Оновлення даних network stat",
|
||||
"interval_parental_control": "Оновлення даних parental control",
|
||||
"interval_ports": "Оновлення даних ports",
|
||||
"interval_ram": "Оновлення даних RAM",
|
||||
"interval_sysinfo": "Оновлення даних sysinfo",
|
||||
"interval_temperature": "Оновлення даних temperature",
|
||||
"interval_vpn": "Оновлення даних VPN",
|
||||
"interval_wan": "Оновлення даних WAN",
|
||||
"interval_wlan": "Оновлення даних WLAN"
|
||||
}
|
||||
},
|
||||
"interfaces": {
|
||||
"title": "Інтерфейси для відслідковування",
|
||||
"data": {
|
||||
"interfaces": "Виберіть інтерфейси для відслідковування",
|
||||
"units_speed": "Одиниці вимірювання швидкості",
|
||||
"units_traffic": "Одиниці вимірювання трафіку"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"title": "Події",
|
||||
"description": "Які події повинні викликатися",
|
||||
"data": {
|
||||
"device_connected": "Пристрій підключено (цей пристрій раніше не відслідковувався)",
|
||||
"device_disconnected": "Пристрій відключено",
|
||||
"device_reconnected": "Пристрій знов підключено (цей пристрій вже відслідковувався)",
|
||||
"node_connected": "AiMesh нода підключена (підключено вперше)",
|
||||
"node_disconnected": "AiMesh нода відключена",
|
||||
"node_reconnected": "AiMesh нода знов підключена"
|
||||
}
|
||||
},
|
||||
"security": {
|
||||
"title": "Безпека",
|
||||
"data": {
|
||||
"hide_passwords": "Приховати паролі з сенсорів та атрибутів"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"access_error": "Помилка доступу. Перевірте деталі в журналі",
|
||||
"connection_error": "Помилка підключення. Перевірти деталі в журналі подій",
|
||||
"connection_refused": "З'єднання відхилено",
|
||||
"error": "Не вдалося підключитися",
|
||||
"login_blocked": "Вхід заблоковано пристроєм. Будь ласка, зачекайте",
|
||||
"not_confirmed": "Необхідне підтвердження",
|
||||
"timeout": "Таймаут підключення",
|
||||
"unknown": "Невідома помилка",
|
||||
"wrong_credentials": "Неправильні облікові дані"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"device_internet_access": {
|
||||
"name": "Інтернет доступ для пристрою",
|
||||
"description": "Змініть доступ до Інтернету за допомогою функції батьківського контролю маршрутизатора. Будь ласка, зверніться до документації для отримання додаткових можливих параметрів",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Пристрої",
|
||||
"description": "Оберіть пристрої для зміни доступу до Інтернету"
|
||||
},
|
||||
"state": {
|
||||
"name": "Доступ",
|
||||
"description": "Оберіть вид доступу до Інтернету"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove_trackers": {
|
||||
"name": "Видалити трекери пристроїв",
|
||||
"description": "Видалити трекери з реєстру. Врахуйте наступне: при виконанні цього сервісу, обрані трекери будуть видалені з реєстру. Після цього ви зможете видалити їх сутності вручну.",
|
||||
"fields": {
|
||||
"entities": {
|
||||
"name": "Пристрої",
|
||||
"description": "Оберіть пристрої для видалення з реєстру"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"set_pc_rule": {
|
||||
"options": {
|
||||
"allow": "Дозволити доступ",
|
||||
"block": "Заблокувати доступ",
|
||||
"remove": "Видалити правило зі списку"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
"""AsusRouter update module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from asusrouter.modules.system import AsusSystem
|
||||
from homeassistant.components.update import UpdateEntity, UpdateEntityFeature
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
from .const import STATIC_UPDATES
|
||||
from .dataclass import ARUpdateDescription
|
||||
from .entity import ARBinaryEntity, async_setup_ar_entry
|
||||
from .router import ARDevice
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up AsusRouter updates."""
|
||||
|
||||
updates = STATIC_UPDATES.copy()
|
||||
|
||||
await async_setup_ar_entry(
|
||||
hass, config_entry, async_add_entities, updates, ARUpdate
|
||||
)
|
||||
|
||||
|
||||
class ARUpdate(ARBinaryEntity, UpdateEntity):
|
||||
"""AsusRouter update."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
router: ARDevice,
|
||||
description: ARUpdateDescription,
|
||||
) -> None:
|
||||
"""Initialize AsusRouter update."""
|
||||
|
||||
super().__init__(coordinator, router, description)
|
||||
self.entity_description: ARUpdateDescription = description
|
||||
|
||||
self._attr_installed_version = self.extra_state_attributes.get(
|
||||
"current"
|
||||
)
|
||||
self._attr_latest_version = self.extra_state_attributes.get("latest")
|
||||
self._attr_release_summary = self.extra_state_attributes.get(
|
||||
"release_note"
|
||||
)
|
||||
self._attr_in_progress = False
|
||||
|
||||
self._attr_supported_features = (
|
||||
UpdateEntityFeature.RELEASE_NOTES
|
||||
| UpdateEntityFeature.INSTALL
|
||||
| UpdateEntityFeature.PROGRESS
|
||||
)
|
||||
|
||||
def release_notes(self) -> str | None:
|
||||
"""Return the release notes."""
|
||||
|
||||
return self.extra_state_attributes.get("release_note")
|
||||
|
||||
async def async_install(
|
||||
self, version: str | None, backup: bool, **kwargs: Any
|
||||
) -> None:
|
||||
"""Install the update."""
|
||||
try:
|
||||
_LOGGER.debug(
|
||||
"Trying to install Firmware update. "
|
||||
"This might take several minutes."
|
||||
)
|
||||
result = await self.api.async_set_state(
|
||||
state=AsusSystem.FIRMWARE_UPGRADE,
|
||||
)
|
||||
if not result:
|
||||
_LOGGER.debug(
|
||||
"Something went wrong while trying to install the update."
|
||||
)
|
||||
else:
|
||||
self._attr_in_progress = True
|
||||
await asyncio.sleep(120)
|
||||
self._attr_in_progress = False
|
||||
|
||||
except Exception as ex: # noqa: BLE001
|
||||
_LOGGER.error(
|
||||
"An exception occurred while trying to install the update: %s",
|
||||
ex,
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
"""C.A.F.E. - Visual automation editor for Home Assistant."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import DOMAIN
|
||||
from .panel import async_register_panel, async_unregister_panel
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up the C.A.F.E. component."""
|
||||
# This will be called when the integration is loaded
|
||||
# But actual setup happens in async_setup_entry
|
||||
return True
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry) -> bool:
|
||||
"""Set up C.A.F.E. from a config entry."""
|
||||
|
||||
# Register the panel (frontend)
|
||||
await async_register_panel(hass)
|
||||
|
||||
_LOGGER.info("C.A.F.E. integration set up successfully")
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry) -> bool:
|
||||
"""Unload a config entry."""
|
||||
async_unregister_panel(hass)
|
||||
return True
|
||||
@@ -0,0 +1,53 @@
|
||||
"""Config flow for C.A.F.E. integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
STEP_USER_DATA_SCHEMA = vol.Schema({})
|
||||
|
||||
|
||||
class CafeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for C.A.F.E."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Handle the initial step."""
|
||||
if user_input is not None:
|
||||
# Check if already configured
|
||||
await self.async_set_unique_id(DOMAIN)
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
return self.async_create_entry(
|
||||
title="C.A.F.E.",
|
||||
data={}
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
data_schema=STEP_USER_DATA_SCHEMA,
|
||||
description_placeholders={
|
||||
"name": "C.A.F.E.",
|
||||
"description": "Visual automation editor for Home Assistant"
|
||||
}
|
||||
)
|
||||
|
||||
async def async_step_import(self, user_input: dict[str, Any]) -> FlowResult:
|
||||
"""Handle import from configuration.yaml."""
|
||||
await self.async_set_unique_id(DOMAIN)
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
return self.async_create_entry(title="C.A.F.E.", data={})
|
||||
@@ -0,0 +1,6 @@
|
||||
"""Constants for C.A.F.E.."""
|
||||
|
||||
DOMAIN = "cafe"
|
||||
PANEL_URL = "/cafe_panel"
|
||||
PANEL_TITLE = "C.A.F.E."
|
||||
PANEL_ICON = "mdi:coffee-to-go"
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"domain": "cafe",
|
||||
"name": "C.A.F.E.",
|
||||
"version": "0.6.0",
|
||||
"codeowners": [],
|
||||
"config_flow": true,
|
||||
"dependencies": ["frontend", "http"],
|
||||
"documentation": "https://github.com/FezVrasta/cafe-hass",
|
||||
"documentation_url": "https://github.com/FezVrasta/cafe-hass",
|
||||
"integration_type": "service",
|
||||
"iot_class": "local_push",
|
||||
"issue_tracker": "https://github.com/FezVrasta/cafe-hass/issues",
|
||||
"requirements": []
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
"""Panel for C.A.F.E."""
|
||||
import os
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.components import frontend, panel_custom
|
||||
from homeassistant.components.http import StaticPathConfig
|
||||
|
||||
from .const import DOMAIN, PANEL_TITLE, PANEL_ICON
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PANEL_URL = f"/api/{DOMAIN}_panel"
|
||||
PANEL_NAME = f"{DOMAIN}-panel"
|
||||
|
||||
|
||||
async def async_register_panel(hass: HomeAssistant) -> None:
|
||||
"""Register the C.A.F.E. panel."""
|
||||
# Get the path to the www folder within the component
|
||||
www_path = Path(__file__).parent / "www"
|
||||
|
||||
# Register static path for the frontend assets
|
||||
await hass.http.async_register_static_paths([
|
||||
StaticPathConfig("/cafe-hass", str(www_path), False)
|
||||
])
|
||||
|
||||
# The panel wrapper has a fixed name (not hashed)
|
||||
wrapper_path = www_path / "assets" / "panel-wrapper.js"
|
||||
if not wrapper_path.exists():
|
||||
_LOGGER.error("panel-wrapper.js not found in assets directory")
|
||||
_LOGGER.error(f"www path: {www_path}, assets exist: {(www_path / 'assets').exists()}")
|
||||
return
|
||||
|
||||
# Add cache-busting parameter to force fresh load
|
||||
import time
|
||||
cache_bust = int(time.time())
|
||||
module_url = f"/cafe-hass/assets/panel-wrapper.js?v={cache_bust}"
|
||||
|
||||
# First try to unregister any existing panel
|
||||
try:
|
||||
hass.data.get("frontend_panels", {}).pop(DOMAIN, None)
|
||||
_LOGGER.info("Removed any existing panel registration")
|
||||
except:
|
||||
pass
|
||||
|
||||
# Register the panel as a custom panel with module_url
|
||||
await panel_custom.async_register_panel(
|
||||
hass,
|
||||
webcomponent_name=PANEL_NAME,
|
||||
frontend_url_path=DOMAIN,
|
||||
module_url=module_url,
|
||||
sidebar_title=PANEL_TITLE,
|
||||
sidebar_icon=PANEL_ICON,
|
||||
require_admin=True,
|
||||
config={},
|
||||
config_panel_domain=DOMAIN,
|
||||
)
|
||||
|
||||
_LOGGER.info("C.A.F.E. panel registered successfully with iframe wrapper")
|
||||
|
||||
|
||||
def async_unregister_panel(hass: HomeAssistant) -> None:
|
||||
"""Unregister the C.A.F.E. panel."""
|
||||
frontend.async_remove_panel(hass, DOMAIN)
|
||||
_LOGGER.info("C.A.F.E. panel unregistered")
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"config": {
|
||||
"title": "C.A.F.E.",
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "Set up C.A.F.E.",
|
||||
"description": "C.A.F.E. is a visual automation editor for Home Assistant. It allows you to create and manage your automations using a visual flow editor.\n\nClick Submit to add C.A.F.E. to your Home Assistant."
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "C.A.F.E. is already configured"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"config": {
|
||||
"title": "C.A.F.E.",
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "Set up C.A.F.E.",
|
||||
"description": "C.A.F.E. is a visual automation editor for Home Assistant. It allows you to create and manage your automations using a visual flow editor.\n\nClick Submit to add C.A.F.E. to your Home Assistant."
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "C.A.F.E. is already configured"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
var d=Object.defineProperty;var o=(t,s,e)=>s in t?d(t,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[s]=e;var a=(t,s,e)=>o(t,typeof s!="symbol"?s+"":s,e);class m extends HTMLElement{constructor(){super(...arguments);a(this,"_messageHandler");a(this,"iframe",null);a(this,"_hass")}set hass(e){var i;this._hass=e,window.hass=e,(i=this.iframe)!=null&&i.contentWindow&&this.iframe.contentWindow.setHass&&this.iframe.contentWindow.setHass(e)}get hass(){return this._hass}connectedCallback(){var n,r;this.style.display="block",this.style.width="100%",this.style.height="100%",this.style.position="relative";const i=((r=(n=this._hass)==null?void 0:n.themes)==null?void 0:r.darkMode)??!1?"hsl(222.2, 84%, 4.9%)":"hsl(0, 0%, 100%)";this.iframe=document.createElement("iframe"),this.iframe.src="/cafe-hass/index.html",this.iframe.style.width="100%",this.iframe.style.height="100%",this.iframe.style.border="none",this.iframe.style.display="block",this.iframe.style.background=i,this.iframe.setAttribute("allow","clipboard-read *; clipboard-write *"),this.appendChild(this.iframe),this._messageHandler=h=>{var l;h.source===((l=this.iframe)==null?void 0:l.contentWindow)&&h.data&&h.data.type==="CAFE_TOGGLE_SIDEBAR"&&this.dispatchEvent(new Event("hass-toggle-menu",{bubbles:!0,composed:!0}))},window.addEventListener("message",this._messageHandler)}disconnectedCallback(){this.iframe&&(this.removeChild(this.iframe),this.iframe=null),window.hass=void 0,this._messageHandler&&(window.removeEventListener("message",this._messageHandler),this._messageHandler=void 0)}}customElements.get("cafe-panel")||customElements.define("cafe-panel",m);
|
||||
//# sourceMappingURL=panel-wrapper.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"panel-wrapper.js","sources":["../../src/panel-wrapper.ts"],"sourcesContent":["/**\n * Minimal wrapper for Home Assistant panel integration.\n * This web component receives the hass object from HA, exposes it on window,\n * and loads the actual app in an iframe for proper document isolation.\n */\nimport type { HomeAssistant } from './types/hass';\n\n// Type for window with hass\ndeclare const window: Window & {\n hass?: HomeAssistant;\n};\n\nclass CafePanelWrapper extends HTMLElement {\n private _messageHandler?: (event: MessageEvent) => void;\n private iframe: HTMLIFrameElement | null = null;\n private _hass: HomeAssistant | undefined = undefined;\n\n // Properties that HA will set\n set hass(value: HomeAssistant | undefined) {\n this._hass = value;\n // Expose hass on window so iframe can access via window.parent.hass\n window.hass = value;\n\n // Notify the iframe of the update if it has registered a listener\n if (this.iframe?.contentWindow && (this.iframe.contentWindow as any).setHass) {\n (this.iframe.contentWindow as any).setHass(value);\n }\n }\n\n get hass() {\n return this._hass;\n }\n\n connectedCallback() {\n // Style the wrapper to fill the container\n this.style.display = 'block';\n this.style.width = '100%';\n this.style.height = '100%';\n this.style.position = 'relative';\n\n // Detect dark mode from hass to set initial background and avoid white flash\n const isDarkMode = this._hass?.themes?.darkMode ?? false;\n // These match the CSS variables in index.css:\n // Light: --background: 0 0% 100% (white)\n // Dark: --background: 222.2 84% 4.9% (dark blue)\n const bgColor = isDarkMode ? 'hsl(222.2, 84%, 4.9%)' : 'hsl(0, 0%, 100%)';\n\n // Create iframe pointing to the app\n this.iframe = document.createElement('iframe');\n this.iframe.src = '/cafe-hass/index.html';\n this.iframe.style.width = '100%';\n this.iframe.style.height = '100%';\n this.iframe.style.border = 'none';\n this.iframe.style.display = 'block';\n this.iframe.style.background = bgColor;\n // Allow same-origin access\n this.iframe.setAttribute('allow', 'clipboard-read *; clipboard-write *');\n\n this.appendChild(this.iframe);\n\n // Listen for messages from the iframe to trigger sidebar toggle\n this._messageHandler = (event: MessageEvent) => {\n // Only accept messages from our iframe\n if (event.source !== this.iframe?.contentWindow) return;\n if (event.data && event.data.type === 'CAFE_TOGGLE_SIDEBAR') {\n this.dispatchEvent(new Event('hass-toggle-menu', { bubbles: true, composed: true }));\n }\n };\n window.addEventListener('message', this._messageHandler);\n }\n\n disconnectedCallback() {\n if (this.iframe) {\n this.removeChild(this.iframe);\n this.iframe = null;\n }\n // Clean up window properties\n window.hass = undefined;\n if (this._messageHandler) {\n window.removeEventListener('message', this._messageHandler);\n this._messageHandler = undefined;\n }\n }\n}\n\n// Register the custom element\nif (!customElements.get('cafe-panel')) {\n customElements.define('cafe-panel', CafePanelWrapper);\n}\n"],"names":["CafePanelWrapper","__publicField","value","_a","_b","bgColor","event"],"mappings":"oKAYA,MAAMA,UAAyB,WAAY,CAA3C,kCACUC,EAAA,wBACAA,EAAA,cAAmC,MACnCA,EAAA,cAGR,IAAI,KAAKC,EAAkC,CAN7C,IAAAC,EAOI,KAAK,MAAQD,EAEb,OAAO,KAAOA,GAGVC,EAAA,KAAK,SAAL,MAAAA,EAAa,eAAkB,KAAK,OAAO,cAAsB,SAClE,KAAK,OAAO,cAAsB,QAAQD,CAAK,CAEpD,CAEA,IAAI,MAAO,CACT,OAAO,KAAK,KACd,CAEA,mBAAoB,CArBtB,IAAAC,EAAAC,EAuBI,KAAK,MAAM,QAAU,QACrB,KAAK,MAAM,MAAQ,OACnB,KAAK,MAAM,OAAS,OACpB,KAAK,MAAM,SAAW,WAOtB,MAAMC,IAJaD,GAAAD,EAAA,KAAK,QAAL,YAAAA,EAAY,SAAZ,YAAAC,EAAoB,WAAY,GAItB,wBAA0B,mBAGvD,KAAK,OAAS,SAAS,cAAc,QAAQ,EAC7C,KAAK,OAAO,IAAM,wBAClB,KAAK,OAAO,MAAM,MAAQ,OAC1B,KAAK,OAAO,MAAM,OAAS,OAC3B,KAAK,OAAO,MAAM,OAAS,OAC3B,KAAK,OAAO,MAAM,QAAU,QAC5B,KAAK,OAAO,MAAM,WAAaC,EAE/B,KAAK,OAAO,aAAa,QAAS,qCAAqC,EAEvE,KAAK,YAAY,KAAK,MAAM,EAG5B,KAAK,gBAAmBC,GAAwB,CAjDpD,IAAAH,EAmDUG,EAAM,WAAWH,EAAA,KAAK,SAAL,YAAAA,EAAa,gBAC9BG,EAAM,MAAQA,EAAM,KAAK,OAAS,uBACpC,KAAK,cAAc,IAAI,MAAM,mBAAoB,CAAE,QAAS,GAAM,SAAU,EAAA,CAAM,CAAC,CAEvF,EACA,OAAO,iBAAiB,UAAW,KAAK,eAAe,CACzD,CAEA,sBAAuB,CACjB,KAAK,SACP,KAAK,YAAY,KAAK,MAAM,EAC5B,KAAK,OAAS,MAGhB,OAAO,KAAO,OACV,KAAK,kBACP,OAAO,oBAAoB,UAAW,KAAK,eAAe,EAC1D,KAAK,gBAAkB,OAE3B,CACF,CAGK,eAAe,IAAI,YAAY,GAClC,eAAe,OAAO,aAAcN,CAAgB"}
|
||||
@@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>C.A.F.E. - Home Assistant</title>
|
||||
<script>
|
||||
// Set background color immediately to avoid white flash in dark mode
|
||||
// This runs before CSS loads, checking parent window's hass dark mode setting
|
||||
(function() {
|
||||
try {
|
||||
var isDark = window.parent && window.parent.hass && window.parent.hass.themes && window.parent.hass.themes.darkMode;
|
||||
// Match CSS variables: light = hsl(0, 0%, 100%), dark = hsl(222.2, 84%, 4.9%)
|
||||
var bg = isDark ? 'hsl(222.2, 84%, 4.9%)' : 'hsl(0, 0%, 100%)';
|
||||
document.documentElement.style.background = bg;
|
||||
// Inject style for body since it doesn't exist yet
|
||||
var style = document.createElement('style');
|
||||
style.textContent = 'body { background: ' + bg + ' !important; }';
|
||||
document.head.appendChild(style);
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
<script type="module" crossorigin src="/cafe-hass/assets/main-BIzscans.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/cafe-hass/assets/main-DfXhj31a.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||