Compare commits

..

41 Commits

Author SHA1 Message Date
Paulus Schoutsen
b1a05e7605 Merge pull request #17578 from home-assistant/rc
0.80.3
2018-10-18 14:55:46 +02:00
Paulus Schoutsen
cd90bb4161 Bumped version to 0.80.3 2018-10-18 13:58:58 +02:00
Paulus Schoutsen
17d0fe02c7 Update snapcast to 2.0.9 (#17573) 2018-10-18 13:58:48 +02:00
Steven Looman
43b140be5e Upgrade async_upnp_client to 0.12.6 (#17560) 2018-10-18 13:58:48 +02:00
Steven Looman
9ded16ccc3 Update to async-upnp-client==0.12.5 (#17401) 2018-10-18 13:58:47 +02:00
Marcel Hoppe
91dc0c3731 update hangups to 0.4.6 and fix Issue #16593 hangouts reconnects. (#17518) 2018-10-18 13:57:04 +02:00
Paulus Schoutsen
6e4a99cec0 Bump frontend to 20181018.0 2018-10-18 13:52:52 +02:00
Paulus Schoutsen
fa196e5889 Merge pull request #17546 from home-assistant/rc
0.80.2
2018-10-17 14:56:58 +02:00
Paulus Schoutsen
9500bb1ac8 Bumped version to 0.80.2 2018-10-17 14:17:56 +02:00
Paulus Schoutsen
b3548f1ead Add another 3 days leeway to give time for payment processing times (#17542) 2018-10-17 14:17:47 +02:00
Kevin Fronczak
f74e976be1 Blink update - fixes #17316 (#17538)
* Updgrae blinkpy to 0.10.0

- Remove status sensor (API endpoint unreliable for this)
- Wifi strength reports in wifi bars rather than dBm (result of new API
endpoint)
- Added unique ids based on serial number

* Update requirements
2018-10-17 14:17:47 +02:00
Nikolay Vasilchuk
dc55718bc3 Fix: Connection pool of Request object is smaller than optimal value (8) (#17483) 2018-10-17 14:17:46 +02:00
Paulus Schoutsen
6551c53e32 Bump frontend to 20181017.0 2018-10-17 14:17:35 +02:00
Paulus Schoutsen
a27d49d022 Update translations 2018-10-17 14:17:33 +02:00
Paulus Schoutsen
4ea71b0602 Merge pull request #17480 from home-assistant/rc
0.80.1
2018-10-15 16:10:50 +02:00
Paulus Schoutsen
708334c0c2 Bumped version to 0.80.1 2018-10-15 15:31:12 +02:00
Paulus Schoutsen
b5272f2bc7 Fix websocket API (#17471) 2018-10-15 15:30:21 +02:00
Pascal Vizeli
80867cc9b7 Bugfix eventstream with EOF on end (#17465) 2018-10-15 15:30:20 +02:00
Tommy Jonsson
f92b392a24 Fix hangout.send_message requiring data key (#17393) 2018-10-15 15:30:20 +02:00
Martin Berg
220054a6c3 Fix arm/disarm calls. (#17381) 2018-10-15 15:30:19 +02:00
Paulus Schoutsen
49a9b61f6f Update frontend to 20181014.0 2018-10-14 19:17:41 +02:00
Paulus Schoutsen
8eb4e77365 Merge pull request #17361 from home-assistant/rc
0.80.0
2018-10-12 16:57:52 +02:00
Paulus Schoutsen
cd29b47924 Bumped version to 0.80.0 2018-10-12 14:59:36 +02:00
Pascal Vizeli
edb3722abd Hass.io auth/sso part2 (#17324)
* Update discovery.py

* Create const.py

* Update auth.py

* Update const.py

* Update const.py

* Update http.py

* Update handler.py

* Update auth.py

* Update auth.py

* Update test_auth.py
2018-10-12 14:59:17 +02:00
Pascal Vizeli
bc036cc2fe Fix auth for hass.io (#17318)
* Update test_auth.py

* Update auth.py

* Update test_auth.py
2018-10-12 14:59:17 +02:00
Martin Hjelmare
8778b707f1 Allow tradfri groups for new imported entries (#17310)
* Clean up leftover config schema option

* Allow import groups via new config yaml setup

* Fix and add test

* Add a test without groups for legacy import

* Change default import groups to False

* Fix I/O in test
2018-10-12 14:59:16 +02:00
Alok Saboo
05ae8f9dd4 Fix samsung bug (#17285) 2018-10-12 14:59:16 +02:00
Nikolay Vasilchuk
d199f57aa8 Logbook: filter by entity and period (#17095)
* Filter logbook by entity_id

* Filter logbook by period

* Simple test

* houndci-bot review

* Tests

* Test fix

* Test Fix
2018-10-12 14:59:15 +02:00
Paulus Schoutsen
f47e080f37 Update translations 2018-10-12 14:58:48 +02:00
Paulus Schoutsen
cfc5ebbfb0 Update frontend 2018-10-12 14:58:23 +02:00
Paulus Schoutsen
fa3f6ca2c7 Bumped version to 0.80.0b5 2018-10-10 14:29:04 +02:00
Paul Annekov
1d78393680 fixed 'on_startup() takes 0 positional arguments but 1 was given' (#17295) 2018-10-10 14:26:34 +02:00
Pascal Vizeli
951d7154b8 Fix hassio discovery (#17275)
* Update discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Update test_discovery.py

* Fix tests

* fix lint
2018-10-10 14:26:33 +02:00
Pascal Vizeli
3f28b30860 Hassio auth (#17274)
* Create auth.py

* Update auth.py

* Update auth.py

* Update __init__.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Update auth.py

* Add tests

* Update test_auth.py

* Update auth.py

* Update test_auth.py

* Update auth.py
2018-10-10 14:26:32 +02:00
Paulus Schoutsen
83dec7173c Update translations 2018-10-10 14:25:49 +02:00
Paulus Schoutsen
a8a21ee28d Bumped version to 0.80.0b4 2018-10-09 16:20:39 +02:00
Anders Melchiorsen
1a76603f53 Remove warning on script delay (#17264)
* Remove warning on script delay

* Use suppress
2018-10-09 16:20:31 +02:00
Steven Looman
089e15e046 Add defaults, fixing #17229 (#17261) 2018-10-09 16:20:31 +02:00
Sebastian Muszynski
b59d69f313 Fix ambient light state of the Philips Eyecare Lamp (Closes: #16269) (#17259) 2018-10-09 16:20:30 +02:00
Paulus Schoutsen
eb7db1f763 block external IP (#17248)
* block external IP

* Update __init__.py
2018-10-09 16:20:29 +02:00
Paulus Schoutsen
429f09deb3 Add a webhook automation trigger (#17246) 2018-10-09 16:20:29 +02:00
157 changed files with 2486 additions and 114 deletions

View File

@@ -43,6 +43,11 @@ class BlinkSyncModule(AlarmControlPanel):
self._name = name
self._state = None
@property
def unique_id(self):
"""Return the unique id for the sync module."""
return self.sync.serial
@property
def icon(self):
"""Return icon."""
@@ -61,9 +66,10 @@ class BlinkSyncModule(AlarmControlPanel):
@property
def device_state_attributes(self):
"""Return the state attributes."""
return {
ATTR_ATTRIBUTION: DEFAULT_ATTRIBUTION,
}
attr = self.sync.attributes
attr['network_info'] = self.data.networks
attr[ATTR_ATTRIBUTION] = DEFAULT_ATTRIBUTION
return attr
def update(self):
"""Update the state of the device."""

View File

@@ -85,19 +85,23 @@ class SpcAlarm(alarm.AlarmControlPanel):
async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
from pyspcwebgw.const import AreaMode
self._api.change_mode(area=self._area, new_mode=AreaMode.UNSET)
await self._api.change_mode(area=self._area,
new_mode=AreaMode.UNSET)
async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
from pyspcwebgw.const import AreaMode
self._api.change_mode(area=self._area, new_mode=AreaMode.PART_SET_A)
await self._api.change_mode(area=self._area,
new_mode=AreaMode.PART_SET_A)
async def async_alarm_arm_night(self, code=None):
"""Send arm home command."""
from pyspcwebgw.const import AreaMode
self._api.change_mode(area=self._area, new_mode=AreaMode.PART_SET_B)
await self._api.change_mode(area=self._area,
new_mode=AreaMode.PART_SET_B)
async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
from pyspcwebgw.const import AreaMode
self._api.change_mode(area=self._area, new_mode=AreaMode.FULL_SET)
await self._api.change_mode(area=self._area,
new_mode=AreaMode.FULL_SET)

View File

@@ -141,6 +141,8 @@ class APIEventStream(HomeAssistantView):
_LOGGER.debug("STREAM %s RESPONSE CLOSED", id(stop_obj))
unsub_stream()
return response
class APIConfigView(HomeAssistantView):
"""View to handle Configuration requests."""

View File

@@ -1,11 +1,23 @@
{
"mfa_setup": {
"notify": {
"abort": {
"no_available_service": "Aucun service de notification disponible."
},
"error": {
"invalid_code": "Code invalide. Veuillez essayer \u00e0 nouveau."
},
"step": {
"init": {
"description": "Veuillez s\u00e9lectionner l'un des services de notification:",
"title": "Configurer un mot de passe \u00e0 usage unique d\u00e9livr\u00e9 par le composant notify"
},
"setup": {
"description": "Un mot de passe unique a \u00e9t\u00e9 envoy\u00e9 par **notify.{notify_service}**. Veuillez le saisir ci-dessous :"
"description": "Un mot de passe unique a \u00e9t\u00e9 envoy\u00e9 par **notify.{notify_service}**. Veuillez le saisir ci-dessous :",
"title": "V\u00e9rifier la configuration"
}
}
},
"title": "Notifier un mot de passe unique"
},
"totp": {
"error": {

View File

@@ -8,11 +8,16 @@
"invalid_code": "Ogiltig kod, var god f\u00f6rs\u00f6k igen."
},
"step": {
"init": {
"description": "Var god v\u00e4lj en av notifieringstj\u00e4nsterna:",
"title": "Konfigurera ett eng\u00e5ngsl\u00f6senord levererat genom notifieringskomponenten"
},
"setup": {
"description": "Ett eng\u00e5ngsl\u00f6senord har skickats av **notify.{notify_service}**. V\u00e4nligen ange det nedan:",
"title": "Verifiera installationen"
"title": "Verifiera inst\u00e4llningen"
}
}
},
"title": "Meddela eng\u00e5ngsl\u00f6senord"
},
"totp": {
"error": {

View File

@@ -0,0 +1,9 @@
{
"mfa_setup": {
"notify": {
"error": {
"invalid_code": "\u041d\u0435\u0432\u0456\u0440\u043d\u0438\u0439 \u043a\u043e\u0434, \u0441\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435 \u0449\u0435 \u0440\u0430\u0437."
}
}
}
}

View File

@@ -0,0 +1,54 @@
"""
Offer webhook triggered automation rules.
For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/docs/automation/trigger/#webhook-trigger
"""
from functools import partial
import logging
from aiohttp import hdrs
import voluptuous as vol
from homeassistant.core import callback
from homeassistant.const import CONF_PLATFORM
import homeassistant.helpers.config_validation as cv
DEPENDENCIES = ('webhook',)
_LOGGER = logging.getLogger(__name__)
CONF_WEBHOOK_ID = 'webhook_id'
TRIGGER_SCHEMA = vol.Schema({
vol.Required(CONF_PLATFORM): 'webhook',
vol.Required(CONF_WEBHOOK_ID): cv.string,
})
async def _handle_webhook(action, hass, webhook_id, request):
"""Handle incoming webhook."""
result = {
'platform': 'webhook',
'webhook_id': webhook_id,
}
if 'json' in request.headers.get(hdrs.CONTENT_TYPE, ''):
result['json'] = await request.json()
else:
result['data'] = await request.post()
hass.async_run_job(action, {'trigger': result})
async def async_trigger(hass, config, action):
"""Trigger based on incoming webhooks."""
webhook_id = config.get(CONF_WEBHOOK_ID)
hass.components.webhook.async_register(
webhook_id, partial(_handle_webhook, action))
@callback
def unregister():
"""Unregister webhook."""
hass.components.webhook.async_unregister(webhook_id)
return unregister

View File

@@ -36,6 +36,7 @@ class BlinkBinarySensor(BinarySensorDevice):
self._icon = icon
self._camera = data.sync.cameras[camera]
self._state = None
self._unique_id = "{}-{}".format(self._camera.serial, self._type)
@property
def name(self):

View File

@@ -15,7 +15,7 @@ from homeassistant.const import (
CONF_BINARY_SENSORS, CONF_SENSORS, CONF_FILENAME,
CONF_MONITORED_CONDITIONS, TEMP_FAHRENHEIT)
REQUIREMENTS = ['blinkpy==0.9.0']
REQUIREMENTS = ['blinkpy==0.10.0']
_LOGGER = logging.getLogger(__name__)
@@ -36,7 +36,6 @@ TYPE_MOTION_DETECTED = 'motion_detected'
TYPE_TEMPERATURE = 'temperature'
TYPE_BATTERY = 'battery'
TYPE_WIFI_STRENGTH = 'wifi_strength'
TYPE_STATUS = 'status'
SERVICE_REFRESH = 'blink_update'
SERVICE_TRIGGER = 'trigger_camera'
@@ -50,8 +49,7 @@ BINARY_SENSORS = {
SENSORS = {
TYPE_TEMPERATURE: ['Temperature', TEMP_FAHRENHEIT, 'mdi:thermometer'],
TYPE_BATTERY: ['Battery', '%', 'mdi:battery-80'],
TYPE_WIFI_STRENGTH: ['Wifi Signal', 'dBm', 'mdi:wifi-strength-2'],
TYPE_STATUS: ['Status', '', 'mdi:bell']
TYPE_WIFI_STRENGTH: ['Wifi Signal', 'bars', 'mdi:wifi-strength-2'],
}
BINARY_SENSOR_SCHEMA = vol.Schema({

View File

@@ -38,6 +38,7 @@ class BlinkCamera(Camera):
self.data = data
self._name = "{} {}".format(BLINK_DATA, name)
self._camera = camera
self._unique_id = "{}-camera".format(camera.serial)
self.response = None
self.current_image = None
self.last_image = None
@@ -48,6 +49,11 @@ class BlinkCamera(Camera):
"""Return the camera name."""
return self._name
@property
def unique_id(self):
"""Return the unique camera id."""
return self._unique_id
@property
def device_state_attributes(self):
"""Return the camera attributes."""
@@ -64,7 +70,7 @@ class BlinkCamera(Camera):
@property
def motion_detection_enabled(self):
"""Return the state of the camera."""
return self._camera.armed
return self._camera.motion_enabled
@property
def brand(self):

View File

@@ -1,7 +1,7 @@
{
"config": {
"abort": {
"no_devices_found": "\u5728\u7db2\u8def\u4e0a\u627e\u4e0d\u5230 Google Cast \u8a2d\u5099\u3002",
"no_devices_found": "\u5728\u7db2\u8def\u4e0a\u627e\u4e0d\u5230 Google Cast \u88dd\u7f6e\u3002",
"single_instance_allowed": "\u50c5\u9700\u8a2d\u5b9a\u4e00\u6b21 Google Cast \u5373\u53ef\u3002"
},
"step": {

View File

@@ -5,7 +5,7 @@ For more details about this component, please refer to the documentation at
https://home-assistant.io/components/cloud/
"""
import asyncio
from datetime import datetime
from datetime import datetime, timedelta
import json
import logging
import os
@@ -162,7 +162,7 @@ class Cloud:
@property
def subscription_expired(self):
"""Return a boolean if the subscription has expired."""
return dt_util.utcnow() > self.expiration_date
return dt_util.utcnow() > self.expiration_date + timedelta(days=3)
@property
def expiration_date(self):

View File

@@ -3,7 +3,7 @@
"abort": {
"already_configured": "Bridge \u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210",
"no_bridges": "\u672a\u641c\u5c0b\u5230 deCONZ Bridfe",
"one_instance_only": "\u7d44\u4ef6\u50c5\u652f\u63f4\u4e00\u7d44 deCONZ \u5be6\u4f8b"
"one_instance_only": "\u7d44\u4ef6\u50c5\u652f\u63f4\u4e00\u7d44 deCONZ \u7269\u4ef6"
},
"error": {
"no_key": "\u7121\u6cd5\u53d6\u5f97 API key"

View File

@@ -18,6 +18,8 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.deprecation import get_deprecated
import homeassistant.helpers.config_validation as cv
from homeassistant.util.json import load_json, save_json
from homeassistant.components.http import real_ip
from .hue_api import (
HueUsernameView, HueAllLightsStateView, HueOneLightStateView,
HueOneLightChangeView, HueGroupView)
@@ -81,12 +83,20 @@ ATTR_EMULATED_HUE_NAME = 'emulated_hue_name'
ATTR_EMULATED_HUE_HIDDEN = 'emulated_hue_hidden'
def setup(hass, yaml_config):
async def async_setup(hass, yaml_config):
"""Activate the emulated_hue component."""
config = Config(hass, yaml_config.get(DOMAIN, {}))
app = web.Application()
app['hass'] = hass
real_ip.setup_real_ip(app, False, [])
# We misunderstood the startup signal. You're not allowed to change
# anything during startup. Temp workaround.
# pylint: disable=protected-access
app._on_startup.freeze()
await app.startup()
handler = None
server = None
@@ -131,7 +141,8 @@ def setup(hass, yaml_config):
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_STOP, stop_emulated_hue_bridge)
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_emulated_hue_bridge)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START,
start_emulated_hue_bridge)
return True

View File

@@ -20,6 +20,9 @@ from homeassistant.components.fan import (
SPEED_MEDIUM, SPEED_HIGH
)
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http.const import KEY_REAL_IP
from homeassistant.util.network import is_local
_LOGGER = logging.getLogger(__name__)
@@ -46,6 +49,10 @@ class HueUsernameView(HomeAssistantView):
return self.json_message('devicetype not specified',
HTTP_BAD_REQUEST)
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)
return self.json([{'success': {'username': '12345678901234567890'}}])
@@ -63,6 +70,10 @@ class HueGroupView(HomeAssistantView):
@core.callback
def put(self, request, username):
"""Process a request to make the Logitech Pop working."""
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)
return self.json([{
'error': {
'address': '/groups/0/action/scene',
@@ -86,6 +97,10 @@ class HueAllLightsStateView(HomeAssistantView):
@core.callback
def get(self, request, username):
"""Process a request to get the list of available lights."""
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)
hass = request.app['hass']
json_response = {}
@@ -114,6 +129,10 @@ class HueOneLightStateView(HomeAssistantView):
@core.callback
def get(self, request, username, entity_id):
"""Process a request to get the state of an individual light."""
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)
hass = request.app['hass']
entity_id = self.config.number_to_entity_id(entity_id)
entity = hass.states.get(entity_id)
@@ -146,6 +165,10 @@ class HueOneLightChangeView(HomeAssistantView):
async def put(self, request, username, entity_number):
"""Process a request to set the state of an individual light."""
if not is_local(request[KEY_REAL_IP]):
return self.json_message('only local IPs allowed',
HTTP_BAD_REQUEST)
config = self.config
hass = request.app['hass']
entity_id = config.number_to_entity_id(entity_number)

View File

@@ -24,7 +24,7 @@ from homeassistant.core import callback
from homeassistant.helpers.translation import async_get_translations
from homeassistant.loader import bind_hass
REQUIREMENTS = ['home-assistant-frontend==20181007.0']
REQUIREMENTS = ['home-assistant-frontend==20181018.0']
DOMAIN = 'frontend'
DEPENDENCIES = ['api', 'websocket_api', 'http', 'system_log',

View File

@@ -14,6 +14,7 @@
"data": {
"2fa": "2FA Pinkod"
},
"description": "Missing english translation",
"title": "Tv\u00e5faktorsautentisering"
},
"user": {
@@ -21,6 +22,7 @@
"email": "E-postadress",
"password": "L\u00f6senord"
},
"description": "Missing english translation",
"title": "Google Hangouts-inloggning"
}
},

View File

@@ -27,7 +27,7 @@ from .const import (
# We need an import from .config_flow, without it .config_flow is never loaded.
from .config_flow import HangoutsFlowHandler # noqa: F401
REQUIREMENTS = ['hangups==0.4.5']
REQUIREMENTS = ['hangups==0.4.6']
_LOGGER = logging.getLogger(__name__)

View File

@@ -191,16 +191,19 @@ class HangoutsBot:
self._connected = True
dispatcher.async_dispatcher_send(self.hass, EVENT_HANGOUTS_CONNECTED)
def _on_disconnect(self):
async def _on_disconnect(self):
"""Handle disconnecting."""
_LOGGER.debug('Connection lost!')
self._connected = False
dispatcher.async_dispatcher_send(self.hass,
EVENT_HANGOUTS_DISCONNECTED)
if self._connected:
_LOGGER.debug('Connection lost! Reconnect...')
await self.async_connect()
else:
dispatcher.async_dispatcher_send(self.hass,
EVENT_HANGOUTS_DISCONNECTED)
async def async_disconnect(self):
"""Disconnect the client if it is connected."""
if self._connected:
self._connected = False
await self._client.disconnect()
async def async_handle_hass_stop(self, _):
@@ -304,7 +307,7 @@ class HangoutsBot:
"""Handle the send_message service."""
await self._async_send_message(service.data[ATTR_MESSAGE],
service.data[ATTR_TARGET],
service.data[ATTR_DATA])
service.data.get(ATTR_DATA, {}))
async def async_handle_update_users_and_conversations(self, _=None):
"""Handle the update_users_and_conversations service."""

View File

@@ -19,6 +19,7 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.loader import bind_hass
from homeassistant.util.dt import utcnow
from .auth import async_setup_auth
from .handler import HassIO, HassioAPIError
from .discovery import async_setup_discovery
from .http import HassIOView
@@ -280,4 +281,7 @@ async def async_setup(hass, config):
# Init discovery Hass.io feature
async_setup_discovery(hass, hassio, config)
# Init auth Hass.io feature
async_setup_auth(hass)
return True

View File

@@ -0,0 +1,74 @@
"""Implement the auth feature from Hass.io for Add-ons."""
import logging
from ipaddress import ip_address
import os
from aiohttp import web
from aiohttp.web_exceptions import HTTPForbidden, HTTPNotFound
import voluptuous as vol
from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv
from homeassistant.exceptions import HomeAssistantError
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http.const import KEY_REAL_IP
from homeassistant.components.http.data_validator import RequestDataValidator
from .const import ATTR_USERNAME, ATTR_PASSWORD, ATTR_ADDON
_LOGGER = logging.getLogger(__name__)
SCHEMA_API_AUTH = vol.Schema({
vol.Required(ATTR_USERNAME): cv.string,
vol.Required(ATTR_PASSWORD): cv.string,
vol.Required(ATTR_ADDON): cv.string,
}, extra=vol.ALLOW_EXTRA)
@callback
def async_setup_auth(hass):
"""Auth setup."""
hassio_auth = HassIOAuth(hass)
hass.http.register_view(hassio_auth)
class HassIOAuth(HomeAssistantView):
"""Hass.io view to handle base part."""
name = "api:hassio_auth"
url = "/api/hassio_auth"
def __init__(self, hass):
"""Initialize WebView."""
self.hass = hass
@RequestDataValidator(SCHEMA_API_AUTH)
async def post(self, request, data):
"""Handle new discovery requests."""
hassio_ip = os.environ['HASSIO'].split(':')[0]
if request[KEY_REAL_IP] != ip_address(hassio_ip):
_LOGGER.error(
"Invalid auth request from %s", request[KEY_REAL_IP])
raise HTTPForbidden()
await self._check_login(data[ATTR_USERNAME], data[ATTR_PASSWORD])
return web.Response(status=200)
def _get_provider(self):
"""Return Homeassistant auth provider."""
for prv in self.hass.auth.auth_providers:
if prv.type == 'homeassistant':
return prv
_LOGGER.error("Can't find Home Assistant auth.")
raise HTTPNotFound()
async def _check_login(self, username, password):
"""Check User credentials."""
provider = self._get_provider()
try:
await provider.async_validate_login(username, password)
except HomeAssistantError:
raise HTTPForbidden() from None

View File

@@ -0,0 +1,12 @@
"""Hass.io const variables."""
ATTR_DISCOVERY = 'discovery'
ATTR_ADDON = 'addon'
ATTR_NAME = 'name'
ATTR_SERVICE = 'service'
ATTR_CONFIG = 'config'
ATTR_UUID = 'uuid'
ATTR_USERNAME = 'username'
ATTR_PASSWORD = 'password'
X_HASSIO = 'X-HASSIO-KEY'

View File

@@ -5,21 +5,17 @@ import logging
from aiohttp import web
from aiohttp.web_exceptions import HTTPServiceUnavailable
from homeassistant.core import callback
from homeassistant.core import callback, CoreState
from homeassistant.const import EVENT_HOMEASSISTANT_START
from homeassistant.components.http import HomeAssistantView
from .handler import HassioAPIError
from .const import (
ATTR_DISCOVERY, ATTR_ADDON, ATTR_NAME, ATTR_SERVICE, ATTR_CONFIG,
ATTR_UUID)
_LOGGER = logging.getLogger(__name__)
ATTR_DISCOVERY = 'discovery'
ATTR_ADDON = 'addon'
ATTR_NAME = 'name'
ATTR_SERVICE = 'service'
ATTR_CONFIG = 'config'
ATTR_UUID = 'uuid'
@callback
def async_setup_discovery(hass, hassio, config):
@@ -40,8 +36,11 @@ def async_setup_discovery(hass, hassio, config):
if jobs:
await asyncio.wait(jobs)
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, async_discovery_start_handler)
if hass.state == CoreState.running:
hass.async_create_task(async_discovery_start_handler(None))
else:
hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_START, async_discovery_start_handler)
hass.http.register_view(hassio_discovery)

View File

@@ -16,9 +16,9 @@ from homeassistant.components.http import (
CONF_SSL_CERTIFICATE)
from homeassistant.const import CONF_TIME_ZONE, SERVER_PORT
_LOGGER = logging.getLogger(__name__)
from .const import X_HASSIO
X_HASSIO = 'X-HASSIO-KEY'
_LOGGER = logging.getLogger(__name__)
class HassioAPIError(RuntimeError):

View File

@@ -18,9 +18,10 @@ from aiohttp.web_exceptions import HTTPBadGateway
from homeassistant.const import CONTENT_TYPE_TEXT_PLAIN
from homeassistant.components.http import KEY_AUTHENTICATED, HomeAssistantView
from .const import X_HASSIO
_LOGGER = logging.getLogger(__name__)
X_HASSIO = 'X-HASSIO-KEY'
NO_TIMEOUT = re.compile(
r'^(?:'

View File

@@ -18,7 +18,7 @@
"name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0434\u043b\u044f \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432)",
"pin": "PIN-\u043a\u043e\u0434 (\u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e)"
},
"title": "\u0412\u044b\u0431\u0438\u0440\u0438\u0442\u0435 \u0442\u043e\u0447\u043a\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 HomematicIP"
"title": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0442\u043e\u0447\u043a\u0443 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 HomematicIP"
},
"link": {
"description": "\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u0441\u0438\u043d\u044e\u044e \u043a\u043d\u043e\u043f\u043a\u0443 \u043d\u0430 \u0442\u043e\u0447\u043a\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0438 \u043a\u043d\u043e\u043f\u043a\u0443 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c HomematicIP \u0432 Home Assistant. \n\n ![\u0420\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438](/static/images/config_flows/config_homematicip_cloud.png)",

View File

@@ -0,0 +1,11 @@
{
"config": {
"step": {
"user": {
"description": "Opravdu chcete nastavit IFTTT?",
"title": "Nastavte applet IFTTT Webhook"
}
},
"title": "IFTTT"
}
}

View File

@@ -5,7 +5,7 @@
"one_instance_allowed": "Nur eine einzige Instanz ist notwendig."
},
"create_entry": {
"default": "Um Ereignisse an den Home Assistant zu senden, m\u00fcssen Sie die Aktion \"Eine Webanforderung erstellen\" aus dem [IFTTT Webhook Applet]({applet_url}) ausw\u00e4hlen.\n\nF\u00fcllen Sie folgende Informationen aus: \n- URL: `{webhook_url}`\n- Methode: POST\n- Inhaltstyp: application/json\n\nIn der Dokumentation ({docs_url}) finden Sie Informationen zur Konfiguration der Automation eingehender Daten."
"default": "Um Ereignisse an Home Assistant zu senden, musst du die Aktion \"Eine Webanforderung erstellen\" aus dem [IFTTT Webhook Applet]({applet_url}) ausw\u00e4hlen.\n\nF\u00fclle folgende Informationen aus: \n- URL: `{webhook_url}`\n- Methode: POST\n- Inhaltstyp: application/json\n\nIn der Dokumentation ({docs_url}) findest du Informationen zur Konfiguration der Automation eingehender Daten."
},
"step": {
"user": {

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"not_internet_accessible": "Votre instance Home Assistant doit \u00eatre accessible \u00e0 partir d'Internet pour recevoir les messages IFTTT.",
"one_instance_allowed": "Une seule instance est n\u00e9cessaire."
},
"create_entry": {
"default": "Pour envoyer des \u00e9v\u00e9nements \u00e0 Home Assistant, vous devez utiliser l'action \"Effectuer une demande Web\" \u00e0 partir de [l'applet IFTTT Webhook] ( {applet_url} ). \n\n Remplissez les informations suivantes: \n\n - URL: ` {webhook_url} ` \n - M\u00e9thode: POST \n - Type de contenu: application / json \n\n Voir [la documentation] ( {docs_url} ) pour savoir comment configurer les automatisations pour g\u00e9rer les donn\u00e9es entrantes."
},
"step": {
"user": {
"description": "\u00cates-vous s\u00fbr de vouloir configurer IFTTT?",
"title": "Configurer l'applet IFTTT Webhook"
}
},
"title": "IFTTT"
}
}

View File

@@ -5,7 +5,7 @@
"one_instance_allowed": "\ud558\ub098\uc758 \uc778\uc2a4\ud134\uc2a4\ub9cc \ud544\uc694\ud569\ub2c8\ub2e4."
},
"create_entry": {
"default": "Home Assistant \ub85c \uc774\ubca4\ud2b8\ub97c \ubcf4\ub0b4\uae30 \uc704\ud574\uc11c\ub294 [IFTTT Webhook \uc560\ud50c\ub9bf]({applet_url}) \uc5d0\uc11c \"Make a web request\" \ub97c \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4. \n\n \ub2e4\uc74c\uc758 \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc138\uc694.\n\n - URL: `{webhook_url}` \n - Method: POST \n - Content Type: application/json \n\n Home Assistant \ub85c \ub4e4\uc5b4\uc624\ub294 \ub370\uc774\ud130\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud55c \uc790\ub3d9\ud654\ub97c \uad6c\uc131\ud558\ub294 \ubc29\ubc95\uc740 [\ubcf8 \ubb38\uc11c]({docs_url}) \ub97c \ucc38\uc870\ud574 \uc8fc\uc138\uc694."
"default": "Home Assistant \ub85c \uc774\ubca4\ud2b8\ub97c \ubcf4\ub0b4\uae30 \uc704\ud574\uc11c\ub294 [IFTTT Webhook \uc560\ud50c\ub9bf]({applet_url}) \uc5d0\uc11c \"Make a web request\" \ub97c \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4. \n\n \ub2e4\uc74c\uc758 \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc138\uc694.\n\n - URL: `{webhook_url}` \n - Method: POST \n - Content Type: application/json \n\n Home Assistant \ub85c \ub4e4\uc5b4\uc624\ub294 \ub370\uc774\ud130\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud55c \uc790\ub3d9\ud654\ub97c \uad6c\uc131\ud558\ub294 \ubc29\ubc95\uc740 [\uc548\ub0b4]({docs_url})\ub97c \ucc38\uc870\ud574 \uc8fc\uc138\uc694."
},
"step": {
"user": {

View File

@@ -0,0 +1,10 @@
{
"config": {
"step": {
"user": {
"description": "Sigur dori\u021bi s\u0103 configura\u021bi IFTTT?"
}
},
"title": "IFTTT"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"abort": {
"not_internet_accessible": "Va\u0161 Home Assistent mora biti dostopek prek interneta, da boste lahko prejemali IFTTT sporo\u010dila.",
"one_instance_allowed": "Potrebna je samo ena instanca."
},
"create_entry": {
"default": "\u010ce \u017eelite poslati dogodke Home Assistent-u, boste morali uporabiti akcijo \u00bbNaredi spletno zahtevo\u00ab iz orodja [IFTTT Webhook applet] ( {applet_url} ). \n\n Izpolnite naslednje podatke: \n\n - URL: ` {webhook_url} ` \n - Metoda: POST \n - Vrsta vsebine: application/json \n\n Poglejte si [dokumentacijo] ( {docs_url} ) o tem, kako konfigurirati avtomatizacijo za obdelavo dohodnih podatkov."
},
"step": {
"user": {
"description": "Ali ste prepri\u010dani, da \u017eelite nastaviti IFTTT?",
"title": "Nastavite IFTTT Webhook Applet"
}
},
"title": "IFTTT"
}
}

View File

@@ -1,5 +1,18 @@
{
"config": {
"abort": {
"not_internet_accessible": "Din Home Assistant instans m\u00e5ste vara tillg\u00e4nglig fr\u00e5n internet f\u00f6r att ta emot IFTTT meddelanden.",
"one_instance_allowed": "Endast en enda instans \u00e4r n\u00f6dv\u00e4ndig."
},
"create_entry": {
"default": "F\u00f6r att skicka h\u00e4ndelser till Home Assistant m\u00e5ste du anv\u00e4nda \u00e5tg\u00e4rden \"G\u00f6r en webbf\u00f6rfr\u00e5gan\" fr\u00e5n [IFTTT Webhook applet] ( {applet_url} ).\n\n Fyll i f\u00f6ljande information:\n \n - URL: ` {webhook_url} `\n - Metod: POST\n - Inneh\u00e5llstyp: application / json\n\n Se [dokumentationen] ( {docs_url} ) om hur du konfigurerar automatiseringar f\u00f6r att hantera inkommande data."
},
"step": {
"user": {
"description": "\u00c4r du s\u00e4ker p\u00e5 att du vill st\u00e4lla in IFTTT?",
"title": "St\u00e4lla in IFTTT Webhook Applet"
}
},
"title": "IFTTT"
}
}

View File

@@ -1,8 +1,8 @@
{
"config": {
"abort": {
"not_internet_accessible": "Home Assistant \u5be6\u4f8b\u5fc5\u9808\u80fd\u5920\u7531\u7db2\u969b\u7db2\u8def\u5b58\u53d6\uff0c\u65b9\u80fd\u63a5\u53d7 IFTTT \u8a0a\u606f\u3002",
"one_instance_allowed": "\u50c5\u9700\u8a2d\u5b9a\u4e00\u7d44\u5be6\u4f8b\u5373\u53ef\u3002"
"not_internet_accessible": "Home Assistant \u7269\u4ef6\u5fc5\u9808\u80fd\u5920\u7531\u7db2\u969b\u7db2\u8def\u5b58\u53d6\uff0c\u65b9\u80fd\u63a5\u53d7 IFTTT \u8a0a\u606f\u3002",
"one_instance_allowed": "\u50c5\u9700\u8a2d\u5b9a\u4e00\u7d44\u7269\u4ef6\u5373\u53ef\u3002"
},
"create_entry": {
"default": "\u6b32\u50b3\u9001\u4e8b\u4ef6\u81f3 Home Assistant\uff0c\u5c07\u9700\u8981\u7531 [IFTTT Webhook applet]({applet_url}) \u547c\u53eb\u300c\u9032\u884c Web \u8acb\u6c42\u300d\u52d5\u4f5c\u3002\n\n\u8acb\u586b\u5beb\u4e0b\u5217\u8cc7\u8a0a\uff1a\n\n- URL: `{webhook_url}`\n- Method: POST\n- Content Type: application/json\n\n\u95dc\u65bc\u5982\u4f55\u50b3\u5165\u8cc7\u6599\u81ea\u52d5\u5316\u8a2d\u5b9a\uff0c\u8acb\u53c3\u95b1[\u6587\u4ef6]({docs_url})\u4ee5\u9032\u884c\u4e86\u89e3\u3002"

View File

@@ -1,5 +1,8 @@
{
"config": {
"abort": {
"single_instance_allowed": "Endast en enda konfiguration av Home Assistant iOS \u00e4r n\u00f6dv\u00e4ndig."
},
"step": {
"confirm": {
"description": "Vill du konfigurera Home Assistants iOS komponent?",

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "No s'han trobat dispositius LIFX a la xarxa.",
"single_instance_allowed": "Nom\u00e9s \u00e9s possible una \u00fanica configuraci\u00f3 de LIFX."
},
"step": {
"confirm": {
"description": "Voleu configurar LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "V s\u00edti nejsou nalezena \u017e\u00e1dn\u00e1 za\u0159\u00edzen\u00ed LIFX.",
"single_instance_allowed": "K dispozici je pouze jedna konfigurace LIFX."
},
"step": {
"confirm": {
"description": "Chcete nastavit LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "Keine LIFX Ger\u00e4te im Netzwerk gefunden.",
"single_instance_allowed": "Nur eine einzige Konfiguration von LIFX ist zul\u00e4ssig."
},
"step": {
"confirm": {
"description": "M\u00f6chtest du LIFX einrichten?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "No LIFX devices found on the network.",
"single_instance_allowed": "Only a single configuration of LIFX is possible."
},
"step": {
"confirm": {
"description": "Do you want to set up LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "Aucun p\u00e9riph\u00e9rique LIFX trouv\u00e9 sur le r\u00e9seau.",
"single_instance_allowed": "Une seule configuration de LIFX est possible."
},
"step": {
"confirm": {
"description": "Voulez-vous configurer LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,10 @@
{
"config": {
"step": {
"confirm": {
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "LIFX \uc7a5\uce58\uac00 \ub124\ud2b8\uc6cc\ud06c\uc5d0\uc11c \ubc1c\uacac\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.",
"single_instance_allowed": "\ud558\ub098\uc758 LIFX \ub9cc \uad6c\uc131 \ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4."
},
"step": {
"confirm": {
"description": "LIFX \ub97c \uc124\uc815\ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "Keng LIFX Apparater am Netzwierk fonnt.",
"single_instance_allowed": "N\u00ebmmen eng eenzeg Konfiguratioun vun LIFX ass erlaabt."
},
"step": {
"confirm": {
"description": "Soll LIFX konfigur\u00e9iert ginn?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "Geen LIFX-apparaten gevonden op het netwerk.",
"single_instance_allowed": "Slechts een enkele configuratie van LIFX is mogelijk."
},
"step": {
"confirm": {
"description": "Wilt u LIFX instellen?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "Ingen LIFX-enheter funnet p\u00e5 nettverket.",
"single_instance_allowed": "Kun en enkelt konfigurasjon av LIFX er mulig."
},
"step": {
"confirm": {
"description": "\u00d8nsker du \u00e5 sette opp LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "Nie znaleziono w sieci urz\u0105dze\u0144 LIFX.",
"single_instance_allowed": "Wymagana jest tylko jedna konfiguracja LIFX."
},
"step": {
"confirm": {
"description": "Czy chcesz skonfigurowa\u0107 LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "Nu exist\u0103 dispozitive LIFX g\u0103site \u00een re\u021bea.",
"single_instance_allowed": "Doar o singur\u0103 configura\u021bie de LIFX este posibil\u0103."
},
"step": {
"confirm": {
"description": "Dori\u021bi s\u0103 configura\u021bi LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 LIFX \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u0432 \u0441\u0435\u0442\u0438.",
"single_instance_allowed": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430"
},
"step": {
"confirm": {
"description": "\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "V omre\u017eju ni najdenih naprav LIFX.",
"single_instance_allowed": "Mo\u017ena je samo ena konfiguracija LIFX-a."
},
"step": {
"confirm": {
"description": "Ali \u017eelite nastaviti LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "Inga LIFX enheter hittas i n\u00e4tverket.",
"single_instance_allowed": "Endast en enda konfiguration av LIFX \u00e4r m\u00f6jlig."
},
"step": {
"confirm": {
"description": "Vill du st\u00e4lla in LIFX?",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "\u6ca1\u6709\u5728\u7f51\u7edc\u4e0a\u627e\u5230 LIFX \u8bbe\u5907\u3002",
"single_instance_allowed": "LIFX \u53ea\u80fd\u914d\u7f6e\u4e00\u6b21\u3002"
},
"step": {
"confirm": {
"description": "\u60a8\u60f3\u8981\u914d\u7f6e LIFX \u5417\uff1f",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -0,0 +1,15 @@
{
"config": {
"abort": {
"no_devices_found": "\u5728\u7db2\u8def\u4e0a\u627e\u4e0d\u5230 LIFX \u88dd\u7f6e\u3002",
"single_instance_allowed": "\u50c5\u80fd\u8a2d\u5b9a\u4e00\u7d44 LIFX\u3002"
},
"step": {
"confirm": {
"description": "\u662f\u5426\u8981\u8a2d\u5b9a LIFX\uff1f",
"title": "LIFX"
}
},
"title": "LIFX"
}
}

View File

@@ -713,7 +713,7 @@ class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight):
_LOGGER.debug("Got new state: %s", state)
self._available = True
self._state = state.eyecare
self._state = state.ambient
self._brightness = ceil((255 / 100.0) * state.ambient_brightness)
except DeviceException as ex:

View File

@@ -133,14 +133,21 @@ class LogbookView(HomeAssistantView):
else:
datetime = dt_util.start_of_local_day()
start_day = dt_util.as_utc(datetime)
end_day = start_day + timedelta(days=1)
period = request.query.get('period')
if period is None:
period = 1
else:
period = int(period)
entity_id = request.query.get('entity')
start_day = dt_util.as_utc(datetime) - timedelta(days=period - 1)
end_day = start_day + timedelta(days=period)
hass = request.app['hass']
def json_events():
"""Fetch events and generate JSON."""
return self.json(list(
_get_events(hass, self.config, start_day, end_day)))
_get_events(hass, self.config, start_day, end_day, entity_id)))
return await hass.async_add_job(json_events)
@@ -288,7 +295,7 @@ def humanify(hass, events):
}
def _get_events(hass, config, start_day, end_day):
def _get_events(hass, config, start_day, end_day, entity_id=None):
"""Get events for a period of time."""
from homeassistant.components.recorder.models import Events, States
from homeassistant.components.recorder.util import (
@@ -302,6 +309,10 @@ def _get_events(hass, config, start_day, end_day):
& (Events.time_fired < end_day)) \
.filter((States.last_updated == States.last_changed)
| (States.state_id.is_(None)))
if entity_id is not None:
query = query.filter(States.entity_id == entity_id.lower())
events = execute(query)
return humanify(hass, _exclude_events(events, config))

View File

@@ -25,7 +25,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
from homeassistant.util import get_local_ip
REQUIREMENTS = ['async-upnp-client==0.12.4']
REQUIREMENTS = ['async-upnp-client==0.12.6']
_LOGGER = logging.getLogger(__name__)

View File

@@ -30,7 +30,7 @@ _LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'Samsung TV Remote'
DEFAULT_PORT = 55000
DEFAULT_TIMEOUT = 0
DEFAULT_TIMEOUT = 1
KEY_PRESS_TIMEOUT = 1.2
KNOWN_DEVICES_KEY = 'samsungtv_known_devices'

View File

@@ -17,7 +17,7 @@ from homeassistant.const import (
STATE_PLAYING, STATE_UNKNOWN)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['snapcast==2.0.8']
REQUIREMENTS = ['snapcast==2.0.9']
_LOGGER = logging.getLogger(__name__)

View File

@@ -22,7 +22,7 @@
"data": {
"discovery": "Suche aktivieren"
},
"description": "M\u00f6chten Sie den Home Assistant so konfigurieren, dass er eine Verbindung mit dem MQTT-Broker herstellt, der vom Add-on hass.io {addon} bereitgestellt wird?",
"description": "M\u00f6chtest du Home Assistant so konfigurieren, dass er eine Verbindung mit dem MQTT-Broker herstellt, der vom Add-on hass.io {addon} bereitgestellt wird?",
"title": "MQTT Broker per Hass.io add-on"
}
},

View File

@@ -10,13 +10,20 @@
"broker": {
"data": {
"broker": "Broker",
"discovery": "Activer la d\u00e9couverte automatique",
"discovery": "Activer la d\u00e9couverte",
"password": "Mot de passe",
"port": "Port",
"username": "Nom d'utilisateur"
},
"description": "Veuillez entrer les informations de connexion de votre broker MQTT.",
"title": "MQTT"
},
"hassio_confirm": {
"data": {
"discovery": "Activer la d\u00e9couverte"
},
"description": "Vous voulez configurer Home Assistant pour vous connecter au broker MQTT fourni par l\u2019Add-on hass.io {addon} ?",
"title": "MQTT Broker via le module compl\u00e9mentaire Hass.io"
}
},
"title": "MQTT"

View File

@@ -17,6 +17,13 @@
},
"description": "Prosimo vnesite informacije o povezavi va\u0161ega MQTT posrednika.",
"title": "MQTT"
},
"hassio_confirm": {
"data": {
"discovery": "Omogo\u010di odkrivanje"
},
"description": "\u017delite konfigurirati Home Assistent-a za povezavo s posrednikom MQTT, ki ga ponuja hass.io add-on {addon} ?",
"title": "MQTT Broker prek dodatka Hass.io"
}
},
"title": "MQTT"

View File

@@ -1,13 +1,31 @@
{
"config": {
"abort": {
"single_instance_allowed": "Endast en enda konfiguration av MQTT \u00e4r till\u00e5ten."
},
"error": {
"cannot_connect": "Det gick inte att ansluta till broker."
},
"step": {
"broker": {
"data": {
"broker": "Broker",
"discovery": "Aktivera uppt\u00e4ckt",
"password": "L\u00f6senord",
"port": "Port",
"username": "Anv\u00e4ndarnamn"
}
},
"description": "V\u00e4nligen ange anslutningsinformationen f\u00f6r din MQTT broker.",
"title": "MQTT"
},
"hassio_confirm": {
"data": {
"discovery": "Aktivera uppt\u00e4ckt"
},
"description": "Vill du konfigurera Home Assistant f\u00f6r att ansluta till MQTT Broker som tillhandah\u00e5lls av hass.io-till\u00e4gget {addon} ?",
"title": "MQTT Broker via Hass.io till\u00e4gg"
}
}
},
"title": "MQTT"
}
}

View File

@@ -0,0 +1,23 @@
{
"config": {
"error": {
"cannot_connect": "\u041d\u0435\u043c\u043e\u0436\u043b\u0438\u0432\u043e \u043f\u0456\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0438\u0441\u044f \u0434\u043e \u0431\u0440\u043e\u043a\u0435\u0440\u0430."
},
"step": {
"broker": {
"data": {
"broker": "\u0411\u0440\u043e\u043a\u0435\u0440",
"discovery": "\u0423\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043e\u0448\u0443\u043a",
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
"port": "\u041f\u043e\u0440\u0442",
"username": "\u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430"
}
},
"hassio_confirm": {
"data": {
"discovery": "\u0423\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u043f\u043e\u0448\u0443\u043a"
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
{
"config": {
"error": {
"identifier_exists": "\u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0438 \u0432\u0436\u0435 \u0437\u0430\u0440\u0435\u0454\u0441\u0442\u0440\u043e\u0432\u0430\u043d\u0456"
},
"step": {
"user": {
"data": {
"elevation": "\u0412\u0438\u0441\u043e\u0442\u0430",
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
"longitude": "\u0414\u043e\u0432\u0433\u043e\u0442\u0430"
},
"title": "\u0417\u0430\u043f\u043e\u0432\u043d\u0456\u0442\u044c \u0432\u0430\u0448\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"state": {
"autumn": "\u041e\u0441\u0456\u043d\u044c",
"spring": "\u0412\u0435\u0441\u043d\u0430",
"summer": "\u041b\u0456\u0442\u043e",
"winter": "\u0417\u0438\u043c\u0430"
}
}

View File

@@ -43,12 +43,18 @@ class BlinkSensor(Entity):
self._state = None
self._unit_of_measurement = units
self._icon = icon
self._unique_id = "{}-{}".format(self._camera.serial, self._type)
@property
def name(self):
"""Return the name of the camera."""
return self._name
@property
def unique_id(self):
"""Return the unique id for the camera sensor."""
return self._unique_id
@property
def icon(self):
"""Return the icon of the sensor."""

View File

@@ -106,7 +106,7 @@ class MiFloraSensor(Entity):
async def async_added_to_hass(self):
"""Set initial state."""
@callback
def on_startup():
def on_startup(_):
self.async_schedule_update_ha_state(True)
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, on_startup)

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Aquest compte ja est\u00e0 registrat",
"invalid_credentials": "Credencials inv\u00e0lides"
},
"step": {
"user": {
"data": {
"code": "Codi (pel Home Assistant)",
"password": "Contrasenya",
"username": "Correu electr\u00f2nic"
},
"title": "Introdu\u00efu la vostra informaci\u00f3"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"error": {
"identifier_exists": "\u00da\u010det je ji\u017e zaregistrov\u00e1n",
"invalid_credentials": "Neplatn\u00e9 p\u0159ihla\u0161ovac\u00ed \u00fadaje"
},
"step": {
"user": {
"data": {
"code": "K\u00f3d (pro Home Assistant)",
"password": "Heslo",
"username": "E-mailov\u00e1 adresa"
},
"title": "Vypl\u0148te va\u0161e \u00fadaje"
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Konto bereits registriert",
"invalid_credentials": "Ung\u00fcltige Anmeldeinformationen"
},
"step": {
"user": {
"data": {
"code": "Code (f\u00fcr Home Assistant)",
"password": "Passwort",
"username": "E-Mail-Adresse"
},
"title": "Gebe deine Informationen ein"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,11 @@
{
"config": {
"step": {
"user": {
"data": {
"password": "Jelsz\u00f3"
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Account gi\u00e0 registrato",
"invalid_credentials": "Credenziali non valide"
},
"step": {
"user": {
"data": {
"code": "Codice (Home Assistant)",
"password": "Password",
"username": "Indirizzo email"
},
"title": "Inserisci i tuoi dati"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "\uacc4\uc815\uc774 \uc774\ubbf8 \ub4f1\ub85d\ub418\uc5c8\uc2b5\ub2c8\ub2e4",
"invalid_credentials": "\uc774\uba54\uc77c \uc8fc\uc18c \ud639\uc740 \ube44\ubc00\ubc88\ud638\uac00 \uc798\ubabb\ub418\uc5c8\uc2b5\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"code": "\ucf54\ub4dc (Home Assistant \uc6a9)",
"password": "\ube44\ubc00\ubc88\ud638",
"username": "\uc774\uba54\uc77c \uc8fc\uc18c"
},
"title": "\uc0ac\uc6a9\uc790 \uc815\ubcf4\ub97c \uc785\ub825\ud574 \uc8fc\uc138\uc694"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Konto ass scho registr\u00e9iert",
"invalid_credentials": "Ong\u00eblteg Login Informatioune"
},
"step": {
"user": {
"data": {
"code": "Code (fir Home Assistant)",
"password": "Passwuert",
"username": "E-Mail Adress"
},
"title": "F\u00ebllt \u00e4r Informatiounen aus"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Konto er allerede registrert",
"invalid_credentials": "Ugyldig legitimasjon"
},
"step": {
"user": {
"data": {
"code": "Kode (for Home Assistant)",
"password": "Passord",
"username": "E-postadresse"
},
"title": "Fyll ut informasjonen din"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Konto zosta\u0142o ju\u017c zarejestrowane",
"invalid_credentials": "Nieprawid\u0142owe po\u015bwiadczenia"
},
"step": {
"user": {
"data": {
"code": "Kod (dla Home Assistant'a)",
"password": "Has\u0142o",
"username": "Adres e-mail"
},
"title": "Wprowad\u017a swoje dane"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,17 @@
{
"config": {
"error": {
"identifier_exists": "Contul este deja \u00eenregistrat",
"invalid_credentials": "Credentiale invalide"
},
"step": {
"user": {
"data": {
"password": "Parola",
"username": "Adresa de email"
},
"title": "Completa\u021bi informa\u021biile dvs."
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "\u0423\u0447\u0435\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430",
"invalid_credentials": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435"
},
"step": {
"user": {
"data": {
"code": "\u041a\u043e\u0434 (\u0434\u043b\u044f Home Assistant)",
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
"username": "\u0410\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b"
},
"title": "\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u0432\u043e\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "Ra\u010dun je \u017ee registriran",
"invalid_credentials": "Neveljavne poverilnice"
},
"step": {
"user": {
"data": {
"code": "Koda (za Home Assistant)",
"password": "Geslo",
"username": "E-po\u0161tni naslov"
},
"title": "Izpolnite svoje podatke"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,14 @@
{
"config": {
"step": {
"user": {
"data": {
"code": "\u041a\u043e\u0434 (\u0434\u043b\u044f Home Assistant)",
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
"username": "\u0410\u0434\u0440\u0435\u0441\u0430 \u0435\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0457 \u043f\u043e\u0448\u0442\u0438"
},
"title": "\u0417\u0430\u043f\u043e\u0432\u043d\u0456\u0442\u044c \u0432\u0430\u0448\u0443 \u0456\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0456\u044e"
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "\u5e10\u6237\u5df2\u6ce8\u518c",
"invalid_credentials": "\u65e0\u6548\u7684\u8eab\u4efd\u8ba4\u8bc1"
},
"step": {
"user": {
"data": {
"code": "\u4ee3\u7801\uff08\u7528\u4e8eHome Assistant\uff09",
"password": "\u5bc6\u7801",
"username": "\u7535\u5b50\u90ae\u4ef6\u5730\u5740"
},
"title": "\u586b\u5199\u60a8\u7684\u4fe1\u606f"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"identifier_exists": "\u5e33\u865f\u5df2\u8a3b\u518a",
"invalid_credentials": "\u6191\u8b49\u7121\u6548"
},
"step": {
"user": {
"data": {
"code": "\u9a57\u8b49\u78bc\uff08Home Assistant \u7528\uff09",
"password": "\u5bc6\u78bc",
"username": "\u96fb\u5b50\u90f5\u4ef6\u5730\u5740"
},
"title": "\u586b\u5beb\u8cc7\u8a0a"
}
},
"title": "SimpliSafe"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "El nom ja existeix",
"wrong_location": "Ubicaci\u00f3 nom\u00e9s a Su\u00e8cia"
},
"step": {
"user": {
"data": {
"latitude": "Latitud",
"longitude": "Longitud",
"name": "Nom"
},
"title": "Ubicaci\u00f3 a Su\u00e8cia"
}
},
"title": "Servei meteorol\u00f2gic suec (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "N\u00e1zev ji\u017e existuje",
"wrong_location": "Lokalita pouze pro \u0160v\u00e9dsko"
},
"step": {
"user": {
"data": {
"latitude": "Zem\u011bpisn\u00e1 \u0161\u00ed\u0159ka",
"longitude": "Zem\u011bpisn\u00e1 d\u00e9lka",
"name": "N\u00e1zev"
},
"title": "Lokalita ve \u0160v\u00e9dsku"
}
},
"title": "\u0160v\u00e9dsk\u00e1 meteorologick\u00e1 slu\u017eba (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "Name existiert bereits",
"wrong_location": "Standort nur in Schweden"
},
"step": {
"user": {
"data": {
"latitude": "Breitengrad",
"longitude": "L\u00e4ngengrad",
"name": "Name"
},
"title": "Standort in Schweden"
}
},
"title": "Schwedischer Wetterdienst (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "Name already exists",
"wrong_location": "Location Sweden only"
},
"step": {
"user": {
"data": {
"latitude": "Latitude",
"longitude": "Longitude",
"name": "Name"
},
"title": "Location in Sweden"
}
},
"title": "Swedish weather service (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "\uc774\ub984\uc774 \uc774\ubbf8 \uc874\uc7ac\ud569\ub2c8\ub2e4",
"wrong_location": "\uc2a4\uc6e8\ub374 \uc9c0\uc5ed \uc804\uc6a9\uc785\ub2c8\ub2e4"
},
"step": {
"user": {
"data": {
"latitude": "\uc704\ub3c4",
"longitude": "\uacbd\ub3c4",
"name": "\uc774\ub984"
},
"title": "\uc2a4\uc6e8\ub374 \uc9c0\uc5ed \uc704\uce58"
}
},
"title": "\uc2a4\uc6e8\ub374 \uae30\uc0c1 \uc11c\ube44\uc2a4 (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "Numm g\u00ebtt et schonn",
"wrong_location": "N\u00ebmmen Uertschaften an Schweden"
},
"step": {
"user": {
"data": {
"latitude": "Breedegrad",
"longitude": "L\u00e4ngegrad",
"name": "Numm"
},
"title": "Uertschaft an Schweden"
}
},
"title": "Schwedeschen Wieder D\u00e9ngscht (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "Naam bestaat al",
"wrong_location": "Locatie alleen Zweden"
},
"step": {
"user": {
"data": {
"latitude": "Breedtegraad",
"longitude": "Lengtegraad",
"name": "Naam"
},
"title": "Locatie in Zweden"
}
},
"title": "Zweedse weerdienst (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "Navnet eksisterer allerede",
"wrong_location": "Bare plassering i Sverige"
},
"step": {
"user": {
"data": {
"latitude": "Breddegrad",
"longitude": "Lengdegrad",
"name": "Navn"
},
"title": "Plassering i Sverige"
}
},
"title": "Sveriges Meteorologiske og Hydrologiske Institut (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "Nazwa ju\u017c istnieje",
"wrong_location": "Lokalizacja w Szwecji"
},
"step": {
"user": {
"data": {
"latitude": "Szeroko\u015b\u0107 geograficzna",
"longitude": "D\u0142ugo\u015b\u0107 geograficzna",
"name": "Nazwa"
},
"title": "Lokalizacja w Szwecji"
}
},
"title": "Szwedzka us\u0142uga pogodowa (SMHI)"
}
}

View File

@@ -0,0 +1,18 @@
{
"config": {
"error": {
"name_exists": "Numele exist\u0103 deja"
},
"step": {
"user": {
"data": {
"latitude": "Latitudine",
"longitude": "Longitudine",
"name": "Nume"
},
"title": "Loca\u021bie \u00een Suedia"
}
},
"title": "Serviciul meteorologic suedez (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "\u0418\u043c\u044f \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442",
"wrong_location": "\u0422\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0428\u0432\u0435\u0446\u0438\u0438"
},
"step": {
"user": {
"data": {
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
"longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430",
"name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"
},
"title": "\u041c\u0435\u0441\u0442\u043e\u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0432 \u0428\u0432\u0435\u0446\u0438\u0438"
}
},
"title": "\u0428\u0432\u0435\u0434\u0441\u043a\u0430\u044f \u043c\u0435\u0442\u0435\u043e\u0440\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0441\u043b\u0443\u0436\u0431\u0430 (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "Ime \u017ee obstaja",
"wrong_location": "Lokacija le na \u0160vedskem"
},
"step": {
"user": {
"data": {
"latitude": "Zemljepisna \u0161irina",
"longitude": "Zemljepisna dol\u017eina",
"name": "Ime"
},
"title": "Lokacija na \u0160vedskem"
}
},
"title": "\u0160vedska vremenska slu\u017eba (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "Namnet finns redan",
"wrong_location": "Plats i Sverige endast"
},
"step": {
"user": {
"data": {
"latitude": "Latitud",
"longitude": "Longitud",
"name": "Namn"
},
"title": "Plats i Sverige"
}
},
"title": "Svensk v\u00e4derservice (SMHI)"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "\u540d\u79f0\u5df2\u5b58\u5728",
"wrong_location": "\u4ec5\u9650\u745e\u5178\u7684\u4f4d\u7f6e"
},
"step": {
"user": {
"data": {
"latitude": "\u7eac\u5ea6",
"longitude": "\u7ecf\u5ea6",
"name": "\u540d\u79f0"
},
"title": "\u5728\u745e\u5178\u7684\u4f4d\u7f6e"
}
},
"title": "\u745e\u5178\u6c14\u8c61\u670d\u52a1\uff08SMHI\uff09"
}
}

View File

@@ -0,0 +1,19 @@
{
"config": {
"error": {
"name_exists": "\u8a72\u540d\u7a31\u5df2\u5b58\u5728",
"wrong_location": "\u50c5\u9650\u745e\u5178\u5ea7\u6a19"
},
"step": {
"user": {
"data": {
"latitude": "\u7def\u5ea6",
"longitude": "\u7d93\u5ea6",
"name": "\u540d\u7a31"
},
"title": "\u745e\u5178\u5ea7\u6a19"
}
},
"title": "\u745e\u5178\u6c23\u8c61\u670d\u52d9\uff08SMHI\uff09"
}
}

View File

@@ -6,7 +6,7 @@
},
"step": {
"confirm": {
"description": "Sonos\ub97c \uc124\uc815 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
"description": "Sonos \ub97c \uc124\uc815 \ud558\uc2dc\uaca0\uc2b5\ub2c8\uae4c?",
"title": "Sonos"
}
},

View File

@@ -6,7 +6,7 @@
},
"step": {
"confirm": {
"description": "Chcesz skonfigurowa\u0107 Sonos?",
"description": "Czy chcesz skonfigurowa\u0107 Sonos?",
"title": "Sonos"
}
},

View File

@@ -1,7 +1,7 @@
{
"config": {
"abort": {
"no_devices_found": "\u5728\u7db2\u8def\u4e0a\u627e\u4e0d\u5230 Sonos \u8a2d\u5099\u3002",
"no_devices_found": "\u5728\u7db2\u8def\u4e0a\u627e\u4e0d\u5230 Sonos \u88dd\u7f6e\u3002",
"single_instance_allowed": "\u50c5\u9700\u8a2d\u5b9a\u4e00\u6b21 Sonos \u5373\u53ef\u3002"
},
"step": {

View File

@@ -309,10 +309,10 @@ def initialize_bot(p_config):
proxy_params = p_config.get(CONF_PROXY_PARAMS)
if proxy_url is not None:
request = Request(con_pool_size=4, proxy_url=proxy_url,
request = Request(con_pool_size=8, proxy_url=proxy_url,
urllib3_proxy_kwargs=proxy_params)
else:
request = Request(con_pool_size=4)
request = Request(con_pool_size=8)
return Bot(token=api_key, request=request)

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