mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Use voluptuous for FitBit (#3686)
* Migrate to voluptuous * Fix default
This commit is contained in:
parent
7cf9ff83bc
commit
7cf2c48175
@ -10,110 +10,125 @@ import logging
|
|||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from homeassistant.util import Throttle
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.http import HomeAssistantView
|
||||||
|
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.loader import get_component
|
from homeassistant.loader import get_component
|
||||||
from homeassistant.components.http import HomeAssistantView
|
from homeassistant.util import Throttle
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
REQUIREMENTS = ['fitbit==0.2.3']
|
||||||
REQUIREMENTS = ["fitbit==0.2.3"]
|
|
||||||
DEPENDENCIES = ["http"]
|
|
||||||
|
|
||||||
ICON = "mdi:walk"
|
|
||||||
|
|
||||||
_CONFIGURING = {}
|
_CONFIGURING = {}
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
ATTR_ACCESS_TOKEN = 'access_token'
|
||||||
|
ATTR_REFRESH_TOKEN = 'refresh_token'
|
||||||
|
ATTR_CLIENT_ID = 'client_id'
|
||||||
|
ATTR_CLIENT_SECRET = 'client_secret'
|
||||||
|
ATTR_LAST_SAVED_AT = 'last_saved_at'
|
||||||
|
|
||||||
|
CONF_MONITORED_RESOURCES = 'monitored_resources'
|
||||||
|
|
||||||
|
DEPENDENCIES = ['http']
|
||||||
|
|
||||||
|
FITBIT_AUTH_CALLBACK_PATH = '/auth/fitbit/callback'
|
||||||
|
FITBIT_AUTH_START = '/auth/fitbit'
|
||||||
|
FITBIT_CONFIG_FILE = 'fitbit.conf'
|
||||||
|
FITBIT_DEFAULT_RESOURCES = ['activities/steps']
|
||||||
|
|
||||||
|
ICON = 'mdi:walk'
|
||||||
|
|
||||||
# Return cached results if last scan was less then this time ago.
|
|
||||||
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=30)
|
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(minutes=30)
|
||||||
|
|
||||||
FITBIT_AUTH_START = "/auth/fitbit"
|
|
||||||
FITBIT_AUTH_CALLBACK_PATH = "/auth/fitbit/callback"
|
|
||||||
|
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"client_id": "CLIENT_ID_HERE",
|
'client_id': 'CLIENT_ID_HERE',
|
||||||
"client_secret": "CLIENT_SECRET_HERE"
|
'client_secret': 'CLIENT_SECRET_HERE'
|
||||||
}
|
}
|
||||||
|
|
||||||
FITBIT_CONFIG_FILE = "fitbit.conf"
|
|
||||||
|
|
||||||
FITBIT_RESOURCES_LIST = {
|
FITBIT_RESOURCES_LIST = {
|
||||||
"activities/activityCalories": "cal",
|
'activities/activityCalories': 'cal',
|
||||||
"activities/calories": "cal",
|
'activities/calories': 'cal',
|
||||||
"activities/caloriesBMR": "cal",
|
'activities/caloriesBMR': 'cal',
|
||||||
"activities/distance": "",
|
'activities/distance': '',
|
||||||
"activities/elevation": "",
|
'activities/elevation': '',
|
||||||
"activities/floors": "floors",
|
'activities/floors': 'floors',
|
||||||
"activities/heart": "bpm",
|
'activities/heart': 'bpm',
|
||||||
"activities/minutesFairlyActive": "minutes",
|
'activities/minutesFairlyActive': 'minutes',
|
||||||
"activities/minutesLightlyActive": "minutes",
|
'activities/minutesLightlyActive': 'minutes',
|
||||||
"activities/minutesSedentary": "minutes",
|
'activities/minutesSedentary': 'minutes',
|
||||||
"activities/minutesVeryActive": "minutes",
|
'activities/minutesVeryActive': 'minutes',
|
||||||
"activities/steps": "steps",
|
'activities/steps': 'steps',
|
||||||
"activities/tracker/activityCalories": "cal",
|
'activities/tracker/activityCalories': 'cal',
|
||||||
"activities/tracker/calories": "cal",
|
'activities/tracker/calories': 'cal',
|
||||||
"activities/tracker/distance": "",
|
'activities/tracker/distance': '',
|
||||||
"activities/tracker/elevation": "",
|
'activities/tracker/elevation': '',
|
||||||
"activities/tracker/floors": "floors",
|
'activities/tracker/floors': 'floors',
|
||||||
"activities/tracker/minutesFairlyActive": "minutes",
|
'activities/tracker/minutesFairlyActive': 'minutes',
|
||||||
"activities/tracker/minutesLightlyActive": "minutes",
|
'activities/tracker/minutesLightlyActive': 'minutes',
|
||||||
"activities/tracker/minutesSedentary": "minutes",
|
'activities/tracker/minutesSedentary': 'minutes',
|
||||||
"activities/tracker/minutesVeryActive": "minutes",
|
'activities/tracker/minutesVeryActive': 'minutes',
|
||||||
"activities/tracker/steps": "steps",
|
'activities/tracker/steps': 'steps',
|
||||||
"body/bmi": "BMI",
|
'body/bmi': 'BMI',
|
||||||
"body/fat": "%",
|
'body/fat': '%',
|
||||||
"sleep/awakeningsCount": "times awaken",
|
'sleep/awakeningsCount': 'times awaken',
|
||||||
"sleep/efficiency": "%",
|
'sleep/efficiency': '%',
|
||||||
"sleep/minutesAfterWakeup": "minutes",
|
'sleep/minutesAfterWakeup': 'minutes',
|
||||||
"sleep/minutesAsleep": "minutes",
|
'sleep/minutesAsleep': 'minutes',
|
||||||
"sleep/minutesAwake": "minutes",
|
'sleep/minutesAwake': 'minutes',
|
||||||
"sleep/minutesToFallAsleep": "minutes",
|
'sleep/minutesToFallAsleep': 'minutes',
|
||||||
"sleep/startTime": "start time",
|
'sleep/startTime': 'start time',
|
||||||
"sleep/timeInBed": "time in bed",
|
'sleep/timeInBed': 'time in bed',
|
||||||
"body/weight": ""
|
'body/weight': ''
|
||||||
}
|
}
|
||||||
|
|
||||||
FITBIT_DEFAULT_RESOURCE_LIST = ["activities/steps"]
|
|
||||||
|
|
||||||
FITBIT_MEASUREMENTS = {
|
FITBIT_MEASUREMENTS = {
|
||||||
"en_US": {
|
'en_US': {
|
||||||
"duration": "ms",
|
'duration': 'ms',
|
||||||
"distance": "mi",
|
'distance': 'mi',
|
||||||
"elevation": "ft",
|
'elevation': 'ft',
|
||||||
"height": "in",
|
'height': 'in',
|
||||||
"weight": "lbs",
|
'weight': 'lbs',
|
||||||
"body": "in",
|
'body': 'in',
|
||||||
"liquids": "fl. oz.",
|
'liquids': 'fl. oz.',
|
||||||
"blood glucose": "mg/dL",
|
'blood glucose': 'mg/dL',
|
||||||
},
|
},
|
||||||
"en_GB": {
|
'en_GB': {
|
||||||
"duration": "milliseconds",
|
'duration': 'milliseconds',
|
||||||
"distance": "kilometers",
|
'distance': 'kilometers',
|
||||||
"elevation": "meters",
|
'elevation': 'meters',
|
||||||
"height": "centimeters",
|
'height': 'centimeters',
|
||||||
"weight": "stone",
|
'weight': 'stone',
|
||||||
"body": "centimeters",
|
'body': 'centimeters',
|
||||||
"liquids": "milliliters",
|
'liquids': 'milliliters',
|
||||||
"blood glucose": "mmol/L"
|
'blood glucose': 'mmol/L'
|
||||||
},
|
},
|
||||||
"metric": {
|
'metric': {
|
||||||
"duration": "milliseconds",
|
'duration': 'milliseconds',
|
||||||
"distance": "kilometers",
|
'distance': 'kilometers',
|
||||||
"elevation": "meters",
|
'elevation': 'meters',
|
||||||
"height": "centimeters",
|
'height': 'centimeters',
|
||||||
"weight": "kilograms",
|
'weight': 'kilograms',
|
||||||
"body": "centimeters",
|
'body': 'centimeters',
|
||||||
"liquids": "milliliters",
|
'liquids': 'milliliters',
|
||||||
"blood glucose": "mmol/L"
|
'blood glucose': 'mmol/L'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
|
vol.Optional(CONF_MONITORED_RESOURCES, default=FITBIT_DEFAULT_RESOURCES):
|
||||||
|
vol.All(cv.ensure_list, [vol.In(FITBIT_RESOURCES_LIST)]),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def config_from_file(filename, config=None):
|
def config_from_file(filename, config=None):
|
||||||
"""Small configuration file management function."""
|
"""Small configuration file management function."""
|
||||||
if config:
|
if config:
|
||||||
# We"re writing configuration
|
# We"re writing configuration
|
||||||
try:
|
try:
|
||||||
with open(filename, "w") as fdesc:
|
with open(filename, 'w') as fdesc:
|
||||||
fdesc.write(json.dumps(config))
|
fdesc.write(json.dumps(config))
|
||||||
except IOError as error:
|
except IOError as error:
|
||||||
_LOGGER.error("Saving config file failed: %s", error)
|
_LOGGER.error("Saving config file failed: %s", error)
|
||||||
@ -123,7 +138,7 @@ def config_from_file(filename, config=None):
|
|||||||
# We"re reading config
|
# We"re reading config
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
try:
|
try:
|
||||||
with open(filename, "r") as fdesc:
|
with open(filename, 'r') as fdesc:
|
||||||
return json.loads(fdesc.read())
|
return json.loads(fdesc.read())
|
||||||
except IOError as error:
|
except IOError as error:
|
||||||
_LOGGER.error("Reading config file failed: %s", error)
|
_LOGGER.error("Reading config file failed: %s", error)
|
||||||
@ -136,7 +151,7 @@ def config_from_file(filename, config=None):
|
|||||||
def request_app_setup(hass, config, add_devices, config_path,
|
def request_app_setup(hass, config, add_devices, config_path,
|
||||||
discovery_info=None):
|
discovery_info=None):
|
||||||
"""Assist user with configuring the Fitbit dev application."""
|
"""Assist user with configuring the Fitbit dev application."""
|
||||||
configurator = get_component("configurator")
|
configurator = get_component('configurator')
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def fitbit_configuration_callback(callback_data):
|
def fitbit_configuration_callback(callback_data):
|
||||||
@ -147,7 +162,7 @@ def request_app_setup(hass, config, add_devices, config_path,
|
|||||||
if config_file == DEFAULT_CONFIG:
|
if config_file == DEFAULT_CONFIG:
|
||||||
error_msg = ("You didn't correctly modify fitbit.conf",
|
error_msg = ("You didn't correctly modify fitbit.conf",
|
||||||
" please try again")
|
" please try again")
|
||||||
configurator.notify_errors(_CONFIGURING["fitbit"], error_msg)
|
configurator.notify_errors(_CONFIGURING['fitbit'], error_msg)
|
||||||
else:
|
else:
|
||||||
setup_platform(hass, config, add_devices, discovery_info)
|
setup_platform(hass, config, add_devices, discovery_info)
|
||||||
else:
|
else:
|
||||||
@ -167,8 +182,8 @@ def request_app_setup(hass, config, add_devices, config_path,
|
|||||||
|
|
||||||
submit = "I have saved my Client ID and Client Secret into fitbit.conf."
|
submit = "I have saved my Client ID and Client Secret into fitbit.conf."
|
||||||
|
|
||||||
_CONFIGURING["fitbit"] = configurator.request_config(
|
_CONFIGURING['fitbit'] = configurator.request_config(
|
||||||
hass, "Fitbit", fitbit_configuration_callback,
|
hass, 'Fitbit', fitbit_configuration_callback,
|
||||||
description=description, submit_caption=submit,
|
description=description, submit_caption=submit,
|
||||||
description_image="/static/images/config_fitbit_app.png"
|
description_image="/static/images/config_fitbit_app.png"
|
||||||
)
|
)
|
||||||
@ -176,10 +191,10 @@ def request_app_setup(hass, config, add_devices, config_path,
|
|||||||
|
|
||||||
def request_oauth_completion(hass):
|
def request_oauth_completion(hass):
|
||||||
"""Request user complete Fitbit OAuth2 flow."""
|
"""Request user complete Fitbit OAuth2 flow."""
|
||||||
configurator = get_component("configurator")
|
configurator = get_component('configurator')
|
||||||
if "fitbit" in _CONFIGURING:
|
if "fitbit" in _CONFIGURING:
|
||||||
configurator.notify_errors(
|
configurator.notify_errors(
|
||||||
_CONFIGURING["fitbit"], "Failed to register, please try again.")
|
_CONFIGURING['fitbit'], "Failed to register, please try again.")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -187,12 +202,12 @@ def request_oauth_completion(hass):
|
|||||||
def fitbit_configuration_callback(callback_data):
|
def fitbit_configuration_callback(callback_data):
|
||||||
"""The actions to do when our configuration callback is called."""
|
"""The actions to do when our configuration callback is called."""
|
||||||
|
|
||||||
start_url = "{}{}".format(hass.config.api.base_url, FITBIT_AUTH_START)
|
start_url = '{}{}'.format(hass.config.api.base_url, FITBIT_AUTH_START)
|
||||||
|
|
||||||
description = "Please authorize Fitbit by visiting {}".format(start_url)
|
description = "Please authorize Fitbit by visiting {}".format(start_url)
|
||||||
|
|
||||||
_CONFIGURING["fitbit"] = configurator.request_config(
|
_CONFIGURING['fitbit'] = configurator.request_config(
|
||||||
hass, "Fitbit", fitbit_configuration_callback,
|
hass, 'Fitbit', fitbit_configuration_callback,
|
||||||
description=description,
|
description=description,
|
||||||
submit_caption="I have authorized Fitbit."
|
submit_caption="I have authorized Fitbit."
|
||||||
)
|
)
|
||||||
@ -206,60 +221,61 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
if os.path.isfile(config_path):
|
if os.path.isfile(config_path):
|
||||||
config_file = config_from_file(config_path)
|
config_file = config_from_file(config_path)
|
||||||
if config_file == DEFAULT_CONFIG:
|
if config_file == DEFAULT_CONFIG:
|
||||||
request_app_setup(hass, config, add_devices, config_path,
|
request_app_setup(
|
||||||
discovery_info=None)
|
hass, config, add_devices, config_path, discovery_info=None)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
config_file = config_from_file(config_path, DEFAULT_CONFIG)
|
config_file = config_from_file(config_path, DEFAULT_CONFIG)
|
||||||
request_app_setup(hass, config, add_devices, config_path,
|
request_app_setup(
|
||||||
discovery_info=None)
|
hass, config, add_devices, config_path, discovery_info=None)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if "fitbit" in _CONFIGURING:
|
if "fitbit" in _CONFIGURING:
|
||||||
get_component("configurator").request_done(_CONFIGURING.pop("fitbit"))
|
get_component('configurator').request_done(_CONFIGURING.pop("fitbit"))
|
||||||
|
|
||||||
import fitbit
|
import fitbit
|
||||||
|
|
||||||
access_token = config_file.get("access_token")
|
access_token = config_file.get(ATTR_ACCESS_TOKEN)
|
||||||
refresh_token = config_file.get("refresh_token")
|
refresh_token = config_file.get(ATTR_REFRESH_TOKEN)
|
||||||
if None not in (access_token, refresh_token):
|
if None not in (access_token, refresh_token):
|
||||||
authd_client = fitbit.Fitbit(config_file.get("client_id"),
|
authd_client = fitbit.Fitbit(config_file.get(ATTR_CLIENT_ID),
|
||||||
config_file.get("client_secret"),
|
config_file.get(ATTR_CLIENT_SECRET),
|
||||||
access_token=access_token,
|
access_token=access_token,
|
||||||
refresh_token=refresh_token)
|
refresh_token=refresh_token)
|
||||||
|
|
||||||
if int(time.time()) - config_file.get("last_saved_at", 0) > 3600:
|
if int(time.time()) - config_file.get(ATTR_LAST_SAVED_AT, 0) > 3600:
|
||||||
authd_client.client.refresh_token()
|
authd_client.client.refresh_token()
|
||||||
|
|
||||||
authd_client.system = authd_client.user_profile_get()["user"]["locale"]
|
authd_client.system = authd_client.user_profile_get()["user"]["locale"]
|
||||||
if authd_client.system != 'en_GB':
|
if authd_client.system != 'en_GB':
|
||||||
if hass.config.units.is_metric:
|
if hass.config.units.is_metric:
|
||||||
authd_client.system = "metric"
|
authd_client.system = 'metric'
|
||||||
else:
|
else:
|
||||||
authd_client.system = "en_US"
|
authd_client.system = 'en_US'
|
||||||
|
|
||||||
dev = []
|
dev = []
|
||||||
for resource in config.get("monitored_resources",
|
for resource in config.get(CONF_MONITORED_RESOURCES):
|
||||||
FITBIT_DEFAULT_RESOURCE_LIST):
|
dev.append(FitbitSensor(
|
||||||
dev.append(FitbitSensor(authd_client, config_path, resource,
|
authd_client, config_path, resource,
|
||||||
hass.config.units.is_metric))
|
hass.config.units.is_metric))
|
||||||
add_devices(dev)
|
add_devices(dev)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
oauth = fitbit.api.FitbitOauth2Client(config_file.get("client_id"),
|
oauth = fitbit.api.FitbitOauth2Client(
|
||||||
config_file.get("client_secret"))
|
config_file.get(ATTR_CLIENT_ID),
|
||||||
|
config_file.get(ATTR_CLIENT_SECRET))
|
||||||
|
|
||||||
redirect_uri = "{}{}".format(hass.config.api.base_url,
|
redirect_uri = '{}{}'.format(hass.config.api.base_url,
|
||||||
FITBIT_AUTH_CALLBACK_PATH)
|
FITBIT_AUTH_CALLBACK_PATH)
|
||||||
|
|
||||||
fitbit_auth_start_url, _ = oauth.authorize_token_url(
|
fitbit_auth_start_url, _ = oauth.authorize_token_url(
|
||||||
redirect_uri=redirect_uri,
|
redirect_uri=redirect_uri,
|
||||||
scope=["activity", "heartrate", "nutrition", "profile",
|
scope=['activity', 'heartrate', 'nutrition', 'profile',
|
||||||
"settings", "sleep", "weight"])
|
'settings', 'sleep', 'weight'])
|
||||||
|
|
||||||
hass.wsgi.register_redirect(FITBIT_AUTH_START, fitbit_auth_start_url)
|
hass.wsgi.register_redirect(FITBIT_AUTH_START, fitbit_auth_start_url)
|
||||||
hass.wsgi.register_view(FitbitAuthCallbackView(hass, config,
|
hass.wsgi.register_view(FitbitAuthCallbackView(
|
||||||
add_devices, oauth))
|
hass, config, add_devices, oauth))
|
||||||
|
|
||||||
request_oauth_completion(hass)
|
request_oauth_completion(hass)
|
||||||
|
|
||||||
@ -288,12 +304,12 @@ class FitbitAuthCallbackView(HomeAssistantView):
|
|||||||
response_message = """Fitbit has been successfully authorized!
|
response_message = """Fitbit has been successfully authorized!
|
||||||
You can close this window now!"""
|
You can close this window now!"""
|
||||||
|
|
||||||
if data.get("code") is not None:
|
if data.get('code') is not None:
|
||||||
redirect_uri = "{}{}".format(self.hass.config.api.base_url,
|
redirect_uri = '{}{}'.format(
|
||||||
FITBIT_AUTH_CALLBACK_PATH)
|
self.hass.config.api.base_url, FITBIT_AUTH_CALLBACK_PATH)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.oauth.fetch_access_token(data.get("code"), redirect_uri)
|
self.oauth.fetch_access_token(data.get('code'), redirect_uri)
|
||||||
except MissingTokenError as error:
|
except MissingTokenError as error:
|
||||||
_LOGGER.error("Missing token: %s", error)
|
_LOGGER.error("Missing token: %s", error)
|
||||||
response_message = """Something went wrong when
|
response_message = """Something went wrong when
|
||||||
@ -315,14 +331,14 @@ class FitbitAuthCallbackView(HomeAssistantView):
|
|||||||
<body><h1>{}</h1></body></html>""".format(response_message)
|
<body><h1>{}</h1></body></html>""".format(response_message)
|
||||||
|
|
||||||
config_contents = {
|
config_contents = {
|
||||||
"access_token": self.oauth.token["access_token"],
|
ATTR_ACCESS_TOKEN: self.oauth.token['access_token'],
|
||||||
"refresh_token": self.oauth.token["refresh_token"],
|
ATTR_REFRESH_TOKEN: self.oauth.token['refresh_token'],
|
||||||
"client_id": self.oauth.client_id,
|
ATTR_CLIENT_ID: self.oauth.client_id,
|
||||||
"client_secret": self.oauth.client_secret
|
ATTR_CLIENT_SECRET: self.oauth.client_secret
|
||||||
}
|
}
|
||||||
if not config_from_file(self.hass.config.path(FITBIT_CONFIG_FILE),
|
if not config_from_file(self.hass.config.path(FITBIT_CONFIG_FILE),
|
||||||
config_contents):
|
config_contents):
|
||||||
_LOGGER.error("failed to save config file")
|
_LOGGER.error("Failed to save config file")
|
||||||
|
|
||||||
setup_platform(self.hass, self.config, self.add_devices)
|
setup_platform(self.hass, self.config, self.add_devices)
|
||||||
|
|
||||||
@ -338,22 +354,22 @@ class FitbitSensor(Entity):
|
|||||||
self.client = client
|
self.client = client
|
||||||
self.config_path = config_path
|
self.config_path = config_path
|
||||||
self.resource_type = resource_type
|
self.resource_type = resource_type
|
||||||
pretty_resource = self.resource_type.replace("activities/", "")
|
pretty_resource = self.resource_type.replace('activities/', '')
|
||||||
pretty_resource = pretty_resource.replace("/", " ")
|
pretty_resource = pretty_resource.replace('/', ' ')
|
||||||
pretty_resource = pretty_resource.title()
|
pretty_resource = pretty_resource.title()
|
||||||
if pretty_resource == "Body Bmi":
|
if pretty_resource == 'Body Bmi':
|
||||||
pretty_resource = "BMI"
|
pretty_resource = 'BMI'
|
||||||
self._name = pretty_resource
|
self._name = pretty_resource
|
||||||
unit_type = FITBIT_RESOURCES_LIST[self.resource_type]
|
unit_type = FITBIT_RESOURCES_LIST[self.resource_type]
|
||||||
if unit_type == "":
|
if unit_type == "":
|
||||||
split_resource = self.resource_type.split("/")
|
split_resource = self.resource_type.split('/')
|
||||||
try:
|
try:
|
||||||
measurement_system = FITBIT_MEASUREMENTS[self.client.system]
|
measurement_system = FITBIT_MEASUREMENTS[self.client.system]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
if is_metric:
|
if is_metric:
|
||||||
measurement_system = FITBIT_MEASUREMENTS["metric"]
|
measurement_system = FITBIT_MEASUREMENTS['metric']
|
||||||
else:
|
else:
|
||||||
measurement_system = FITBIT_MEASUREMENTS["en_US"]
|
measurement_system = FITBIT_MEASUREMENTS['en_US']
|
||||||
unit_type = measurement_system[split_resource[-1]]
|
unit_type = measurement_system[split_resource[-1]]
|
||||||
self._unit_of_measurement = unit_type
|
self._unit_of_measurement = unit_type
|
||||||
self._state = 0
|
self._state = 0
|
||||||
@ -384,16 +400,16 @@ class FitbitSensor(Entity):
|
|||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest data from the Fitbit API and update the states."""
|
"""Get the latest data from the Fitbit API and update the states."""
|
||||||
container = self.resource_type.replace("/", "-")
|
container = self.resource_type.replace("/", "-")
|
||||||
response = self.client.time_series(self.resource_type, period="7d")
|
response = self.client.time_series(self.resource_type, period='7d')
|
||||||
self._state = response[container][-1].get("value")
|
self._state = response[container][-1].get('value')
|
||||||
if self.resource_type == "activities/heart":
|
if self.resource_type == 'activities/heart':
|
||||||
self._state = response[container][-1].get("restingHeartRate")
|
self._state = response[container][-1].get('restingHeartRate')
|
||||||
config_contents = {
|
config_contents = {
|
||||||
"access_token": self.client.client.token["access_token"],
|
ATTR_ACCESS_TOKEN: self.client.client.token['access_token'],
|
||||||
"refresh_token": self.client.client.token["refresh_token"],
|
ATTR_REFRESH_TOKEN: self.client.client.token['refresh_token'],
|
||||||
"client_id": self.client.client.client_id,
|
ATTR_CLIENT_ID: self.client.client.client_id,
|
||||||
"client_secret": self.client.client.client_secret,
|
ATTR_CLIENT_SECRET: self.client.client.client_secret,
|
||||||
"last_saved_at": int(time.time())
|
ATTR_LAST_SAVED_AT: int(time.time())
|
||||||
}
|
}
|
||||||
if not config_from_file(self.config_path, config_contents):
|
if not config_from_file(self.config_path, config_contents):
|
||||||
_LOGGER.error("failed to save config file")
|
_LOGGER.error("Failed to save config file")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user