mirror of
https://github.com/home-assistant/core.git
synced 2026-01-13 19:17:24 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c5efd5b7e | ||
|
|
c3b6086d80 | ||
|
|
0d93369154 | ||
|
|
644d5de890 | ||
|
|
343625d539 | ||
|
|
2e10b4bf67 | ||
|
|
d86a5a1e91 | ||
|
|
1327051277 | ||
|
|
2544635921 | ||
|
|
3c364fa7e9 | ||
|
|
ceb0ec5fa4 | ||
|
|
a28196df9a |
4
.github/ISSUE_TEMPLATE.md
vendored
4
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,4 +1,6 @@
|
||||
Make sure you run the latest version before reporting an issue. Feature requests should go in the forum: https://community.home-assistant.io/c/feature-requests
|
||||
Make sure you are running the latest version of Home Assistant before reporting an issue.
|
||||
|
||||
You should only file an issue if you found a bug. Feature and enhancement requests should go in [the Feature Requests section](https://community.home-assistant.io/c/feature-requests) of our community forum:
|
||||
|
||||
**Home Assistant release (`hass --version`):**
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ from __future__ import print_function
|
||||
import argparse
|
||||
import os
|
||||
import platform
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
@@ -321,33 +320,18 @@ def try_to_restart():
|
||||
# Count remaining threads, ideally there should only be one non-daemonized
|
||||
# thread left (which is us). Nothing we really do with it, but it might be
|
||||
# useful when debugging shutdown/restart issues.
|
||||
nthreads = sum(thread.isAlive() and not thread.isDaemon()
|
||||
for thread in threading.enumerate())
|
||||
if nthreads > 1:
|
||||
sys.stderr.write("Found {} non-daemonic threads.\n".format(nthreads))
|
||||
try:
|
||||
nthreads = sum(thread.isAlive() and not thread.isDaemon()
|
||||
for thread in threading.enumerate())
|
||||
if nthreads > 1:
|
||||
sys.stderr.write(
|
||||
"Found {} non-daemonic threads.\n".format(nthreads))
|
||||
|
||||
# Send terminate signal to all processes in our process group which
|
||||
# should be any children that have not themselves changed the process
|
||||
# group id. Don't bother if couldn't even call setpgid.
|
||||
if hasattr(os, 'setpgid'):
|
||||
sys.stderr.write("Signalling child processes to terminate...\n")
|
||||
os.kill(0, signal.SIGTERM)
|
||||
|
||||
# wait for child processes to terminate
|
||||
try:
|
||||
while True:
|
||||
time.sleep(1)
|
||||
if os.waitpid(0, os.WNOHANG) == (0, 0):
|
||||
break
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
elif os.name == 'nt':
|
||||
# Maybe one of the following will work, but how do we indicate which
|
||||
# processes are our children if there is no process group?
|
||||
# os.kill(0, signal.CTRL_C_EVENT)
|
||||
# os.kill(0, signal.CTRL_BREAK_EVENT)
|
||||
pass
|
||||
# Somehow we sometimes seem to trigger an assertion in the python threading
|
||||
# module. It seems we find threads that have no associated OS level thread
|
||||
# which are not marked as stopped at the python level.
|
||||
except AssertionError:
|
||||
sys.stderr.write("Failed to count non-daemonic threads.\n")
|
||||
|
||||
# Try to not leave behind open filedescriptors with the emphasis on try.
|
||||
try:
|
||||
@@ -400,13 +384,6 @@ def main():
|
||||
if args.pid_file:
|
||||
write_pid(args.pid_file)
|
||||
|
||||
# Create new process group if we can
|
||||
if hasattr(os, 'setpgid'):
|
||||
try:
|
||||
os.setpgid(0, 0)
|
||||
except PermissionError:
|
||||
pass
|
||||
|
||||
exit_code = setup_and_run_hass(config_dir, args)
|
||||
if exit_code == RESTART_EXIT_CODE and not args.runner:
|
||||
try_to_restart()
|
||||
|
||||
@@ -131,26 +131,38 @@ class ForeCastSensor(Entity):
|
||||
"""Return the unit system of this entity."""
|
||||
return self._unit_system
|
||||
|
||||
# pylint: disable=too-many-branches
|
||||
# pylint: disable=too-many-branches,too-many-statements
|
||||
def update(self):
|
||||
"""Get the latest data from Forecast.io and updates the states."""
|
||||
import forecastio
|
||||
|
||||
self.forecast_client.update()
|
||||
data = self.forecast_client.data.currently()
|
||||
data_minutely = self.forecast_client.data.minutely()
|
||||
data_hourly = self.forecast_client.data.hourly()
|
||||
data_daily = self.forecast_client.data.daily()
|
||||
|
||||
try:
|
||||
if self.type == 'minutely_summary':
|
||||
self.forecast_client.update_minutely()
|
||||
self._state = self.forecast_client.data_minutely.summary
|
||||
return
|
||||
|
||||
elif self.type == 'hourly_summary':
|
||||
self.forecast_client.update_hourly()
|
||||
self._state = self.forecast_client.data_hourly.summary
|
||||
return
|
||||
|
||||
elif self.type == 'daily_summary':
|
||||
self.forecast_client.update_daily()
|
||||
self._state = self.forecast_client.data_daily.summary
|
||||
return
|
||||
|
||||
except forecastio.utils.PropertyUnavailable:
|
||||
return
|
||||
|
||||
self.forecast_client.update_currently()
|
||||
data = self.forecast_client.data_currently
|
||||
|
||||
try:
|
||||
if self.type == 'summary':
|
||||
self._state = data.summary
|
||||
elif self.type == 'minutely_summary':
|
||||
self._state = data_minutely.summary
|
||||
elif self.type == 'hourly_summary':
|
||||
self._state = data_hourly.summary
|
||||
elif self.type == 'daily_summary':
|
||||
self._state = data_daily.summary
|
||||
elif self.type == 'icon':
|
||||
self._state = data.icon
|
||||
elif self.type == 'nearest_storm_distance':
|
||||
@@ -191,14 +203,22 @@ class ForeCastSensor(Entity):
|
||||
class ForeCastData(object):
|
||||
"""Gets the latest data from Forecast.io."""
|
||||
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
|
||||
def __init__(self, api_key, latitude, longitude, units):
|
||||
"""Initialize the data object."""
|
||||
self._api_key = api_key
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.units = units
|
||||
|
||||
self.data = None
|
||||
self.unit_system = None
|
||||
self.units = units
|
||||
self.data_currently = None
|
||||
self.data_minutely = None
|
||||
self.data_hourly = None
|
||||
self.data_daily = None
|
||||
|
||||
self.update()
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
@@ -206,9 +226,28 @@ class ForeCastData(object):
|
||||
"""Get the latest data from Forecast.io."""
|
||||
import forecastio
|
||||
|
||||
forecast = forecastio.load_forecast(self._api_key,
|
||||
self.latitude,
|
||||
self.longitude,
|
||||
units=self.units)
|
||||
self.data = forecast
|
||||
self.unit_system = forecast.json['flags']['units']
|
||||
self.data = forecastio.load_forecast(self._api_key,
|
||||
self.latitude,
|
||||
self.longitude,
|
||||
units=self.units)
|
||||
self.unit_system = self.data.json['flags']['units']
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update_currently(self):
|
||||
"""Update currently data."""
|
||||
self.data_currently = self.data.currently()
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update_minutely(self):
|
||||
"""Update minutely data."""
|
||||
self.data_minutely = self.data.minutely()
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update_hourly(self):
|
||||
"""Update hourly data."""
|
||||
self.data_hourly = self.data.hourly()
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update_daily(self):
|
||||
"""Update daily data."""
|
||||
self.data_daily = self.data.daily()
|
||||
|
||||
@@ -136,11 +136,12 @@ class GoogleTravelTimeSensor(Entity):
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
try:
|
||||
res = self._matrix['rows'][0]['elements'][0]['duration']['value']
|
||||
return round(res/60)
|
||||
except KeyError:
|
||||
return None
|
||||
_data = self._matrix['rows'][0]['elements'][0]
|
||||
if 'duration_in_traffic' in _data:
|
||||
return round(_data['duration_in_traffic']['value']/60)
|
||||
if 'duration' in _data:
|
||||
return round(_data['duration']['value']/60)
|
||||
return None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@@ -175,9 +176,15 @@ class GoogleTravelTimeSensor(Entity):
|
||||
atime = options_copy.get('arrival_time')
|
||||
if dtime is not None and ':' in dtime:
|
||||
options_copy['departure_time'] = convert_time_to_utc(dtime)
|
||||
elif dtime is not None:
|
||||
options_copy['departure_time'] = dtime
|
||||
else:
|
||||
options_copy['departure_time'] = 'now'
|
||||
|
||||
if atime is not None and ':' in atime:
|
||||
options_copy['arrival_time'] = convert_time_to_utc(atime)
|
||||
elif atime is not None:
|
||||
options_copy['arrival_time'] = atime
|
||||
|
||||
self._matrix = self._client.distance_matrix(self._origin,
|
||||
self._destination,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# coding: utf-8
|
||||
"""Constants used by Home Assistant components."""
|
||||
|
||||
__version__ = "0.20.0"
|
||||
__version__ = "0.20.3"
|
||||
REQUIRED_PYTHON_VER = (3, 4)
|
||||
|
||||
PLATFORM_FORMAT = '{}.{}'
|
||||
|
||||
Reference in New Issue
Block a user