Compare commits

..

55 Commits

Author SHA1 Message Date
Paulus Schoutsen
75b508e872 Merge pull request #31931 from home-assistant/rc
0.105.5
2020-02-17 14:52:02 -08:00
Paulus Schoutsen
7bc87eef6f Bumped version to 0.105.5 2020-02-17 14:15:37 -08:00
Paulus Schoutsen
8812b60f2e Report which data causes JSON serialization error (#31901) 2020-02-17 14:15:09 -08:00
Gerard
21a1186efe Upgrade bimmer_connected to 0.7.0 (#31894) 2020-02-17 14:15:09 -08:00
Paulus Schoutsen
68d2a1107e Merge pull request #31841 from home-assistant/rc
0.105.4
2020-02-14 16:29:09 -08:00
Paulus Schoutsen
350726d938 Revert "For vizio integration, set unique ID early to prevent multiple zeroconf discovery items for the same device to appear (#31686)"
This reverts commit 295963f8e8.
2020-02-14 15:47:14 -08:00
Paulus Schoutsen
8140c033fa Bumped version to 0.105.4 2020-02-14 15:30:23 -08:00
Franck Nijhof
f26cbbdef9 Spotify integration hotfixes (#31835)
* Remove services file, incorrect info

* Guard currently playing for being a NoneType

* Revert "Guard currently playing for being a NoneType"

This reverts commit f5f56b0db03b407e058d45cd3549af1388916e06.

* Guard currently playing item is None

* Process review suggestions
2020-02-14 15:30:11 -08:00
Paulus Schoutsen
7705eb7941 Google Assistant: Remove speaker type and earlier filter out devices from being locally exposed (#31830)
* Remove speaker type

* Do not expose locks or alarms to Google Local
2020-02-14 15:30:11 -08:00
Paulus Schoutsen
af9832d468 Fix person device_trackers null (#31829) 2020-02-14 15:30:10 -08:00
Bram Kragten
f042c6f8d5 Updated frontend to 20200130.3 (#31771) 2020-02-14 15:29:41 -08:00
SukramJ
656c901f7b Fix smoke detection for HomematicIP Cloud (#31753) 2020-02-14 15:29:10 -08:00
Paulus Schoutsen
30e302a8a3 Fix person reload service (#31716) 2020-02-14 15:29:09 -08:00
cgtobi
7edf0460cc Fix missing device class in netatmo binary sensors (#31693)
* Bring back device class

* Add door tag sensors types

* Actually discover individual tags per camera
2020-02-14 15:29:08 -08:00
Raman Gupta
295963f8e8 For vizio integration, set unique ID early to prevent multiple zeroconf discovery items for the same device to appear (#31686)
* set unique ID early to prevent multiple zeroconf discovery items for the same device to appear

* add test
2020-02-14 15:29:08 -08:00
Paulus Schoutsen
966df6a411 Guard writing automation/scene/script config (#31568) 2020-02-14 15:29:07 -08:00
Paulus Schoutsen
fb6fb42f85 Merge pull request #31712 from home-assistant/rc
0.105.3
2020-02-10 15:49:08 -08:00
Paulus Schoutsen
992484fbe6 Bumped version to 0.105.3 2020-02-10 14:45:44 -08:00
cgtobi
834b0e6cf0 Fix wrong error message in netatmo integration (#31690) 2020-02-10 14:45:34 -08:00
Daniel Høyer Iversen
925fa25ac7 Fix hvac_action for mill (#31630) 2020-02-10 14:45:33 -08:00
Alexei Chetroi
fb6eedb4c2 Bump ZHA dependencies. (#31619)
Bump up zigpy-homeassistant==0.13.2
2020-02-10 14:44:25 -08:00
Ron Klinkien
881c501cef Catch garmin_connect keyerrors with unknown entity type updates (#31608)
* Catch keyerrors with unknown entity type updates

* Change debug level and removed . from log call
2020-02-10 14:44:24 -08:00
MatthewFlamm
4212fd8999 update pynws to 0.10.4 (#31591) 2020-02-10 14:44:23 -08:00
Rami Mosleh
b3aacfeb90 Fix librouteros response error handling (#31588) 2020-02-10 14:44:23 -08:00
Franck Nijhof
8da948e909 Bump adguardhome to 0.4.1 (#31565) 2020-02-10 14:44:22 -08:00
J. Nick Koston
a02bb893ef Resolve August integration makes too many requests and hits rate limits (#31558) 2020-02-10 14:44:21 -08:00
Alexei Chetroi
cc5377747f Bump ZHA dependencies. (#31555) 2020-02-10 14:44:21 -08:00
Paulus Schoutsen
76d2658101 Merge pull request #31550 from home-assistant/rc
0.105.2
2020-02-06 11:54:23 -08:00
Paulus Schoutsen
8ab91eb6bb Update MQTT service description 2020-02-06 11:39:55 -08:00
Paulus Schoutsen
4e5c74d293 Bumped version to 0.105.2 2020-02-06 11:08:26 -08:00
Paulus Schoutsen
d31eb9f352 Guard for reloading with no zone config (#31547) 2020-02-06 11:08:18 -08:00
Josh Bendavid
bb96584d6e update aiopylgtv to 0.3.3 (#31545) 2020-02-06 11:08:17 -08:00
Paulus Schoutsen
774f0f9b67 Deprecate old netatmo keys (#31544) 2020-02-06 11:08:16 -08:00
Ville Skyttä
64fc7103be Use min and m as units in Garmin Connect for consistency and correctness (#31543) 2020-02-06 11:08:16 -08:00
Franck Nijhof
080f9725dc Limit OAuth scopes for Netatmo and Home Assistant Cloud (#31538)
* Limit OAuth scopes for Netatmo and Home Assistant Cloud

* Fix tests by making order of scopes predictable
2020-02-06 11:08:15 -08:00
Quentame
bf1b78f621 Fix iCloud determine_interval: add default interval to max_interval (#31533) 2020-02-06 11:08:14 -08:00
Dougal Matthews
6b5cd74771 Only normalise Garmin connect data to minutes if the value is not None (#31526)
Otherwise this causes additional TypeError messages to be logged for
division of None.
2020-02-06 11:08:13 -08:00
Robert Chmielowiec
60c5ef5b34 Fix migrating huawei_lte entry without recipient (#31522) 2020-02-06 11:08:12 -08:00
Paulus Schoutsen
1e81d14822 Fix automation sun import (#31521) 2020-02-06 11:08:11 -08:00
Paulus Schoutsen
8b4bd95fc5 Merge pull request #31510 from home-assistant/rc
0.105.1
2020-02-05 16:41:17 -08:00
Paulus Schoutsen
6246382983 Bumped version to 0.105.1 2020-02-05 15:53:11 -08:00
Paulus Schoutsen
29f17956bf Update translations 2020-02-05 15:53:04 -08:00
Paulus Schoutsen
6e0e58f6cc Sonos services to work without admin access (#31506) 2020-02-05 15:52:15 -08:00
Paulus Schoutsen
46fb73ea76 Updated frontend to 20200130.2 (#31502) 2020-02-05 15:51:49 -08:00
Andrew
08b24afc2d Move program_mode check (#31501)
Don't try to capture program_mode unless ct80
2020-02-05 15:50:49 -08:00
Paulus Schoutsen
f7f8de41e2 Check for known Hue vulnerability (#31494) 2020-02-05 15:50:48 -08:00
Franck Nijhof
b2cd6707b6 0.105.0 (#31489)
0.105.0
2020-02-05 20:02:36 +01:00
Paulus Schoutsen
6a4d9d3a73 Fix Google API key test (#31492) 2020-02-05 18:57:43 +01:00
Paulus Schoutsen
1ee1a43fb9 Remove tests for deprecated key (#31491) 2020-02-05 18:02:53 +01:00
Franck Nijhof
f1d5fcac75 Bumped version to 0.105.0 2020-02-05 17:01:57 +01:00
Franck Nijhof
97250d8225 Re-branding of Hass.io panel to Supervisor (#31480) 2020-02-05 16:59:29 +01:00
Paulus Schoutsen
8b6b8f1994 Automation device/entity extraction to include triggers + conditions (#31474)
* Add support for extracting triggers

* Add support for extracting triggers

* Fix test
2020-02-05 16:59:24 +01:00
Quentame
2d393b8f8b Fix iCloud device battery level can be None (#31468) 2020-02-05 16:59:19 +01:00
Paulus Schoutsen
6d79898926 Fix coordinator reference (#31467) 2020-02-05 16:59:14 +01:00
Raman Gupta
2509518950 Update vizio host check to handle entries that don't have port (#31463)
* Update vizio host check to handle entries that don't have port

* add comment explaining no_port test for future

* remove _name_is_same function and support user updating name in config

* Update strings.json

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
2020-02-05 16:59:07 +01:00
172 changed files with 1919 additions and 614 deletions

View File

@@ -14,7 +14,7 @@
"password": "Contrasenya",
"username": "Correu electr\u00f2nic"
},
"title": "Introdueix la teva informaci\u00f3 d'inici de sessi\u00f3 a Abode."
"title": "Introducci\u00f3 de la informaci\u00f3 d'inici de sessi\u00f3 a Abode."
}
},
"title": "Abode"

View File

@@ -3,7 +3,7 @@
"name": "AdGuard Home",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/adguard",
"requirements": ["adguardhome==0.4.0"],
"requirements": ["adguardhome==0.4.1"],
"dependencies": [],
"codeowners": ["@frenck"]
}

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "Ja est\u00e0 configurada un integraci\u00f3 Airly amb aquestes coordenades."
},
"error": {
"auth": "La clau API no \u00e9s correcta.",
"name_exists": "El nom ja existeix.",

View File

@@ -1,18 +1,18 @@
{
"device_automation": {
"action_type": {
"arm_away": "\u8a2d\u5b9a {entity_name} \u5916\u51fa\u6a21\u5f0f",
"arm_home": "\u8a2d\u5b9a {entity_name} \u8fd4\u5bb6\u6a21\u5f0f",
"arm_night": "\u8a2d\u5b9a {entity_name} \u591c\u9593\u6a21\u5f0f",
"disarm": "\u89e3\u9664 {entity_name}",
"trigger": "\u89f8\u767c {entity_name}"
"arm_away": "\u8a2d\u5b9a{entity_name}\u5916\u51fa\u6a21\u5f0f",
"arm_home": "\u8a2d\u5b9a{entity_name}\u8fd4\u5bb6\u6a21\u5f0f",
"arm_night": "\u8a2d\u5b9a{entity_name}\u591c\u9593\u6a21\u5f0f",
"disarm": "\u89e3\u9664{entity_name}",
"trigger": "\u89f8\u767c{entity_name}"
},
"trigger_type": {
"armed_away": "{entity_name} \u8a2d\u5b9a\u5916\u51fa",
"armed_home": "{entity_name} \u8a2d\u5b9a\u5728\u5bb6",
"armed_night": "{entity_name} \u8a2d\u5b9a\u591c\u9593",
"disarmed": "{entity_name} \u5df2\u89e3\u9664",
"triggered": "{entity_name} \u5df2\u89f8\u767c"
"armed_away": "{entity_name}\u8a2d\u5b9a\u5916\u51fa",
"armed_home": "{entity_name}\u8a2d\u5b9a\u5728\u5bb6",
"armed_night": "{entity_name}\u8a2d\u5b9a\u591c\u9593",
"disarmed": "{entity_name}\u5df2\u89e3\u9664",
"triggered": "{entity_name}\u5df2\u89f8\u767c"
}
}
}

View File

@@ -7,6 +7,7 @@
},
"step": {
"hassio_confirm": {
"description": "Vols configurar Home Assistant perqu\u00e8 es connecti amb Almond proporcionat pel complement de Hass.io: {addon}?",
"title": "Almond (complement de Hass.io)"
},
"pick_implementation": {

View File

@@ -6,6 +6,10 @@
"missing_configuration": "Bitte \u00fcberpr\u00fcfe die Dokumentation zur Einrichtung von Almond."
},
"step": {
"hassio_confirm": {
"description": "M\u00f6chtest du Home Assistant so konfigurieren, dass eine Verbindung mit Almond als Hass.io-Add-On hergestellt wird: {addon}?",
"title": "Almond \u00fcber das Hass.io Add-on"
},
"pick_implementation": {
"title": "W\u00e4hle die Authentifizierungsmethode"
}

View File

@@ -36,8 +36,15 @@ AUGUST_CONFIG_FILE = ".august.conf"
DATA_AUGUST = "august"
DOMAIN = "august"
DEFAULT_ENTITY_NAMESPACE = "august"
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=5)
DEFAULT_SCAN_INTERVAL = timedelta(seconds=5)
# Limit battery and hardware updates to 1800 seconds
# in order to reduce the number of api requests and
# avoid hitting rate limits
MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES = timedelta(seconds=1800)
DEFAULT_SCAN_INTERVAL = timedelta(seconds=10)
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10)
LOGIN_METHODS = ["phone", "email"]
CONFIG_SCHEMA = vol.Schema(
@@ -180,7 +187,9 @@ class AugustData:
self._access_token = access_token
self._doorbells = self._api.get_doorbells(self._access_token) or []
self._locks = self._api.get_operable_locks(self._access_token) or []
self._house_ids = [d.house_id for d in self._doorbells + self._locks]
self._house_ids = set()
for device in self._doorbells + self._locks:
self._house_ids.add(device.house_id)
self._doorbell_detail_by_id = {}
self._lock_status_by_id = {}
@@ -284,58 +293,51 @@ class AugustData:
This is the status from the door sensor.
"""
self._update_doors()
self._update_locks_status()
return self._door_state_by_id.get(lock_id)
def _update_locks(self):
self._update_locks_status()
self._update_locks_detail()
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def _update_doors(self):
def _update_locks_status(self):
status_by_id = {}
state_by_id = {}
_LOGGER.debug("Start retrieving door status")
_LOGGER.debug("Start retrieving lock and door status")
for lock in self._locks:
_LOGGER.debug("Updating door status for %s", lock.device_name)
_LOGGER.debug("Updating lock and door status for %s", lock.device_name)
try:
state_by_id[lock.device_id] = self._api.get_lock_door_status(
self._access_token, lock.device_id
(
status_by_id[lock.device_id],
state_by_id[lock.device_id],
) = self._api.get_lock_status(
self._access_token, lock.device_id, door_status=True
)
except RequestException as ex:
_LOGGER.error(
"Request error trying to retrieve door status for %s. %s",
"Request error trying to retrieve lock and door status for %s. %s",
lock.device_name,
ex,
)
status_by_id[lock.device_id] = None
state_by_id[lock.device_id] = None
except Exception:
status_by_id[lock.device_id] = None
state_by_id[lock.device_id] = None
raise
_LOGGER.debug("Completed retrieving door status")
_LOGGER.debug("Completed retrieving lock and door status")
self._lock_status_by_id = status_by_id
self._door_state_by_id = state_by_id
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def _update_locks(self):
status_by_id = {}
@Throttle(MIN_TIME_BETWEEN_LOCK_DETAIL_UPDATES)
def _update_locks_detail(self):
detail_by_id = {}
_LOGGER.debug("Start retrieving locks status")
_LOGGER.debug("Start retrieving locks detail")
for lock in self._locks:
_LOGGER.debug("Updating lock status for %s", lock.device_name)
try:
status_by_id[lock.device_id] = self._api.get_lock_status(
self._access_token, lock.device_id
)
except RequestException as ex:
_LOGGER.error(
"Request error trying to retrieve door status for %s. %s",
lock.device_name,
ex,
)
status_by_id[lock.device_id] = None
except Exception:
status_by_id[lock.device_id] = None
raise
try:
detail_by_id[lock.device_id] = self._api.get_lock_detail(
self._access_token, lock.device_id
@@ -351,8 +353,7 @@ class AugustData:
detail_by_id[lock.device_id] = None
raise
_LOGGER.debug("Completed retrieving locks status")
self._lock_status_by_id = status_by_id
_LOGGER.debug("Completed retrieving locks detail")
self._lock_detail_by_id = detail_by_id
def lock(self, device_id):

View File

@@ -11,7 +11,7 @@ from . import DATA_AUGUST
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=5)
SCAN_INTERVAL = timedelta(seconds=10)
def _retrieve_door_state(data, lock):

View File

@@ -7,7 +7,7 @@ from homeassistant.components.camera import Camera
from . import DATA_AUGUST, DEFAULT_TIMEOUT
SCAN_INTERVAL = timedelta(seconds=5)
SCAN_INTERVAL = timedelta(seconds=10)
def setup_platform(hass, config, add_entities, discovery_info=None):

View File

@@ -12,7 +12,7 @@ from . import DATA_AUGUST
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=5)
SCAN_INTERVAL = timedelta(seconds=10)
def setup_platform(hass, config, add_entities, discovery_info=None):
@@ -88,7 +88,12 @@ class AugustLock(LockDevice):
if self._lock_detail is None:
return None
return {ATTR_BATTERY_LEVEL: self._lock_detail.battery_level}
attributes = {ATTR_BATTERY_LEVEL: self._lock_detail.battery_level}
if self._lock_detail.keypad is not None:
attributes["keypad_battery_level"] = self._lock_detail.keypad.battery_level
return attributes
@property
def unique_id(self) -> str:

View File

@@ -2,7 +2,7 @@
"domain": "august",
"name": "August",
"documentation": "https://www.home-assistant.io/integrations/august",
"requirements": ["py-august==0.7.0"],
"requirements": ["py-august==0.8.1"],
"dependencies": ["configurator"],
"codeowners": []
}

View File

@@ -1,16 +1,18 @@
"""Allow to set up simple automation rules via the config file."""
from functools import partial
import importlib
import logging
from typing import Any, Awaitable, Callable, List
from typing import Any, Awaitable, Callable, List, Optional, Set
import voluptuous as vol
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_NAME,
CONF_DEVICE_ID,
CONF_ENTITY_ID,
CONF_ID,
CONF_PLATFORM,
CONF_ZONE,
EVENT_AUTOMATION_TRIGGERED,
EVENT_HOMEASSISTANT_START,
SERVICE_RELOAD,
@@ -130,7 +132,7 @@ def automations_with_entity(hass: HomeAssistant, entity_id: str) -> List[str]:
results = []
for automation_entity in component.entities:
if entity_id in automation_entity.action_script.referenced_entities:
if entity_id in automation_entity.referenced_entities:
results.append(automation_entity.entity_id)
return results
@@ -149,7 +151,7 @@ def entities_in_automation(hass: HomeAssistant, entity_id: str) -> List[str]:
if automation_entity is None:
return []
return list(automation_entity.action_script.referenced_entities)
return list(automation_entity.referenced_entities)
@callback
@@ -163,7 +165,7 @@ def automations_with_device(hass: HomeAssistant, device_id: str) -> List[str]:
results = []
for automation_entity in component.entities:
if device_id in automation_entity.action_script.referenced_devices:
if device_id in automation_entity.referenced_devices:
results.append(automation_entity.entity_id)
return results
@@ -182,7 +184,7 @@ def devices_in_automation(hass: HomeAssistant, entity_id: str) -> List[str]:
if automation_entity is None:
return []
return list(automation_entity.action_script.referenced_devices)
return list(automation_entity.referenced_devices)
async def async_setup(hass, config):
@@ -232,7 +234,7 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
self,
automation_id,
name,
async_attach_triggers,
trigger_config,
cond_func,
action_script,
hidden,
@@ -241,7 +243,7 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
"""Initialize an automation entity."""
self._id = automation_id
self._name = name
self._async_attach_triggers = async_attach_triggers
self._trigger_config = trigger_config
self._async_detach_triggers = None
self._cond_func = cond_func
self.action_script = action_script
@@ -249,6 +251,8 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
self._hidden = hidden
self._initial_state = initial_state
self._is_enabled = False
self._referenced_entities: Optional[Set[str]] = None
self._referenced_devices: Optional[Set[str]] = None
@property
def name(self):
@@ -280,6 +284,45 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
"""Return True if entity is on."""
return self._async_detach_triggers is not None or self._is_enabled
@property
def referenced_devices(self):
"""Return a set of referenced devices."""
if self._referenced_devices is not None:
return self._referenced_devices
referenced = self.action_script.referenced_devices
if self._cond_func is not None:
for conf in self._cond_func.config:
referenced |= condition.async_extract_devices(conf)
for conf in self._trigger_config:
device = _trigger_extract_device(conf)
if device is not None:
referenced.add(device)
self._referenced_devices = referenced
return referenced
@property
def referenced_entities(self):
"""Return a set of referenced entities."""
if self._referenced_entities is not None:
return self._referenced_entities
referenced = self.action_script.referenced_entities
if self._cond_func is not None:
for conf in self._cond_func.config:
referenced |= condition.async_extract_entities(conf)
for conf in self._trigger_config:
for entity_id in _trigger_extract_entities(conf):
referenced.add(entity_id)
self._referenced_entities = referenced
return referenced
async def async_added_to_hass(self) -> None:
"""Startup with initial state or previous state."""
await super().async_added_to_hass()
@@ -330,7 +373,11 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
This method is a coroutine.
"""
if not skip_condition and not self._cond_func(variables):
if (
not skip_condition
and self._cond_func is not None
and not self._cond_func(variables)
):
return
# Create a new context referring to the old context.
@@ -373,9 +420,7 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
# HomeAssistant is starting up
if self.hass.state != CoreState.not_running:
self._async_detach_triggers = await self._async_attach_triggers(
self.async_trigger
)
self._async_detach_triggers = await self._async_attach_triggers()
self.async_write_ha_state()
return
@@ -385,9 +430,7 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
if not self._is_enabled or self._async_detach_triggers is not None:
return
self._async_detach_triggers = await self._async_attach_triggers(
self.async_trigger
)
self._async_detach_triggers = await self._async_attach_triggers()
self.hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, async_enable_automation
@@ -407,6 +450,38 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
self.async_write_ha_state()
async def _async_attach_triggers(self):
"""Set up the triggers."""
removes = []
info = {"name": self._name}
for conf in self._trigger_config:
platform = importlib.import_module(
".{}".format(conf[CONF_PLATFORM]), __name__
)
remove = await platform.async_attach_trigger(
self.hass, conf, self.async_trigger, info
)
if not remove:
_LOGGER.error("Error setting up trigger %s", self._name)
continue
_LOGGER.info("Initialized trigger %s", self._name)
removes.append(remove)
if not removes:
return None
@callback
def remove_triggers():
"""Remove attached triggers."""
for remove in removes:
remove()
return remove_triggers
@property
def device_state_attributes(self):
"""Return automation attributes."""
@@ -441,22 +516,12 @@ async def _async_process_config(hass, config, component):
if cond_func is None:
continue
else:
cond_func = None
def cond_func(variables):
"""Condition will always pass."""
return True
async_attach_triggers = partial(
_async_process_trigger,
hass,
config,
config_block.get(CONF_TRIGGER, []),
name,
)
entity = AutomationEntity(
automation_id,
name,
async_attach_triggers,
config_block[CONF_TRIGGER],
cond_func,
action_script,
hidden,
@@ -471,7 +536,7 @@ async def _async_process_config(hass, config, component):
async def _async_process_if(hass, config, p_config):
"""Process if checks."""
if_configs = p_config.get(CONF_CONDITION)
if_configs = p_config[CONF_CONDITION]
checks = []
for if_config in if_configs:
@@ -485,35 +550,33 @@ async def _async_process_if(hass, config, p_config):
"""AND all conditions."""
return all(check(hass, variables) for check in checks)
if_action.config = if_configs
return if_action
async def _async_process_trigger(hass, config, trigger_configs, name, action):
"""Set up the triggers.
This method is a coroutine.
"""
removes = []
info = {"name": name}
for conf in trigger_configs:
platform = importlib.import_module(".{}".format(conf[CONF_PLATFORM]), __name__)
remove = await platform.async_attach_trigger(hass, conf, action, info)
if not remove:
_LOGGER.error("Error setting up trigger %s", name)
continue
_LOGGER.info("Initialized trigger %s", name)
removes.append(remove)
if not removes:
@callback
def _trigger_extract_device(trigger_conf: dict) -> Optional[str]:
"""Extract devices from a trigger config."""
if trigger_conf[CONF_PLATFORM] != "device":
return None
def remove_triggers():
"""Remove attached triggers."""
for remove in removes:
remove()
return trigger_conf[CONF_DEVICE_ID]
return remove_triggers
@callback
def _trigger_extract_entities(trigger_conf: dict) -> List[str]:
"""Extract entities from a trigger config."""
if trigger_conf[CONF_PLATFORM] in ("state", "numeric_state"):
return trigger_conf[CONF_ENTITY_ID]
if trigger_conf[CONF_PLATFORM] == "zone":
return trigger_conf[CONF_ENTITY_ID] + [trigger_conf[CONF_ZONE]]
if trigger_conf[CONF_PLATFORM] == "geo_location":
return [trigger_conf[CONF_ZONE]]
if trigger_conf[CONF_PLATFORM] == "sun":
return ["sun.sun"]
return []

View File

@@ -1,94 +1,94 @@
{
"device_automation": {
"condition_type": {
"is_bat_low": "{entity_name} \u96fb\u91cf\u904e\u4f4e",
"is_cold": "{entity_name} \u51b7",
"is_connected": "{entity_name} \u5df2\u9023\u7dda",
"is_gas": "{entity_name} \u5075\u6e2c\u5230\u6c23\u9ad4",
"is_hot": "{entity_name} \u71b1",
"is_light": "{entity_name} \u5075\u6e2c\u5230\u5149\u7dda\u4e2d",
"is_locked": "{entity_name} \u5df2\u4e0a\u9396",
"is_moist": "{entity_name} \u6f6e\u6fd5",
"is_motion": "{entity_name} \u5075\u6e2c\u5230\u52d5\u4f5c\u4e2d",
"is_moving": "{entity_name} \u79fb\u52d5\u4e2d",
"is_no_gas": "{entity_name} \u672a\u5075\u6e2c\u5230\u6c23\u9ad4",
"is_no_light": "{entity_name} \u672a\u5075\u6e2c\u5230\u5149\u7dda",
"is_no_motion": "{entity_name} \u672a\u5075\u6e2c\u5230\u52d5\u4f5c",
"is_no_problem": "{entity_name} \u672a\u5075\u6e2c\u5230\u554f\u984c",
"is_no_smoke": "{entity_name} \u672a\u5075\u6e2c\u5230\u7159\u9727",
"is_no_sound": "{entity_name} \u672a\u5075\u6e2c\u5230\u8072\u97f3",
"is_no_vibration": "{entity_name} \u672a\u5075\u6e2c\u5230\u9707\u52d5",
"is_not_bat_low": "{entity_name} \u96fb\u91cf\u6b63\u5e38",
"is_not_cold": "{entity_name} \u4e0d\u51b7",
"is_not_connected": "{entity_name} \u65b7\u7dda",
"is_not_hot": "{entity_name} \u4e0d\u71b1",
"is_not_locked": "{entity_name} \u89e3\u9396",
"is_not_moist": "{entity_name} \u4e7e\u71e5",
"is_not_moving": "{entity_name} \u672a\u5728\u79fb\u52d5",
"is_not_occupied": "{entity_name} \u672a\u6709\u4eba",
"is_not_open": "{entity_name} \u95dc\u9589",
"is_not_plugged_in": "{entity_name} \u672a\u63d2\u5165",
"is_not_powered": "{entity_name} \u672a\u901a\u96fb",
"is_not_present": "{entity_name} \u672a\u51fa\u73fe",
"is_not_unsafe": "{entity_name} \u5b89\u5168",
"is_occupied": "{entity_name} \u6709\u4eba",
"is_off": "{entity_name} \u95dc\u9589",
"is_on": "{entity_name} \u958b\u555f",
"is_open": "{entity_name} \u958b\u555f",
"is_plugged_in": "{entity_name} \u63d2\u5165",
"is_powered": "{entity_name} \u901a\u96fb",
"is_present": "{entity_name} \u51fa\u73fe",
"is_problem": "{entity_name} \u6b63\u5075\u6e2c\u5230\u554f\u984c",
"is_smoke": "{entity_name} \u6b63\u5075\u6e2c\u5230\u7159\u9727",
"is_sound": "{entity_name} \u6b63\u5075\u6e2c\u5230\u8072\u97f3",
"is_unsafe": "{entity_name} \u4e0d\u5b89\u5168",
"is_vibration": "{entity_name} \u6b63\u5075\u6e2c\u5230\u9707\u52d5"
"is_bat_low": "{entity_name}\u96fb\u91cf\u904e\u4f4e",
"is_cold": "{entity_name}\u51b7",
"is_connected": "{entity_name}\u5df2\u9023\u7dda",
"is_gas": "{entity_name}\u5075\u6e2c\u5230\u6c23\u9ad4",
"is_hot": "{entity_name}\u71b1",
"is_light": "{entity_name}\u5075\u6e2c\u5230\u5149\u7dda\u4e2d",
"is_locked": "{entity_name}\u5df2\u4e0a\u9396",
"is_moist": "{entity_name}\u6f6e\u6fd5",
"is_motion": "{entity_name}\u5075\u6e2c\u5230\u52d5\u4f5c\u4e2d",
"is_moving": "{entity_name}\u79fb\u52d5\u4e2d",
"is_no_gas": "{entity_name}\u672a\u5075\u6e2c\u5230\u6c23\u9ad4",
"is_no_light": "{entity_name}\u672a\u5075\u6e2c\u5230\u5149\u7dda",
"is_no_motion": "{entity_name}\u672a\u5075\u6e2c\u5230\u52d5\u4f5c",
"is_no_problem": "{entity_name}\u672a\u5075\u6e2c\u5230\u554f\u984c",
"is_no_smoke": "{entity_name}\u672a\u5075\u6e2c\u5230\u7159\u9727",
"is_no_sound": "{entity_name}\u672a\u5075\u6e2c\u5230\u8072\u97f3",
"is_no_vibration": "{entity_name}\u672a\u5075\u6e2c\u5230\u9707\u52d5",
"is_not_bat_low": "{entity_name}\u96fb\u91cf\u6b63\u5e38",
"is_not_cold": "{entity_name}\u4e0d\u51b7",
"is_not_connected": "{entity_name}\u65b7\u7dda",
"is_not_hot": "{entity_name}\u4e0d\u71b1",
"is_not_locked": "{entity_name}\u89e3\u9396",
"is_not_moist": "{entity_name}\u4e7e\u71e5",
"is_not_moving": "{entity_name}\u672a\u5728\u79fb\u52d5",
"is_not_occupied": "{entity_name}\u672a\u6709\u4eba",
"is_not_open": "{entity_name}\u95dc\u9589",
"is_not_plugged_in": "{entity_name}\u672a\u63d2\u5165",
"is_not_powered": "{entity_name}\u672a\u901a\u96fb",
"is_not_present": "{entity_name}\u672a\u51fa\u73fe",
"is_not_unsafe": "{entity_name}\u5b89\u5168",
"is_occupied": "{entity_name}\u6709\u4eba",
"is_off": "{entity_name}\u95dc\u9589",
"is_on": "{entity_name}\u958b\u555f",
"is_open": "{entity_name}\u958b\u555f",
"is_plugged_in": "{entity_name}\u63d2\u5165",
"is_powered": "{entity_name}\u901a\u96fb",
"is_present": "{entity_name}\u51fa\u73fe",
"is_problem": "{entity_name}\u6b63\u5075\u6e2c\u5230\u554f\u984c",
"is_smoke": "{entity_name}\u6b63\u5075\u6e2c\u5230\u7159\u9727",
"is_sound": "{entity_name}\u6b63\u5075\u6e2c\u5230\u8072\u97f3",
"is_unsafe": "{entity_name}\u4e0d\u5b89\u5168",
"is_vibration": "{entity_name}\u6b63\u5075\u6e2c\u5230\u9707\u52d5"
},
"trigger_type": {
"bat_low": "{entity_name} \u96fb\u91cf\u4f4e",
"closed": "{entity_name} \u5df2\u95dc\u9589",
"cold": "{entity_name} \u5df2\u8b8a\u51b7",
"connected": "{entity_name} \u5df2\u9023\u7dda",
"gas": "{entity_name} \u5df2\u958b\u59cb\u5075\u6e2c\u6c23\u9ad4",
"hot": "{entity_name} \u5df2\u8b8a\u71b1",
"light": "{entity_name} \u5df2\u958b\u59cb\u5075\u6e2c\u5149\u7dda",
"locked": "{entity_name} \u5df2\u4e0a\u9396",
"moist": "{entity_name} \u5df2\u8b8a\u6f6e\u6fd5",
"moist\u00a7": "{entity_name} \u5df2\u8b8a\u6f6e\u6fd5",
"motion": "{entity_name} \u5df2\u5075\u6e2c\u5230\u52d5\u4f5c",
"moving": "{entity_name} \u958b\u59cb\u79fb\u52d5",
"no_gas": "{entity_name} \u5df2\u505c\u6b62\u5075\u6e2c\u6c23\u9ad4",
"no_light": "{entity_name} \u5df2\u505c\u6b62\u5075\u6e2c\u5149\u7dda",
"no_motion": "{entity_name} \u5df2\u505c\u6b62\u5075\u6e2c\u52d5\u4f5c",
"no_problem": "{entity_name} \u5df2\u505c\u6b62\u5075\u6e2c\u554f\u984c",
"no_smoke": "{entity_name} \u5df2\u505c\u6b62\u5075\u6e2c\u7159\u9727",
"no_sound": "{entity_name} \u5df2\u505c\u6b62\u5075\u6e2c\u8072\u97f3",
"no_vibration": "{entity_name} \u5df2\u505c\u6b62\u5075\u6e2c\u9707\u52d5",
"not_bat_low": "{entity_name} \u96fb\u91cf\u6b63\u5e38",
"not_cold": "{entity_name} \u5df2\u4e0d\u51b7",
"not_connected": "{entity_name} \u5df2\u65b7\u7dda",
"not_hot": "{entity_name} \u5df2\u4e0d\u71b1",
"not_locked": "{entity_name} \u5df2\u89e3\u9396",
"not_moist": "{entity_name} \u5df2\u8b8a\u4e7e",
"not_moving": "{entity_name} \u505c\u6b62\u79fb\u52d5",
"not_occupied": "{entity_name} \u672a\u6709\u4eba",
"not_opened": "{entity_name} \u5df2\u95dc\u9589",
"not_plugged_in": "{entity_name} \u672a\u63d2\u5165",
"not_powered": "{entity_name} \u672a\u901a\u96fb",
"not_present": "{entity_name} \u672a\u51fa\u73fe",
"not_unsafe": "{entity_name} \u5df2\u5b89\u5168",
"occupied": "{entity_name} \u8b8a\u6210\u6709\u4eba",
"opened": "{entity_name} \u5df2\u958b\u555f",
"plugged_in": "{entity_name} \u5df2\u63d2\u5165",
"powered": "{entity_name} \u5df2\u901a\u96fb",
"present": "{entity_name} \u5df2\u51fa\u73fe",
"problem": "{entity_name} \u5df2\u5075\u6e2c\u5230\u554f\u984c",
"smoke": "{entity_name} \u5df2\u5075\u6e2c\u5230\u7159\u9727",
"sound": "{entity_name} \u5df2\u5075\u6e2c\u5230\u8072\u97f3",
"turned_off": "{entity_name} \u5df2\u95dc\u9589",
"turned_on": "{entity_name} \u5df2\u958b\u555f",
"unsafe": "{entity_name} \u5df2\u4e0d\u5b89\u5168",
"vibration": "{entity_name} \u5df2\u5075\u6e2c\u5230\u9707\u52d5"
"bat_low": "{entity_name}\u96fb\u91cf\u4f4e",
"closed": "{entity_name}\u5df2\u95dc\u9589",
"cold": "{entity_name}\u5df2\u8b8a\u51b7",
"connected": "{entity_name}\u5df2\u9023\u7dda",
"gas": "{entity_name}\u5df2\u958b\u59cb\u5075\u6e2c\u6c23\u9ad4",
"hot": "{entity_name}\u5df2\u8b8a\u71b1",
"light": "{entity_name}\u5df2\u958b\u59cb\u5075\u6e2c\u5149\u7dda",
"locked": "{entity_name}\u5df2\u4e0a\u9396",
"moist": "{entity_name}\u5df2\u8b8a\u6f6e\u6fd5",
"moist\u00a7": "{entity_name}\u5df2\u8b8a\u6f6e\u6fd5",
"motion": "{entity_name}\u5df2\u5075\u6e2c\u5230\u52d5\u4f5c",
"moving": "{entity_name}\u958b\u59cb\u79fb\u52d5",
"no_gas": "{entity_name}\u5df2\u505c\u6b62\u5075\u6e2c\u6c23\u9ad4",
"no_light": "{entity_name}\u5df2\u505c\u6b62\u5075\u6e2c\u5149\u7dda",
"no_motion": "{entity_name}\u5df2\u505c\u6b62\u5075\u6e2c\u52d5\u4f5c",
"no_problem": "{entity_name}\u5df2\u505c\u6b62\u5075\u6e2c\u554f\u984c",
"no_smoke": "{entity_name}\u5df2\u505c\u6b62\u5075\u6e2c\u7159\u9727",
"no_sound": "{entity_name}\u5df2\u505c\u6b62\u5075\u6e2c\u8072\u97f3",
"no_vibration": "{entity_name}\u5df2\u505c\u6b62\u5075\u6e2c\u9707\u52d5",
"not_bat_low": "{entity_name}\u96fb\u91cf\u6b63\u5e38",
"not_cold": "{entity_name}\u5df2\u4e0d\u51b7",
"not_connected": "{entity_name}\u5df2\u65b7\u7dda",
"not_hot": "{entity_name}\u5df2\u4e0d\u71b1",
"not_locked": "{entity_name}\u5df2\u89e3\u9396",
"not_moist": "{entity_name}\u5df2\u8b8a\u4e7e",
"not_moving": "{entity_name}\u505c\u6b62\u79fb\u52d5",
"not_occupied": "{entity_name}\u672a\u6709\u4eba",
"not_opened": "{entity_name}\u5df2\u95dc\u9589",
"not_plugged_in": "{entity_name}\u672a\u63d2\u5165",
"not_powered": "{entity_name}\u672a\u901a\u96fb",
"not_present": "{entity_name}\u672a\u51fa\u73fe",
"not_unsafe": "{entity_name}\u5df2\u5b89\u5168",
"occupied": "{entity_name}\u8b8a\u6210\u6709\u4eba",
"opened": "{entity_name}\u5df2\u958b\u555f",
"plugged_in": "{entity_name}\u5df2\u63d2\u5165",
"powered": "{entity_name}\u5df2\u901a\u96fb",
"present": "{entity_name}\u5df2\u51fa\u73fe",
"problem": "{entity_name}\u5df2\u5075\u6e2c\u5230\u554f\u984c",
"smoke": "{entity_name}\u5df2\u5075\u6e2c\u5230\u7159\u9727",
"sound": "{entity_name}\u5df2\u5075\u6e2c\u5230\u8072\u97f3",
"turned_off": "{entity_name}\u5df2\u95dc\u9589",
"turned_on": "{entity_name}\u5df2\u958b\u555f",
"unsafe": "{entity_name}\u5df2\u4e0d\u5b89\u5168",
"vibration": "{entity_name}\u5df2\u5075\u6e2c\u5230\u9707\u52d5"
}
}
}

View File

@@ -2,7 +2,7 @@
"domain": "bmw_connected_drive",
"name": "BMW Connected Drive",
"documentation": "https://www.home-assistant.io/integrations/bmw_connected_drive",
"requirements": ["bimmer_connected==0.6.2"],
"requirements": ["bimmer_connected==0.7.0"],
"dependencies": [],
"codeowners": ["@gerard33"]
}

View File

@@ -1,6 +1,7 @@
{
"config": {
"abort": {
"already_configured": "Aquesta impressora ja est\u00e0 configurada.",
"unsupported_model": "Aquest model d'impressora no \u00e9s compatible."
},
"error": {
@@ -8,6 +9,7 @@
"snmp_error": "El servidor SNMP s'ha tancat o la impressora no \u00e9s compatible.",
"wrong_host": "Nom de l'amfitri\u00f3 o adre\u00e7a IP inv\u00e0lids."
},
"flow_title": "Impressora Brother: {model} {serial_number}",
"step": {
"user": {
"data": {
@@ -16,6 +18,13 @@
},
"description": "Configura la integraci\u00f3 d'impressora Brother. Si tens problemes amb la configuraci\u00f3, visita: https://www.home-assistant.io/integrations/brother",
"title": "Impressora Brother"
},
"zeroconf_confirm": {
"data": {
"type": "Tipus d'impressora"
},
"description": "Vols afegir la impressora Brother {model} amb n\u00famero de s\u00e8rie `{serial_number}` a Home Assistant?",
"title": "Impressora Brother descoberta"
}
},
"title": "Impressora Brother"

View File

@@ -9,6 +9,7 @@
"snmp_error": "SNMP-Server deaktiviert oder Drucker nicht unterst\u00fctzt.",
"wrong_host": " Ung\u00fcltiger Hostname oder IP-Adresse"
},
"flow_title": "Brother-Drucker: {model} {serial_number}",
"step": {
"user": {
"data": {
@@ -17,6 +18,13 @@
},
"description": "Einrichten der Brother-Drucker-Integration. Wenn Du Probleme mit der Konfiguration hast, gehe zu: https://www.home-assistant.io/integrations/brother",
"title": "Brother Drucker"
},
"zeroconf_confirm": {
"data": {
"type": "Typ des Druckers"
},
"description": "M\u00f6chten Sie den Brother Drucker {model} mit der Seriennummer `{serial_number}` zum Home Assistant hinzuf\u00fcgen?",
"title": "Brother-Drucker entdeckt"
}
},
"title": "Brother Drucker"

View File

@@ -9,6 +9,7 @@
"snmp_error": "SNMP \u4f3a\u670d\u5668\u70ba\u95dc\u9589\u72c0\u614b\u6216\u5370\u8868\u6a5f\u4e0d\u652f\u63f4\u3002",
"wrong_host": "\u7121\u6548\u4e3b\u6a5f\u540d\u6216 IP \u4f4d\u5740"
},
"flow_title": "Brother \u5370\u8868\u6a5f\uff1a{model} {serial_number}",
"step": {
"user": {
"data": {
@@ -17,6 +18,13 @@
},
"description": "\u8a2d\u5b9a Brother \u5370\u8868\u6a5f\u6574\u5408\u3002\u5047\u5982\u9700\u8981\u5354\u52a9\uff0c\u8acb\u53c3\u8003\uff1ahttps://www.home-assistant.io/integrations/brother",
"title": "Brother \u5370\u8868\u6a5f"
},
"zeroconf_confirm": {
"data": {
"type": "\u5370\u8868\u6a5f\u985e\u578b"
},
"description": "\u662f\u5426\u8981\u5c07\u5e8f\u865f {serial_number} \u4e4bBrother \u5370\u8868\u6a5f {model} \u65b0\u589e\u81f3 Home Assistant\uff1f",
"title": "\u767c\u73fe Brother \u5370\u8868\u6a5f"
}
},
"title": "Brother \u5370\u8868\u6a5f"

View File

@@ -1,16 +1,16 @@
{
"device_automation": {
"action_type": {
"set_hvac_mode": "\u8b8a\u66f4 {entity_name} HVAC \u6a21\u5f0f",
"set_preset_mode": "\u8b8a\u66f4 {entity_name} \u8a2d\u5b9a\u6a21\u5f0f"
"set_hvac_mode": "\u8b8a\u66f4{entity_name} HVAC \u6a21\u5f0f",
"set_preset_mode": "\u8b8a\u66f4{entity_name}\u8a2d\u5b9a\u6a21\u5f0f"
},
"condition_type": {
"is_hvac_mode": "{entity_name} \u8a2d\u5b9a\u70ba\u6307\u5b9a HVAC \u6a21\u5f0f",
"is_preset_mode": "{entity_name} \u8a2d\u5b9a\u70ba\u6307\u5b9a\u8a2d\u5b9a\u6a21\u5f0f"
"is_hvac_mode": "{entity_name}\u8a2d\u5b9a\u70ba\u6307\u5b9a HVAC \u6a21\u5f0f",
"is_preset_mode": "{entity_name}\u8a2d\u5b9a\u70ba\u6307\u5b9a\u8a2d\u5b9a\u6a21\u5f0f"
},
"trigger_type": {
"current_humidity_changed": "{entity_name} \u91cf\u6e2c\u6fd5\u5ea6\u5df2\u8b8a\u66f4",
"current_temperature_changed": "{entity_name} \u91cf\u6e2c\u6eab\u5ea6\u5df2\u8b8a\u66f4",
"current_humidity_changed": "{entity_name}\u91cf\u6e2c\u6fd5\u5ea6\u5df2\u8b8a\u66f4",
"current_temperature_changed": "{entity_name}\u91cf\u6e2c\u6eab\u5ea6\u5df2\u8b8a\u66f4",
"hvac_mode_changed": "{entity_name} HVAC \u6a21\u5f0f\u5df2\u8b8a\u66f4"
}
}

View File

@@ -94,6 +94,7 @@ class BaseEditConfigView(HomeAssistantView):
self.data_schema = data_schema
self.post_write_hook = post_write_hook
self.data_validator = data_validator
self.mutation_lock = asyncio.Lock()
def _empty_config(self):
"""Empty config if file not found."""
@@ -114,8 +115,9 @@ class BaseEditConfigView(HomeAssistantView):
async def get(self, request, config_key):
"""Fetch device specific config."""
hass = request.app["hass"]
current = await self.read_config(hass)
value = self._get_value(hass, current, config_key)
async with self.mutation_lock:
current = await self.read_config(hass)
value = self._get_value(hass, current, config_key)
if value is None:
return self.json_message("Resource not found", 404)
@@ -148,10 +150,11 @@ class BaseEditConfigView(HomeAssistantView):
path = hass.config.path(self.path)
current = await self.read_config(hass)
self._write_value(hass, current, config_key, data)
async with self.mutation_lock:
current = await self.read_config(hass)
self._write_value(hass, current, config_key, data)
await hass.async_add_executor_job(_write, path, current)
await hass.async_add_executor_job(_write, path, current)
if self.post_write_hook is not None:
hass.async_create_task(
@@ -163,15 +166,16 @@ class BaseEditConfigView(HomeAssistantView):
async def delete(self, request, config_key):
"""Remove an entry."""
hass = request.app["hass"]
current = await self.read_config(hass)
value = self._get_value(hass, current, config_key)
path = hass.config.path(self.path)
async with self.mutation_lock:
current = await self.read_config(hass)
value = self._get_value(hass, current, config_key)
path = hass.config.path(self.path)
if value is None:
return self.json_message("Resource not found", 404)
if value is None:
return self.json_message("Resource not found", 404)
self._delete_value(hass, current, config_key)
await hass.async_add_executor_job(_write, path, current)
self._delete_value(hass, current, config_key)
await hass.async_add_executor_job(_write, path, current)
if self.post_write_hook is not None:
hass.async_create_task(self.post_write_hook(ACTION_DELETE, config_key))

View File

@@ -1,20 +1,20 @@
{
"device_automation": {
"condition_type": {
"is_closed": "{entity_name} \u5df2\u95dc\u9589",
"is_closing": "{entity_name} \u6b63\u5728\u95dc\u9589",
"is_open": "{entity_name} \u5df2\u958b\u555f",
"is_opening": "{entity_name} \u6b63\u5728\u958b\u555f",
"is_position": "\u76ee\u524d {entity_name} \u4f4d\u7f6e\u70ba",
"is_tilt_position": "\u76ee\u524d {entity_name} \u6a19\u984c\u4f4d\u7f6e\u70ba"
"is_closed": "{entity_name}\u5df2\u95dc\u9589",
"is_closing": "{entity_name}\u6b63\u5728\u95dc\u9589",
"is_open": "{entity_name}\u5df2\u958b\u555f",
"is_opening": "{entity_name}\u6b63\u5728\u958b\u555f",
"is_position": "\u76ee\u524d{entity_name}\u4f4d\u7f6e\u70ba",
"is_tilt_position": "\u76ee\u524d{entity_name}\u6a19\u984c\u4f4d\u7f6e\u70ba"
},
"trigger_type": {
"closed": "{entity_name} \u5df2\u95dc\u9589",
"closing": "{entity_name} \u6b63\u5728\u95dc\u9589",
"opened": "{entity_name} \u5df2\u958b\u555f",
"opening": "{entity_name} \u6b63\u5728\u958b\u555f",
"position": "{entity_name} \u4f4d\u7f6e\u8b8a\u66f4",
"tilt_position": "{entity_name} \u6a19\u984c\u4f4d\u7f6e\u8b8a\u66f4"
"closed": "{entity_name}\u5df2\u95dc\u9589",
"closing": "{entity_name}\u6b63\u5728\u95dc\u9589",
"opened": "{entity_name}\u5df2\u958b\u555f",
"opening": "{entity_name}\u6b63\u5728\u958b\u555f",
"position": "{entity_name}\u4f4d\u7f6e\u8b8a\u66f4",
"tilt_position": "{entity_name}\u6a19\u984c\u4f4d\u7f6e\u8b8a\u66f4"
}
}
}

View File

@@ -77,15 +77,21 @@
"remote_button_short_release": "Bot\u00f3 \"{subtype}\" alliberat",
"remote_button_triple_press": "Bot\u00f3 \"{subtype}\" clicat tres vegades consecutives",
"remote_double_tap": "Dispositiu \"{subtype}\" tocat dues vegades",
"remote_double_tap_any_side": "Dispositiu tocat dues vegades a alguna cara",
"remote_falling": "Dispositiu en caiguda lliure",
"remote_flip_180_degrees": "Dispositiu voltejat 180 graus",
"remote_flip_90_degrees": "Dispositiu voltejat 90 graus",
"remote_gyro_activated": "Dispositiu sacsejat",
"remote_moved": "Dispositiu mogut amb la \"{subtype}\" amunt",
"remote_moved_any_side": "Dispositiu mogut amb alguna cara amunt",
"remote_rotate_from_side_1": "Dispositiu rotat de la \"cara 1\" a la \"{subtype}\"",
"remote_rotate_from_side_2": "Dispositiu rotat de la \"cara 2\" a la \"{subtype}\"",
"remote_rotate_from_side_3": "Dispositiu rotat de la \"cara 3\" a la \"{subtype}\"",
"remote_rotate_from_side_4": "Dispositiu rotat de la \"cara 4\" a la \"{subtype}\"",
"remote_rotate_from_side_5": "Dispositiu rotat de la \"cara 5\" a la \"{subtype}\"",
"remote_rotate_from_side_6": "Dispositiu rotat de la \"cara 6\" a la \"{subtype}\""
"remote_rotate_from_side_6": "Dispositiu rotat de la \"cara 6\" a la \"{subtype}\"",
"remote_turned_clockwise": "Dispositiu girat en sentit horari",
"remote_turned_counter_clockwise": "Dispositiu girat en sentit antihorari"
}
},
"options": {

View File

@@ -1,8 +1,8 @@
{
"device_automation": {
"condition_type": {
"is_home": "{entity_name} \u5728\u5bb6",
"is_not_home": "{entity_name} \u4e0d\u5728\u5bb6"
"is_home": "{entity_name}\u5728\u5bb6",
"is_not_home": "{entity_name}\u4e0d\u5728\u5bb6"
}
}
}

View File

@@ -15,7 +15,7 @@
"port": "N\u00famero de port"
},
"description": "Configura l'Elgato Key Light per integrar-lo amb Home Assistant.",
"title": "Enlla\u00e7a Elgato Key Light"
"title": "Enlla\u00e7 amb Elgato Key Light"
},
"zeroconf_confirm": {
"description": "Vols afegir l'Elgato Key Light amb n\u00famero de s\u00e8rie `{serial_number}` a Home Assistant?",

View File

@@ -19,9 +19,9 @@
},
"zeroconf_confirm": {
"description": "\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c Elgato Key Light \u0441 \u0441\u0435\u0440\u0438\u0439\u043d\u044b\u043c \u043d\u043e\u043c\u0435\u0440\u043e\u043c `{serial_number}`?",
"title": "\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e Elgado Key Light"
"title": "\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e Elgato Key Light"
}
},
"title": "Elgado Key Light"
"title": "Elgato Key Light"
}
}

View File

@@ -1,16 +1,16 @@
{
"device_automation": {
"action_type": {
"turn_off": "\u95dc\u9589 {entity_name}",
"turn_on": "\u958b\u555f {entity_name}"
"turn_off": "\u95dc\u9589{entity_name}",
"turn_on": "\u958b\u555f{entity_name}"
},
"condition_type": {
"is_off": "{entity_name} \u95dc\u9589",
"is_on": "{entity_name} \u958b\u555f"
"is_off": "{entity_name}\u95dc\u9589",
"is_on": "{entity_name}\u958b\u555f"
},
"trigger_type": {
"turned_off": "{entity_name} \u5df2\u95dc\u9589",
"turned_on": "{entity_name} \u5df2\u958b\u555f"
"turned_off": "{entity_name}\u5df2\u95dc\u9589",
"turned_on": "{entity_name}\u5df2\u958b\u555f"
}
}
}

View File

@@ -3,7 +3,7 @@
"name": "Home Assistant Frontend",
"documentation": "https://www.home-assistant.io/integrations/frontend",
"requirements": [
"home-assistant-frontend==20200130.1"
"home-assistant-frontend==20200130.3"
],
"dependencies": [
"api",

View File

@@ -0,0 +1,24 @@
{
"config": {
"abort": {
"already_configured": "Aquest compte ja est\u00e0 configurat."
},
"error": {
"cannot_connect": "No s'ha pogut connectar, torna-ho a provar.",
"invalid_auth": "Autenticaci\u00f3 inv\u00e0lida.",
"too_many_requests": "Massa sol\u00b7licituds, torna-ho a intentar m\u00e9s tard.",
"unknown": "Error inesperat."
},
"step": {
"user": {
"data": {
"password": "Contrasenya",
"username": "Nom d'usuari"
},
"description": "Introdueix les teves credencials.",
"title": "Garmin Connect"
}
},
"title": "Garmin Connect"
}
}

View File

@@ -0,0 +1,24 @@
{
"config": {
"abort": {
"already_configured": "Dieses Konto ist bereits konfiguriert."
},
"error": {
"cannot_connect": "Verbindung fehlgeschlagen. Bitte versuchen Sie es erneut.",
"invalid_auth": "Ung\u00fcltige Authentifizierung.",
"too_many_requests": "Zu viele Anfragen, wiederholen Sie es sp\u00e4ter.",
"unknown": "Unerwarteter Fehler."
},
"step": {
"user": {
"data": {
"password": "Passwort",
"username": "Benutzername"
},
"description": "Geben Sie Ihre Zugangsdaten ein.",
"title": "Garmin Connect"
}
},
"title": "Garmin Connect"
}
}

View File

@@ -0,0 +1,24 @@
{
"config": {
"abort": {
"already_configured": "Esta cuenta ya est\u00e1 configurada."
},
"error": {
"cannot_connect": "No se pudo conectar, por favor, int\u00e9ntelo de nuevo.",
"invalid_auth": "Autenticaci\u00f3n inv\u00e1lida",
"too_many_requests": "Demasiadas solicitudes, vuelva a intentarlo m\u00e1s tarde.",
"unknown": "Error inesperado"
},
"step": {
"user": {
"data": {
"password": "Contrase\u00f1a",
"username": "Nombre de usuario"
},
"description": "Introduzca sus credenciales.",
"title": "Garmin Connect"
}
},
"title": "Garmin Connect"
}
}

View File

@@ -0,0 +1,24 @@
{
"config": {
"abort": {
"already_configured": "Questo account \u00e8 gi\u00e0 configurato."
},
"error": {
"cannot_connect": "Impossibile connettersi, si prega di riprovare.",
"invalid_auth": "Autenticazione non valida.",
"too_many_requests": "Troppe richieste, riprovare pi\u00f9 tardi.",
"unknown": "Errore imprevisto."
},
"step": {
"user": {
"data": {
"password": "Password",
"username": "Nome utente"
},
"description": "Inserisci le tue credenziali",
"title": "Garmin Connect"
}
},
"title": "Garmin Connect"
}
}

View File

@@ -0,0 +1,24 @@
{
"config": {
"abort": {
"already_configured": "D\u00ebse Kont ass scho konfigur\u00e9iert"
},
"error": {
"cannot_connect": "Feeler beim verbannen, prob\u00e9iert w.e.g. nach emol.",
"invalid_auth": "Ong\u00eblteg Authentifikatioun.",
"too_many_requests": "Ze vill Ufroen, prob\u00e9iert sp\u00e9ider nach emol.",
"unknown": "Onerwaarte Feeler."
},
"step": {
"user": {
"data": {
"password": "Passwuert",
"username": "Benotzernumm"
},
"description": "F\u00ebllt \u00e4r Umeldungs Informatiounen aus.",
"title": "Garmin Connect"
}
},
"title": "Garmin Connect"
}
}

View File

@@ -16,9 +16,9 @@
"username": "Anv\u00e4ndarnamn"
},
"description": "Ange dina anv\u00e4ndaruppgifter.",
"title": ""
"title": "Garmin Connect"
}
},
"title": ""
"title": "Garmin Connect"
}
}

View File

@@ -0,0 +1,24 @@
{
"config": {
"abort": {
"already_configured": "\u6b64\u5e33\u865f\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210\u3002"
},
"error": {
"cannot_connect": "\u9023\u7dda\u5931\u6557\uff0c\u8acb\u518d\u8a66\u4e00\u6b21\u3002",
"invalid_auth": "\u9a57\u8b49\u7121\u6548\u3002",
"too_many_requests": "\u8acb\u6c42\u6b21\u6578\u904e\u591a\uff0c\u8acb\u7a0d\u5f8c\u91cd\u8a66\u3002",
"unknown": "\u672a\u9810\u671f\u932f\u8aa4\u3002"
},
"step": {
"user": {
"data": {
"password": "\u5bc6\u78bc",
"username": "\u4f7f\u7528\u8005\u540d\u7a31"
},
"description": "\u8f38\u5165\u6191\u8b49\u3002",
"title": "Garmin Connect"
}
},
"title": "Garmin Connect"
}
}

View File

@@ -27,7 +27,7 @@ GARMIN_ENTITY_LIST = {
False,
],
"netCalorieGoal": ["Net Calorie Goal", "cal", "mdi:food", None, False],
"totalDistanceMeters": ["Total Distance Mtr", "mtr", "mdi:walk", None, True],
"totalDistanceMeters": ["Total Distance Mtr", "m", "mdi:walk", None, True],
"wellnessStartTimeLocal": [
"Wellness Start Time",
"",
@@ -43,7 +43,7 @@ GARMIN_ENTITY_LIST = {
False,
],
"wellnessDescription": ["Wellness Description", "", "mdi:clock", None, False],
"wellnessDistanceMeters": ["Wellness Distance Mtr", "mtr", "mdi:walk", None, False],
"wellnessDistanceMeters": ["Wellness Distance Mtr", "m", "mdi:walk", None, False],
"wellnessActiveKilocalories": [
"Wellness Active KiloCalories",
"kcal",
@@ -52,16 +52,16 @@ GARMIN_ENTITY_LIST = {
False,
],
"wellnessKilocalories": ["Wellness KiloCalories", "kcal", "mdi:food", None, False],
"highlyActiveSeconds": ["Highly Active Time", "minutes", "mdi:fire", None, False],
"activeSeconds": ["Active Time", "minutes", "mdi:fire", None, True],
"sedentarySeconds": ["Sedentary Time", "minutes", "mdi:seat", None, True],
"sleepingSeconds": ["Sleeping Time", "minutes", "mdi:sleep", None, True],
"measurableAwakeDuration": ["Awake Duration", "minutes", "mdi:sleep", None, True],
"measurableAsleepDuration": ["Sleep Duration", "minutes", "mdi:sleep", None, True],
"floorsAscendedInMeters": ["Floors Ascended Mtr", "mtr", "mdi:stairs", None, False],
"highlyActiveSeconds": ["Highly Active Time", "min", "mdi:fire", None, False],
"activeSeconds": ["Active Time", "min", "mdi:fire", None, True],
"sedentarySeconds": ["Sedentary Time", "min", "mdi:seat", None, True],
"sleepingSeconds": ["Sleeping Time", "min", "mdi:sleep", None, True],
"measurableAwakeDuration": ["Awake Duration", "min", "mdi:sleep", None, True],
"measurableAsleepDuration": ["Sleep Duration", "min", "mdi:sleep", None, True],
"floorsAscendedInMeters": ["Floors Ascended Mtr", "m", "mdi:stairs", None, False],
"floorsDescendedInMeters": [
"Floors Descended Mtr",
"mtr",
"m",
"mdi:stairs",
None,
False,
@@ -97,52 +97,46 @@ GARMIN_ENTITY_LIST = {
"averageStressLevel": ["Avg Stress Level", "", "mdi:flash-alert", None, True],
"maxStressLevel": ["Max Stress Level", "", "mdi:flash-alert", None, True],
"stressQualifier": ["Stress Qualifier", "", "mdi:flash-alert", None, False],
"stressDuration": ["Stress Duration", "minutes", "mdi:flash-alert", None, False],
"stressDuration": ["Stress Duration", "min", "mdi:flash-alert", None, False],
"restStressDuration": [
"Rest Stress Duration",
"minutes",
"min",
"mdi:flash-alert",
None,
True,
],
"activityStressDuration": [
"Activity Stress Duration",
"minutes",
"min",
"mdi:flash-alert",
None,
True,
],
"uncategorizedStressDuration": [
"Uncat. Stress Duration",
"minutes",
"min",
"mdi:flash-alert",
None,
True,
],
"totalStressDuration": [
"Total Stress Duration",
"minutes",
"mdi:flash-alert",
None,
True,
],
"lowStressDuration": [
"Low Stress Duration",
"minutes",
"min",
"mdi:flash-alert",
None,
True,
],
"lowStressDuration": ["Low Stress Duration", "min", "mdi:flash-alert", None, True],
"mediumStressDuration": [
"Medium Stress Duration",
"minutes",
"min",
"mdi:flash-alert",
None,
True,
],
"highStressDuration": [
"High Stress Duration",
"minutes",
"min",
"mdi:flash-alert",
None,
True,
@@ -192,19 +186,19 @@ GARMIN_ENTITY_LIST = {
],
"moderateIntensityMinutes": [
"Moderate Intensity",
"minutes",
"min",
"mdi:flash-alert",
None,
False,
],
"vigorousIntensityMinutes": [
"Vigorous Intensity",
"minutes",
"min",
"mdi:run-fast",
None,
False,
],
"intensityMinutesGoal": ["Intensity Goal", "minutes", "mdi:run-fast", None, False],
"intensityMinutesGoal": ["Intensity Goal", "min", "mdi:run-fast", None, False],
"bodyBatteryChargedValue": [
"Body Battery Charged",
"%",
@@ -262,21 +256,21 @@ GARMIN_ENTITY_LIST = {
"brpm",
"mdi:progress-clock",
None,
True,
False,
],
"lowestRespirationValue": [
"Lowest Respiration",
"brpm",
"mdi:progress-clock",
None,
True,
False,
],
"latestRespirationValue": [
"Latest Respiration",
"brpm",
"mdi:progress-clock",
None,
True,
False,
],
"latestRespirationTimeGMT": [
"Latest Respiration Update",

View File

@@ -165,12 +165,16 @@ class GarminConnectSensor(Entity):
return
data = self._data.data
if "Duration" in self._type:
self._state = data[self._type] // 60
elif "Seconds" in self._type:
self._state = data[self._type] // 60
else:
self._state = data[self._type]
try:
if "Duration" in self._type and data[self._type]:
self._state = data[self._type] // 60
elif "Seconds" in self._type and data[self._type]:
self._state = data[self._type] // 60
else:
self._state = data[self._type]
except KeyError:
_LOGGER.debug("Entity type %s not found in fetched data", self._type)
return
_LOGGER.debug(
"Entity %s set to state %s %s", self._type, self._state, self._unit

View File

@@ -8,7 +8,7 @@
"data": {
"radius": "Radi"
},
"title": "Introdueix els detalls del filtre."
"title": "Introducci\u00f3 dels detalls del filtre."
}
},
"title": "GeoNet NZ Volcano"

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"already_configured": "La integraci\u00f3 GIO\u015a per a aquesta estaci\u00f3 ja est\u00e0 configurada."
},
"error": {
"cannot_connect": "No s'ha pogut connectar al servidor de GIO\u015a.",
"invalid_sensors_data": "Les dades dels sensors d'aquesta estaci\u00f3 de mesura s\u00f3n inv\u00e0lides.",

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Kiszolg\u00e1l\u00f3 m\u00e1r konfigur\u00e1lva van."
},
"error": {
"cannot_connect": "Nem lehet csatlakozni a kiszolg\u00e1l\u00f3hoz",
"wrong_version": "Nem t\u00e1mogatott verzi\u00f3 (2 vagy 3 csak)"
},
"step": {
"user": {
"data": {
"host": "Kiszolg\u00e1l\u00f3",
"name": "N\u00e9v",
"password": "Jelsz\u00f3",
"port": "Port",
"ssl": "Az SSL / TLS haszn\u00e1lat\u00e1val csatlakozzon a Glances rendszerhez",
"username": "Felhaszn\u00e1l\u00f3n\u00e9v",
"verify_ssl": "A rendszer tan\u00fas\u00edt\u00e1s\u00e1nak ellen\u0151rz\u00e9se",
"version": "Glances API-verzi\u00f3 (2 vagy 3)"
},
"title": "Glances Be\u00e1ll\u00edt\u00e1sa"
}
},
"title": "Glances"
},
"options": {
"step": {
"init": {
"data": {
"scan_interval": "Friss\u00edt\u00e9si gyakoris\u00e1g"
},
"description": "A Glances be\u00e1ll\u00edt\u00e1sainak konfigur\u00e1l\u00e1sa"
}
}
}
}

View File

@@ -133,7 +133,6 @@ DEVICE_CLASS_TO_GOOGLE_TYPES = {
(binary_sensor.DOMAIN, binary_sensor.DEVICE_CLASS_OPENING): TYPE_SENSOR,
(binary_sensor.DOMAIN, binary_sensor.DEVICE_CLASS_WINDOW): TYPE_SENSOR,
(media_player.DOMAIN, media_player.DEVICE_CLASS_TV): TYPE_TV,
(media_player.DOMAIN, media_player.DEVICE_CLASS_SPEAKER): TYPE_SPEAKER,
(sensor.DOMAIN, sensor.DEVICE_CLASS_TEMPERATURE): TYPE_SENSOR,
(sensor.DOMAIN, sensor.DEVICE_CLASS_HUMIDITY): TYPE_SENSOR,
}
@@ -146,3 +145,5 @@ STORE_AGENT_USER_IDS = "agent_user_ids"
SOURCE_CLOUD = "cloud"
SOURCE_LOCAL = "local"
NOT_EXPOSE_LOCAL = {TYPE_ALARM, TYPE_LOCK}

View File

@@ -28,6 +28,7 @@ from .const import (
DOMAIN,
DOMAIN_TO_GOOGLE_TYPES,
ERR_FUNCTION_NOT_SUPPORTED,
NOT_EXPOSE_LOCAL,
SOURCE_LOCAL,
STORE_AGENT_USER_IDS,
)
@@ -351,6 +352,18 @@ class GoogleEntity:
"""If entity should be exposed."""
return self.config.should_expose(self.state)
@callback
def should_expose_local(self) -> bool:
"""Return if the entity should be exposed locally."""
return (
self.should_expose()
and get_google_type(
self.state.domain, self.state.attributes.get(ATTR_DEVICE_CLASS)
)
not in NOT_EXPOSE_LOCAL
and not self.might_2fa()
)
@callback
def is_supported(self) -> bool:
"""Return if the entity is supported by Google."""
@@ -401,7 +414,7 @@ class GoogleEntity:
if aliases:
device["name"]["nicknames"] = [name] + aliases
if self.config.is_local_sdk_active:
if self.config.is_local_sdk_active and self.should_expose_local():
device["otherDeviceIds"] = [{"deviceId": self.entity_id}]
device["customData"] = {
"webhookId": self.config.local_sdk_webhook_id,

View File

@@ -243,9 +243,7 @@ async def async_devices_reachable(hass, data: RequestData, payload):
"devices": [
entity.reachable_device_serialize()
for entity in async_get_entities(hass, data.config)
if entity.entity_id in google_ids
and entity.should_expose()
and not entity.might_2fa()
if entity.entity_id in google_ids and entity.should_expose_local()
]
}

View File

@@ -194,7 +194,7 @@ async def async_setup(hass, config):
await hass.components.panel_custom.async_register_panel(
frontend_url_path="hassio",
webcomponent_name="hassio-main",
sidebar_title="Hass.io",
sidebar_title="Supervisor",
sidebar_icon="hass:home-assistant",
js_url="/api/hassio/app/entrypoint.js",
embed_iframe=True,

View File

@@ -227,7 +227,11 @@ class HomematicipSmokeDetector(HomematicipGenericDevice, BinarySensorDevice):
@property
def is_on(self) -> bool:
"""Return true if smoke is detected."""
return self._device.smokeDetectorAlarmType != SmokeDetectorAlarmType.IDLE_OFF
if self._device.smokeDetectorAlarmType:
return (
self._device.smokeDetectorAlarmType != SmokeDetectorAlarmType.IDLE_OFF
)
return False
class HomematicipWaterDetector(HomematicipGenericDevice, BinarySensorDevice):

View File

@@ -24,7 +24,7 @@
"username": "Nom d'usuari"
},
"description": "Introdueix les dades d\u2019acc\u00e9s del dispositiu. El nom d\u2019usuari i contrasenya s\u00f3n opcionals, per\u00f2 habiliten m\u00e9s funcions de la integraci\u00f3. D'altra banda, (mentre la integraci\u00f3 estigui activa) l'\u00fas d'una connexi\u00f3 autoritzada pot causar problemes per accedir a la interf\u00edcie web del dispositiu des de fora de Home Assistant i viceversa.",
"title": "Con de Huawei LTE"
"title": "Configuraci\u00f3 de Huawei LTE"
}
},
"title": "Huawei LTE"

View File

@@ -510,7 +510,7 @@ async def async_migrate_entry(hass: HomeAssistantType, config_entry: ConfigEntry
"""Migrate config entry to new version."""
if config_entry.version == 1:
options = config_entry.options
recipient = options[CONF_RECIPIENT]
recipient = options.get(CONF_RECIPIENT)
if isinstance(recipient, str):
options[CONF_RECIPIENT] = [x.strip() for x in recipient.split(",")]
config_entry.version = 2

View File

@@ -6,6 +6,7 @@ from aiohue.util import normalize_bridge_id
import voluptuous as vol
from homeassistant import config_entries, core
from homeassistant.components import persistent_notification
from homeassistant.const import CONF_HOST
from homeassistant.helpers import config_validation as cv, device_registry as dr
@@ -142,8 +143,20 @@ async def async_setup_entry(
sw_version=config.swversion,
)
if config.swupdate2_bridge_state == "readytoinstall":
err = "Please check for software updates of the bridge in the Philips Hue App."
if config.modelid == "BSB002" and config.swversion < "1935144040":
persistent_notification.async_create(
hass,
"Your Hue hub has a known security vulnerability ([CVE-2020-6007](https://cve.circl.lu/cve/CVE-2020-6007)). Go to the Hue app and check for software updates.",
"Signify Hue",
"hue_hub_firmware",
)
elif config.swupdate2_bridge_state == "readytoinstall":
err = (
"Please check for software updates of the bridge in the Philips Hue App.",
"Signify Hue",
"hue_hub_firmware",
)
_LOGGER.warning(err)
return True

View File

@@ -209,7 +209,7 @@ class GenericHueSensor(entity.Entity):
Only used by the generic entity update service.
"""
await self.bridge.sensor_manager.coordinator.coordinator.async_request_refresh()
await self.bridge.sensor_manager.coordinator.async_request_refresh()
@property
def device_info(self):

View File

@@ -22,7 +22,7 @@
"username": "Correu electr\u00f2nic"
},
"description": "Introdueix les teves credencials",
"title": "credencials d'iCloud"
"title": "Credencials d'iCloud"
},
"verification_code": {
"data": {

View File

@@ -26,6 +26,7 @@ from .const import (
DEVICE_DISPLAY_NAME,
DEVICE_ID,
DEVICE_LOCATION,
DEVICE_LOCATION_HORIZONTAL_ACCURACY,
DEVICE_LOCATION_LATITUDE,
DEVICE_LOCATION_LONGITUDE,
DEVICE_LOST_MODE_CAPABLE,
@@ -175,8 +176,9 @@ class IcloudAccount:
def _determine_interval(self) -> int:
"""Calculate new interval between two API fetch (in minutes)."""
intervals = {}
intervals = {"default": self._max_interval}
for device in self._devices.values():
# Max interval if no location
if device.location is None:
continue
@@ -186,10 +188,11 @@ class IcloudAccount:
self.hass,
device.location[DEVICE_LOCATION_LATITUDE],
device.location[DEVICE_LOCATION_LONGITUDE],
device.location[DEVICE_LOCATION_HORIZONTAL_ACCURACY],
).result()
# Max interval if in zone
if current_zone is not None:
intervals[device.name] = self._max_interval
continue
zones = (
@@ -209,6 +212,7 @@ class IcloudAccount:
)
distances.append(round(zone_distance / 1000, 1))
# Max interval if no zone
if not distances:
continue
mindistance = min(distances)
@@ -331,14 +335,13 @@ class IcloudDevice:
device_status = DEVICE_STATUS_CODES.get(self._status[DEVICE_STATUS], "error")
self._attrs[ATTR_DEVICE_STATUS] = device_status
if self._status[DEVICE_BATTERY_STATUS] != "Unknown":
self._battery_level = int(self._status.get(DEVICE_BATTERY_LEVEL, 0) * 100)
self._battery_status = self._status[DEVICE_BATTERY_STATUS]
low_power_mode = self._status[DEVICE_LOW_POWER_MODE]
self._battery_status = self._status[DEVICE_BATTERY_STATUS]
self._attrs[ATTR_BATTERY_STATUS] = self._battery_status
device_battery_level = self._status.get(DEVICE_BATTERY_LEVEL, 0)
if self._battery_status != "Unknown" and device_battery_level is not None:
self._battery_level = int(device_battery_level * 100)
self._attrs[ATTR_BATTERY] = self._battery_level
self._attrs[ATTR_BATTERY_STATUS] = self._battery_status
self._attrs[ATTR_LOW_POWER_MODE] = low_power_mode
self._attrs[ATTR_LOW_POWER_MODE] = self._status[DEVICE_LOW_POWER_MODE]
if (
self._status[DEVICE_LOCATION]

View File

@@ -1,17 +1,17 @@
{
"device_automation": {
"action_type": {
"toggle": "\u5207\u63db {entity_name}",
"turn_off": "\u95dc\u9589 {entity_name}",
"turn_on": "\u958b\u555f {entity_name}"
"toggle": "\u5207\u63db{entity_name}",
"turn_off": "\u95dc\u9589{entity_name}",
"turn_on": "\u958b\u555f{entity_name}"
},
"condition_type": {
"is_off": "{entity_name} \u5df2\u95dc\u9589",
"is_on": "{entity_name} \u5df2\u958b\u555f"
"is_off": "{entity_name}\u5df2\u95dc\u9589",
"is_on": "{entity_name}\u5df2\u958b\u555f"
},
"trigger_type": {
"turned_off": "{entity_name} \u5df2\u95dc\u9589",
"turned_on": "{entity_name} \u5df2\u958b\u555f"
"turned_off": "{entity_name}\u5df2\u95dc\u9589",
"turned_on": "{entity_name}\u5df2\u958b\u555f"
}
}
}

View File

@@ -1,13 +1,9 @@
{
"config": {
"abort": {
"username_exists": "\u0412\u0435\u0447\u0435 \u0438\u043c\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d \u043f\u0440\u043e\u0444\u0438\u043b"
},
"error": {
"access": "\u041d\u044f\u043c\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e Enedis.fr, \u043c\u043e\u043b\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e\u0441\u0442\u0442\u0430 \u0441\u0438",
"enedis": "Enedis.fr \u043e\u0442\u0433\u043e\u0432\u043e\u0440\u0438 \u0441 \u0433\u0440\u0435\u0448\u043a\u0430: \u043c\u043e\u043b\u044f, \u043e\u043f\u0438\u0442\u0430\u0439\u0442\u0435 \u043e\u0442\u043d\u043e\u0432\u043e \u043f\u043e-\u043a\u044a\u0441\u043d\u043e (\u043e\u0431\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u043e \u043d\u0435 \u043c\u0435\u0436\u0434\u0443 23:00 \u0438 02:00)",
"unknown": "\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430: \u043c\u043e\u043b\u044f, \u043e\u043f\u0438\u0442\u0430\u0439\u0442\u0435 \u043e\u0442\u043d\u043e\u0432\u043e \u043f\u043e-\u043a\u044a\u0441\u043d\u043e (\u043e\u0431\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u043e \u043d\u0435 \u043c\u0435\u0436\u0434\u0443 23:00 \u0438 02:00)",
"username_exists": "\u0412\u0435\u0447\u0435 \u0438\u043c\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043d \u043f\u0440\u043e\u0444\u0438\u043b",
"wrong_login": "\u0413\u0440\u0435\u0448\u043a\u0430 \u043f\u0440\u0438 \u0432\u043b\u0438\u0437\u0430\u043d\u0435: \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0438\u043c\u0435\u0439\u043b\u0430 \u0438 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 \u0441\u0438"
},
"step": {

View File

@@ -1,13 +1,12 @@
{
"config": {
"abort": {
"username_exists": "El compte ja ha estat configurat"
"already_configured": "El compte ja ha estat configurat"
},
"error": {
"access": "No s'ha pogut accedir a Enedis.fr, comprova la teva connexi\u00f3 a Internet",
"enedis": "Enedis.fr ha respost amb un error: torna-ho a provar m\u00e9s tard (millo no entre les 23:00 i les 14:00)",
"unknown": "Error desconegut: torna-ho a provar m\u00e9s tard (millor no entre les 23:00 i les 14:00)",
"username_exists": "El compte ja ha estat configurat",
"wrong_login": "Error d\u2019inici de sessi\u00f3: comprova el teu correu electr\u00f2nic i la contrasenya"
},
"step": {

View File

@@ -1,14 +1,12 @@
{
"config": {
"abort": {
"already_configured": "Kontoen er allerede konfigureret",
"username_exists": "Kontoen er allerede konfigureret"
"already_configured": "Kontoen er allerede konfigureret"
},
"error": {
"access": "Kunne ikke f\u00e5 adgang til Enedis.fr, kontroller din internetforbindelse",
"enedis": "Enedis.fr svarede med en fejl: Pr\u00f8v igen senere (normalt ikke mellem 23:00 og 02:00)",
"unknown": "Ukendt fejl: Pr\u00f8v igen senere (normalt ikke mellem 23:00 og 02:00)",
"username_exists": "Kontoen er allerede konfigureret",
"wrong_login": "Loginfejl: Kontroller din e-mail og adgangskode"
},
"step": {

View File

@@ -1,13 +1,12 @@
{
"config": {
"abort": {
"username_exists": "Konto bereits konfiguriert"
"already_configured": "Konto bereits konfiguriert"
},
"error": {
"access": "Konnte nicht auf Enedis.fr zugreifen, \u00fcberpr\u00fcfe bitte die Internetverbindung",
"enedis": "Enedis.fr antwortete mit einem Fehler: wiederhole den Vorgang sp\u00e4ter (in der Regel nicht zwischen 23 Uhr und 2 Uhr morgens)",
"unknown": "Unbekannter Fehler: Wiederhole den Vorgang sp\u00e4ter (in der Regel nicht zwischen 23 Uhr und 2 Uhr morgens)",
"username_exists": "Konto bereits konfiguriert",
"wrong_login": "Login-Fehler: Pr\u00fcfe bitte E-Mail & Passwort"
},
"step": {

View File

@@ -1,14 +1,12 @@
{
"config": {
"abort": {
"already_configured": "Account already configured",
"username_exists": "Account already configured"
"already_configured": "Account already configured"
},
"error": {
"access": "Could not access to Enedis.fr, please check your internet connection",
"enedis": "Enedis.fr answered with an error: please retry later (usually not between 11PM and 2AM)",
"unknown": "Unknown error: please retry later (usually not between 11PM and 2AM)",
"username_exists": "Account already configured",
"wrong_login": "Login error: please check your email & password"
},
"step": {

View File

@@ -1,13 +1,9 @@
{
"config": {
"abort": {
"username_exists": "La cuenta ya ha sido configurada"
},
"error": {
"access": "No se pudo acceder a Enedis.fr, compruebe su conexi\u00f3n a Internet.",
"enedis": "Enedis.fr respondi\u00f3 con un error: vuelva a intentarlo m\u00e1s tarde (normalmente no entre las 11 p.m. y las 2 a.m.)",
"unknown": "Error desconocido: por favor, vuelva a intentarlo m\u00e1s tarde (normalmente no entre las 11 p.m. y las 2 a.m.)",
"username_exists": "La cuenta ya ha sido configurada",
"wrong_login": "Error de inicio de sesi\u00f3n: por favor revise su direcci\u00f3n de correo electr\u00f3nico y contrase\u00f1a"
},
"step": {

View File

@@ -1,13 +1,12 @@
{
"config": {
"abort": {
"username_exists": "Cuenta ya configurada"
"already_configured": "La cuenta ya est\u00e1 configurada"
},
"error": {
"access": "No se pudo acceder a Enedis.fr, compruebe su conexi\u00f3n a Internet",
"enedis": "Enedis.fr respondi\u00f3 con un error: vuelva a intentarlo m\u00e1s tarde (normalmente no entre las 11:00 y las 2 de la ma\u00f1ana)",
"unknown": "Error desconocido: por favor, vuelva a intentarlo m\u00e1s tarde (normalmente no entre las 23:00 y las 02:00 horas).",
"username_exists": "Cuenta ya configurada",
"wrong_login": "Error de inicio de sesi\u00f3n: compruebe su direcci\u00f3n de correo electr\u00f3nico y contrase\u00f1a"
},
"step": {

View File

@@ -1,13 +1,12 @@
{
"config": {
"abort": {
"username_exists": "Compte d\u00e9j\u00e0 configur\u00e9"
"already_configured": "Compte d\u00e9j\u00e0 configur\u00e9"
},
"error": {
"access": "Impossible d'acc\u00e9der \u00e0 Enedis.fr, merci de v\u00e9rifier votre connexion internet",
"enedis": "Erreur d'Enedis.fr: merci de r\u00e9essayer plus tard (pas entre 23h et 2h)",
"unknown": "Erreur inconnue: merci de r\u00e9essayer plus tard (pas entre 23h et 2h)",
"username_exists": "Compte d\u00e9j\u00e0 configur\u00e9",
"wrong_login": "Erreur de connexion: veuillez v\u00e9rifier votre e-mail et votre mot de passe"
},
"step": {

View File

@@ -1,13 +1,12 @@
{
"config": {
"abort": {
"username_exists": "Account gi\u00e0 configurato"
"already_configured": "Account gi\u00e0 configurato"
},
"error": {
"access": "Impossibile accedere a Enedis.fr, si prega di controllare la connessione internet",
"enedis": "Enedis.fr ha risposto con un errore: si prega di riprovare pi\u00f9 tardi (di solito non tra le 23:00 e le 02:00).",
"unknown": "Errore sconosciuto: riprova pi\u00f9 tardi (in genere non tra le 23:00 e le 02:00)",
"username_exists": "Account gi\u00e0 configurato",
"wrong_login": "Errore di accesso: si prega di controllare la tua E-mail e la password"
},
"step": {

View File

@@ -1,14 +1,12 @@
{
"config": {
"abort": {
"already_configured": "\uacc4\uc815\uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4.",
"username_exists": "\uacc4\uc815\uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
"already_configured": "\uacc4\uc815\uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
},
"error": {
"access": "Enedis.fr \uc5d0 \uc811\uc18d\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc778\ud130\ub137 \uc5f0\uacb0\uc744 \ud655\uc778\ud574\ubcf4\uc138\uc694",
"enedis": "Enedis.fr \uc774 \uc624\ub958\ub85c \uc751\ub2f5\ud588\uc2b5\ub2c8\ub2e4: \ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694 (\uc800\ub141 11\uc2dc \ubd80\ud130 \uc0c8\ubcbd 2\uc2dc\ub294 \ud53c\ud574\uc8fc\uc138\uc694)",
"unknown": "\uc54c \uc218\uc5c6\ub294 \uc624\ub958: \ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694 (\uc800\ub141 11\uc2dc \ubd80\ud130 \uc0c8\ubcbd 2\uc2dc\ub294 \ud53c\ud574\uc8fc\uc138\uc694)",
"username_exists": "\uacc4\uc815\uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4.",
"wrong_login": "\ub85c\uadf8\uc778 \uc624\ub958: \uc774\uba54\uc77c \ubc0f \ube44\ubc00\ubc88\ud638\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694"
},
"step": {

View File

@@ -1,13 +1,12 @@
{
"config": {
"abort": {
"username_exists": "Kont ass scho konfigur\u00e9iert"
"already_configured": "Kont ass scho konfigur\u00e9iert"
},
"error": {
"access": "Keng Verbindung zu Enedis.fr, iwwerpr\u00e9ift d'Internet Verbindung",
"enedis": "Enedis.fr huet mat engem Feeler ge\u00e4ntwert: prob\u00e9iert sp\u00e9ider nach emol (normalerweis net t\u00ebscht 23h00 an 2h00)",
"unknown": "Onbekannte Feeler: prob\u00e9iert sp\u00e9ider nach emol (normalerweis net t\u00ebscht 23h00 an 2h00)",
"username_exists": "Kont ass scho konfigur\u00e9iert",
"wrong_login": "Feeler beim Login: iwwerpr\u00e9ift \u00e4r E-Mail & Passwuert"
},
"step": {

View File

@@ -1,13 +1,9 @@
{
"config": {
"abort": {
"username_exists": "Account reeds geconfigureerd"
},
"error": {
"access": "Geen toegang tot Enedis.fr, controleer uw internetverbinding",
"enedis": "Enedis.fr antwoordde met een fout: probeer het later opnieuw (meestal niet tussen 23.00 en 02.00 uur)",
"unknown": "Onbekende fout: probeer het later opnieuw (meestal niet tussen 23.00 en 02.00 uur)",
"username_exists": "Account reeds geconfigureerd",
"wrong_login": "Aanmeldingsfout: controleer uw e-mailadres en wachtwoord"
},
"step": {

View File

@@ -1,14 +1,12 @@
{
"config": {
"abort": {
"already_configured": "Kontoen er allerede konfigurert",
"username_exists": "Kontoen er allerede konfigurert"
"already_configured": "Kontoen er allerede konfigurert"
},
"error": {
"access": "Kunne ikke f\u00e5 tilgang til Enedis.fr, vennligst sjekk internettforbindelsen din",
"enedis": "Enedis.fr svarte med en feil: vennligst pr\u00f8v p\u00e5 nytt senere (vanligvis ikke mellom 23:00 og 02:00)",
"unknown": "Ukjent feil: pr\u00f8v p\u00e5 nytt senere (vanligvis ikke mellom 23:00 og 02:00)",
"username_exists": "Kontoen er allerede konfigurert",
"wrong_login": "Innloggingsfeil: vennligst sjekk e-postadressen og passordet ditt"
},
"step": {

View File

@@ -1,14 +1,12 @@
{
"config": {
"abort": {
"already_configured": "Konto jest ju\u017c skonfigurowane",
"username_exists": "Konto jest ju\u017c skonfigurowane"
"already_configured": "Konto jest ju\u017c skonfigurowane"
},
"error": {
"access": "Nie mo\u017cna uzyska\u0107 dost\u0119pu do Enedis.fr, sprawd\u017a po\u0142\u0105czenie internetowe",
"enedis": "Enedis.fr odpowiedzia\u0142 b\u0142\u0119dem: spr\u00f3buj ponownie p\u00f3\u017aniej (zwykle nie mi\u0119dzy 23:00, a 2:00)",
"unknown": "Nieznany b\u0142\u0105d: spr\u00f3buj ponownie p\u00f3\u017aniej (zwykle nie mi\u0119dzy godzin\u0105 23:00, a 2:00)",
"username_exists": "Konto jest ju\u017c skonfigurowane",
"wrong_login": "B\u0142\u0105d logowania: sprawd\u017a adres e-mail i has\u0142o"
},
"step": {

View File

@@ -1,7 +1,6 @@
{
"config": {
"error": {
"username_exists": "Conta j\u00e1 configurada",
"wrong_login": "Erro de Login: por favor, verifique seu e-mail e senha"
},
"step": {

View File

@@ -1,11 +1,5 @@
{
"config": {
"abort": {
"username_exists": "Conta j\u00e1 configurada"
},
"error": {
"username_exists": "Conta j\u00e1 configurada"
},
"step": {
"user": {
"data": {

View File

@@ -1,14 +1,12 @@
{
"config": {
"abort": {
"already_configured": "\u0423\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430.",
"username_exists": "\u0423\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430."
"already_configured": "\u0423\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430."
},
"error": {
"access": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a Enedis.fr, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443.",
"enedis": "Enedis.fr \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u043e\u0442\u0432\u0435\u0442 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439: \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u043f\u043e\u0437\u0436\u0435 (\u043d\u0435 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 \u0441 23:00 \u043f\u043e 2:00).",
"unknown": "\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430: \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u043f\u043e\u0437\u0436\u0435 (\u043d\u0435 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 \u0441 23:00 \u043f\u043e 2:00).",
"username_exists": "\u0423\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430.",
"wrong_login": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0445\u043e\u0434\u0430: \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0430\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b \u0438 \u043f\u0430\u0440\u043e\u043b\u044c."
},
"step": {

View File

@@ -1,13 +1,9 @@
{
"config": {
"abort": {
"username_exists": "Ra\u010dun \u017ee nastavljen"
},
"error": {
"access": "Do Enedis.fr ni bilo mogo\u010de dostopati, preverite internetno povezavo",
"enedis": "Enedis.fr je odgovoril z napako: poskusite pozneje (ponavadi med 23. in 2. uro)",
"unknown": "Neznana napaka: Prosimo, poskusite pozneje (obi\u010dajno ne med 23. in 2. uro)",
"username_exists": "Ra\u010dun \u017ee nastavljen",
"wrong_login": "Napaka pri prijavi: preverite svoj e-po\u0161tni naslov in geslo"
},
"step": {

View File

@@ -1,8 +1,5 @@
{
"config": {
"abort": {
"username_exists": "\u8d26\u6237\u5df2\u914d\u7f6e\u5b8c\u6210"
},
"step": {
"user": {
"data": {

View File

@@ -1,13 +1,12 @@
{
"config": {
"abort": {
"username_exists": "\u5e33\u865f\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
"already_configured": "\u5e33\u865f\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
},
"error": {
"access": "\u7121\u6cd5\u8a2a\u554f Enedis.fr\uff0c\u8acb\u6aa2\u67e5\u60a8\u7684\u7db2\u969b\u7db2\u8def\u9023\u7dda",
"enedis": "Endis.fr \u56de\u5831\u932f\u8aa4\uff1a\u8acb\u7a0d\u5f8c\u518d\u8a66\uff08\u901a\u5e38\u907f\u958b\u591c\u9593 11 - \u51cc\u6668 2 \u9ede\u4e4b\u9593\uff09",
"unknown": "\u672a\u77e5\u932f\u8aa4\uff1a\u8acb\u7a0d\u5f8c\u518d\u8a66\uff08\u901a\u5e38\u907f\u958b\u591c\u9593 11 - \u51cc\u6668 2 \u9ede\u4e4b\u9593\uff09",
"username_exists": "\u5e33\u865f\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210",
"wrong_login": "\u767b\u5165\u932f\u8aa4\uff1a\u8acb\u78ba\u8a8d\u96fb\u5b50\u90f5\u4ef6\u8207\u79d8\u5bc6\u6b63\u78ba\u6027"
},
"step": {

View File

@@ -1,17 +1,17 @@
{
"device_automation": {
"action_type": {
"lock": "\u4e0a\u9396 {entity_name}",
"open": "\u958b\u555f {entity_name}",
"unlock": "\u89e3\u9396 {entity_name}"
"lock": "\u4e0a\u9396{entity_name}",
"open": "\u958b\u555f{entity_name}",
"unlock": "\u89e3\u9396{entity_name}"
},
"condition_type": {
"is_locked": "{entity_name} \u5df2\u4e0a\u9396",
"is_unlocked": "{entity_name} \u5df2\u89e3\u9396"
"is_locked": "{entity_name}\u5df2\u4e0a\u9396",
"is_unlocked": "{entity_name}\u5df2\u89e3\u9396"
},
"trigger_type": {
"locked": "{entity_name} \u5df2\u4e0a\u9396",
"unlocked": "{entity_name} \u5df2\u89e3\u9396"
"locked": "{entity_name}\u5df2\u4e0a\u9396",
"unlocked": "{entity_name}\u5df2\u89e3\u9396"
}
}
}

View File

@@ -1,11 +1,11 @@
{
"device_automation": {
"condition_type": {
"is_idle": "{entity_name} \u9592\u7f6e",
"is_off": "{entity_name} \u95dc\u9589",
"is_on": "{entity_name} \u958b\u555f",
"is_paused": "{entity_name} \u5df2\u66ab\u505c",
"is_playing": "{entity_name} \u6b63\u5728\u64ad\u653e"
"is_idle": "{entity_name}\u9592\u7f6e",
"is_off": "{entity_name}\u95dc\u9589",
"is_on": "{entity_name}\u958b\u555f",
"is_paused": "{entity_name}\u5df2\u66ab\u505c",
"is_playing": "{entity_name}\u6b63\u5728\u64ad\u653e"
}
}
}

View File

@@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"data": {
"city": "Ciutat"
},
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "By er allerede konfigureret",
"unknown": "Ukendt fejl: Pr\u00f8v igen senere"
},
"step": {
"user": {
"data": {
"city": "By"
},
"description": "Indtast postnummer (kun for Frankrig, anbefalet) eller bynavn",
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,17 @@
{
"config": {
"abort": {
"already_configured": "Stadt bereits konfiguriert",
"unknown": "Unbekannter Fehler: Bitte versuchen Sie es sp\u00e4ter erneut"
},
"step": {
"user": {
"data": {
"city": "Stadt"
},
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "City already configured",
"unknown": "Unknown error: please retry later"
},
"step": {
"user": {
"data": {
"city": "City"
},
"description": "Enter the postal code (only for France, recommended) or city name",
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "\ub3c4\uc2dc\uac00 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4.",
"unknown": "\uc54c \uc218 \uc5c6\ub294 \uc624\ub958\uc785\ub2c8\ub2e4. \ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694"
},
"step": {
"user": {
"data": {
"city": "\ub3c4\uc2dc"
},
"description": "\uc6b0\ud3b8\ubc88\ud638 (\ud504\ub791\uc2a4) \ub610\ub294 \ub3c4\uc2dc \uc774\ub984\uc744 \uc785\ub825\ud574\uc8fc\uc138\uc694",
"title": "\ud504\ub791\uc2a4 \uae30\uc0c1\uccad (M\u00e9t\u00e9o-France)"
}
},
"title": "\ud504\ub791\uc2a4 \uae30\uc0c1\uccad (M\u00e9t\u00e9o-France)"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "Stad ass scho konfigur\u00e9iert",
"unknown": "Onbekannte Feeler: prob\u00e9iert sp\u00e9ider nach emol"
},
"step": {
"user": {
"data": {
"city": "Stad"
},
"description": "Gitt de Postcode an (n\u00ebmme fir Frankr\u00e4ich, recommand\u00e9iert) oder den Numm vun der Stad",
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "Byen er allerede konfigurert",
"unknown": "Ukjent feil: pr\u00f8v p\u00e5 nytt senere"
},
"step": {
"user": {
"data": {
"city": "By"
},
"description": "Skriv inn postnummeret (bare for Frankrike, anbefalt) eller bynavn",
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "Miasto jest ju\u017c skonfigurowane",
"unknown": "Nieznany b\u0142\u0105d: spr\u00f3buj ponownie p\u00f3\u017aniej"
},
"step": {
"user": {
"data": {
"city": "Miasto"
},
"description": "Wprowad\u017a kod pocztowy (tylko dla Francji, zalecane) lub nazw\u0119 miasta",
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0436\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.",
"unknown": "\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430: \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u043f\u043e\u0437\u0436\u0435."
},
"step": {
"user": {
"data": {
"city": "\u0413\u043e\u0440\u043e\u0434"
},
"description": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0424\u0440\u0430\u043d\u0446\u0438\u0438) \u0438\u043b\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0433\u043e\u0440\u043e\u0434\u0430",
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "Staden har redan konfigurerats",
"unknown": "Ok\u00e4nt fel: f\u00f6rs\u00f6k igen senare"
},
"step": {
"user": {
"data": {
"city": "Stad"
},
"description": "Ange postnumret (endast f\u00f6r Frankrike, rekommenderat) eller ortsnamn",
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"already_configured": "\u57ce\u5e02\u5df2\u8a2d\u5b9a\u5b8c\u6210",
"unknown": "\u672a\u77e5\u932f\u8aa4\uff1a\u8acb\u7a0d\u5f8c\u518d\u8a66"
},
"step": {
"user": {
"data": {
"city": "\u57ce\u5e02\u540d\u7a31"
},
"description": "\u8f38\u5165\u90f5\u905e\u5340\u865f\uff08\u50c5\u652f\u63f4\u6cd5\u570b\uff09\u6216\u57ce\u5e02\u540d\u7a31",
"title": "M\u00e9t\u00e9o-France"
}
},
"title": "M\u00e9t\u00e9o-France"
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik ja est\u00e0 configurat"
},
"error": {
"cannot_connect": "La connexi\u00f3 no ha tingut \u00e8xit",
"name_exists": "El nom existeix",
"wrong_credentials": "Credencials incorrectes"
},
"step": {
"user": {
"data": {
"host": "Amfitri\u00f3",
"name": "Nom",
"password": "Contrasenya",
"port": "Port",
"username": "Nom d'usuari",
"verify_ssl": "Utilitza SSL"
},
"title": "Configuraci\u00f3 de Mikrotik Router"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "Activa el ping ARP",
"detection_time": "Interval per considerar a casa",
"force_dhcp": "For\u00e7a l'escaneig mitjan\u00e7ant DHCP"
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik er allerede konfigureret"
},
"error": {
"cannot_connect": "Forbindelsen mislykkedes",
"name_exists": "Navnet findes allerede",
"wrong_credentials": "Forkerte legitimationsoplysninger"
},
"step": {
"user": {
"data": {
"host": "V\u00e6rt",
"name": "Navn",
"password": "Adgangskode",
"port": "Port",
"username": "Brugernavn",
"verify_ssl": "Brug ssl"
},
"title": "Konfigurer Mikrotik-router"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "Aktiver ARP-ping",
"detection_time": "'Betragt som hjemme'-interval",
"force_dhcp": "Gennemtving scanning ved hj\u00e6lp af DHCP"
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik ist bereits konfiguriert"
},
"error": {
"cannot_connect": "Verbindung fehlgeschlagen",
"name_exists": "Name vorhanden",
"wrong_credentials": "Falsche Zugangsdaten"
},
"step": {
"user": {
"data": {
"host": "Host",
"name": "Name",
"password": "Passwort",
"port": "Port",
"username": "Benutzername",
"verify_ssl": "Verwenden Sie SSL"
},
"title": "Richten Sie den Mikrotik Router ein"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"force_dhcp": "Erzwingen Sie das Scannen \u00fcber DHCP"
}
}
}
}
}

View File

@@ -1,35 +1,35 @@
{
"config": {
"title": "Mikrotik",
"step": {
"user": {
"title": "Set up Mikrotik Router",
"data": {
"name": "Name",
"host": "Host",
"username": "Username",
"password": "Password",
"port": "Port",
"verify_ssl": "Use ssl"
}
}
},
"error": {
"name_exists": "Name exists",
"cannot_connect": "Connection Unsuccessful",
"wrong_credentials": "Wrong Credentials"
},
"abort": {
"already_configured": "Mikrotik is already configured"
}
},
"error": {
"cannot_connect": "Connection Unsuccessful",
"name_exists": "Name exists",
"wrong_credentials": "Wrong Credentials"
},
"step": {
"user": {
"data": {
"host": "Host",
"name": "Name",
"password": "Password",
"port": "Port",
"username": "Username",
"verify_ssl": "Use ssl"
},
"title": "Set up Mikrotik Router"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "Enable ARP ping",
"force_dhcp": "Force scanning using DHCP",
"detection_time": "Consider home interval"
"detection_time": "Consider home interval",
"force_dhcp": "Force scanning using DHCP"
}
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik ya est\u00e1 configurado"
},
"error": {
"cannot_connect": "Conexi\u00f3n fallida",
"name_exists": "El nombre ya existe",
"wrong_credentials": "Credenciales incorrectas"
},
"step": {
"user": {
"data": {
"host": "Host",
"name": "Nombre",
"password": "Contrase\u00f1a",
"port": "Puerto",
"username": "Nombre de usuario",
"verify_ssl": "Usar ssl"
},
"title": "Configurar el router Mikrotik"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "Habilitar ping ARP",
"detection_time": "Considere el intervalo de inicio",
"force_dhcp": "Forzar el escaneo usando DHCP"
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik \u00e8 gi\u00e0 configurato"
},
"error": {
"cannot_connect": "Connessione Non Riuscita",
"name_exists": "Il Nome esiste gi\u00e0",
"wrong_credentials": "Credenziali Errate"
},
"step": {
"user": {
"data": {
"host": "Host",
"name": "Nome",
"password": "Password",
"port": "Porta",
"username": "Nome utente",
"verify_ssl": "Usa SSL"
},
"title": "Configurare il router Mikrotik"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "Attivare il ping ARP",
"detection_time": "Considerare l'intervallo di casa",
"force_dhcp": "Scansione forzata con DHCP"
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik \uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"error": {
"cannot_connect": "\uc5f0\uacb0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4",
"name_exists": "\uc774\ub984\uc774 \uc774\ubbf8 \uc874\uc7ac\ud569\ub2c8\ub2e4",
"wrong_credentials": "\uc0ac\uc6a9\uc790 \uc774\ub984 \ud639\uc740 \ube44\ubc00\ubc88\ud638\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"host": "\ud638\uc2a4\ud2b8",
"name": "\uc774\ub984",
"password": "\ube44\ubc00\ubc88\ud638",
"port": "\ud3ec\ud2b8",
"username": "\uc0ac\uc6a9\uc790 \uc774\ub984",
"verify_ssl": "SSL \uc0ac\uc6a9"
},
"title": "Mikrotik \ub77c\uc6b0\ud130 \uc124\uc815"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "ARP \ud551 \ud65c\uc131\ud654",
"detection_time": "\uc2a4\uce94 \uac04\uaca9",
"force_dhcp": "DHCP \ub97c \uc0ac\uc6a9\ud558\uc5ec \uac15\uc81c \uc2a4\uce94"
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik ass scho konfigur\u00e9iert"
},
"error": {
"cannot_connect": "Verbindung net erfollegr\u00e4ich",
"name_exists": "Numm g\u00ebtt et schonn",
"wrong_credentials": "Falsh Login Informatiounen"
},
"step": {
"user": {
"data": {
"host": "Apparat",
"name": "Numm",
"password": "Passwuert",
"port": "Port",
"username": "Benotzernumm",
"verify_ssl": "SSL benotzen"
},
"title": "Mikrotik Router ariichten"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "ARP ping aktiv\u00e9ieren",
"detection_time": "Home Intervall betruechten",
"force_dhcp": "Scannen erzw\u00e9ngen mat DHCP"
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik er allerede konfigurert"
},
"error": {
"cannot_connect": "Tilkobling mislykket",
"name_exists": "Navnet eksisterer",
"wrong_credentials": "Feil legitimasjon"
},
"step": {
"user": {
"data": {
"host": "Vert",
"name": "Navn",
"password": "Passord",
"port": "Port",
"username": "Brukernavn",
"verify_ssl": "Bruk ssl"
},
"title": "Konfigurere Mikrotik-ruter"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "Aktiver ARP-ping",
"detection_time": "Vurder hjemmeintervall",
"force_dhcp": "Tving skanning ved hjelp av DHCP"
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikronik jest ju\u017c skonfigurowany"
},
"error": {
"cannot_connect": "Po\u0142\u0105czenie nie powiod\u0142o si\u0119",
"name_exists": "Nazwa ju\u017c istnieje",
"wrong_credentials": "B\u0142\u0119dne dane uwierzytelniaj\u0105ce"
},
"step": {
"user": {
"data": {
"host": "Host",
"name": "Nazwa",
"password": "Has\u0142o",
"port": "Port",
"username": "Nazwa u\u017cytkownika",
"verify_ssl": "U\u017cyj SSL"
},
"title": "Skonfiguruj router Mikrotik"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "W\u0142\u0105cz ping ARP",
"detection_time": "Czas przed oznaczeniem \"poza domem\"",
"force_dhcp": "Wymu\u015b skanowanie przy u\u017cyciu DHCP"
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430."
},
"error": {
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443.",
"name_exists": "\u042d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f.",
"wrong_credentials": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0435 \u0443\u0447\u0451\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435."
},
"step": {
"user": {
"data": {
"host": "\u0425\u043e\u0441\u0442",
"name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435",
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
"port": "\u041f\u043e\u0440\u0442",
"username": "\u041b\u043e\u0433\u0438\u043d",
"verify_ssl": "\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c SSL"
},
"title": "MikroTik"
}
},
"title": "MikroTik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c ARP-\u043f\u0438\u043d\u0433",
"detection_time": "\u0412\u0440\u0435\u043c\u044f \u043e\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u0435\u0430\u043d\u0441\u0430 \u0441\u0432\u044f\u0437\u0438 \u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c (\u0441\u0435\u043a.), \u043f\u043e \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u0441\u0442\u0430\u0442\u0443\u0441 \"\u041d\u0435 \u0434\u043e\u043c\u0430\".",
"force_dhcp": "\u041f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c DHCP"
}
}
}
}
}

View File

@@ -0,0 +1,10 @@
{
"config": {
"step": {
"user": {
"title": "Konfigurera Mikrotik-router"
}
},
"title": "Mikrotik"
}
}

View File

@@ -0,0 +1,37 @@
{
"config": {
"abort": {
"already_configured": "Mikrotik \u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
},
"error": {
"cannot_connect": "\u9023\u7dda\u672a\u6210\u529f",
"name_exists": "\u8a72\u540d\u7a31\u5df2\u5b58\u5728",
"wrong_credentials": "\u6191\u8b49\u932f\u8aa4"
},
"step": {
"user": {
"data": {
"host": "\u4e3b\u6a5f\u7aef",
"name": "\u540d\u7a31",
"password": "\u5bc6\u78bc",
"port": "\u901a\u8a0a\u57e0",
"username": "\u4f7f\u7528\u8005\u540d\u7a31",
"verify_ssl": "\u4f7f\u7528 SSL"
},
"title": "\u8a2d\u5b9a Mikrotik \u8def\u7531\u5668"
}
},
"title": "Mikrotik"
},
"options": {
"step": {
"device_tracker": {
"data": {
"arp_ping": "\u958b\u555f ARP ping",
"detection_time": "\u5224\u5b9a\u5728\u5bb6\u9593\u9694",
"force_dhcp": "\u5f37\u5236\u4f7f\u7528 DHCP \u6383\u63cf"
}
}
}
}
}

View File

@@ -126,7 +126,7 @@ class MikrotikData:
def get_info(self, param):
"""Return device model name."""
cmd = IDENTITY if param == NAME else INFO
data = list(self.command(MIKROTIK_SERVICES[cmd]))
data = self.command(MIKROTIK_SERVICES[cmd])
return data[0].get(param) if data else None
def get_hub_details(self):
@@ -148,7 +148,7 @@ class MikrotikData:
def get_list_from_interface(self, interface):
"""Get devices from interface."""
result = list(self.command(MIKROTIK_SERVICES[interface]))
result = self.command(MIKROTIK_SERVICES[interface])
return self.load_mac(result) if result else {}
def restore_device(self, mac):
@@ -224,7 +224,7 @@ class MikrotikData:
"address": ip_address,
}
cmd = "/ping"
data = list(self.command(cmd, params))
data = self.command(cmd, params)
if data is not None:
status = 0
for result in data:
@@ -242,9 +242,9 @@ class MikrotikData:
try:
_LOGGER.info("Running command %s", cmd)
if params:
response = self.api(cmd=cmd, **params)
response = list(self.api(cmd=cmd, **params))
else:
response = self.api(cmd=cmd)
response = list(self.api(cmd=cmd))
except (
librouteros.exceptions.ConnectionClosed,
socket.error,

View File

@@ -6,6 +6,8 @@ import voluptuous as vol
from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateDevice
from homeassistant.components.climate.const import (
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
FAN_ON,
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
@@ -167,13 +169,20 @@ class MillHeater(ClimateDevice):
"""Return the maximum temperature."""
return MAX_TEMP
@property
def hvac_action(self):
"""Return current hvac i.e. heat, cool, idle."""
if self._heater.is_gen1 or self._heater.is_heating == 1:
return CURRENT_HVAC_HEAT
return CURRENT_HVAC_IDLE
@property
def hvac_mode(self) -> str:
"""Return hvac operation ie. heat, cool mode.
Need to be one of HVAC_MODE_*.
"""
if self._heater.is_gen1 or self._heater.is_heating == 1:
if self._heater.is_gen1 or self._heater.power_status == 1:
return HVAC_MODE_HEAT
return HVAC_MODE_OFF

View File

@@ -30,7 +30,7 @@ dump:
fields:
topic:
description: topic to listen to
example: "openzwave/#"
example: "OpenZWave/#"
duration:
description: how long we should listen for messages in seconds
example: 5

View File

@@ -2,7 +2,8 @@
"config": {
"abort": {
"already_setup": "Nom\u00e9s pots configurar un \u00fanic compte Netatmo.",
"authorize_url_timeout": "S'ha acabat el temps d'espera durant la generaci\u00f3 de l'URL d'autoritzaci\u00f3."
"authorize_url_timeout": "S'ha acabat el temps d'espera durant la generaci\u00f3 de l'URL d'autoritzaci\u00f3.",
"missing_configuration": "El component Netatmo no est\u00e0 configurat. Mira'n la documentaci\u00f3."
},
"create_entry": {
"default": "Autenticaci\u00f3 exitosa amb Netatmo."

Some files were not shown because too many files have changed in this diff Show More