mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 00:37:13 +00:00
Prevent errors on Octoprint sensors and binary_sensors when Octoprint and/or Printer are off (#8343)
* Added platformnotready * Only log the first failure if octoprint/printer isn't up Remove blank line
This commit is contained in:
parent
b67c5df525
commit
652c006cbc
@ -12,13 +12,12 @@ import voluptuous as vol
|
||||
from homeassistant.const import CONF_NAME, CONF_MONITORED_CONDITIONS
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDevice, PLATFORM_SCHEMA)
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['octoprint']
|
||||
|
||||
DOMAIN = "octoprint"
|
||||
DEFAULT_NAME = 'OctoPrint'
|
||||
|
||||
SENSOR_TYPES = {
|
||||
@ -37,7 +36,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the available OctoPrint binary sensors."""
|
||||
octoprint = get_component('octoprint')
|
||||
octoprint_api = hass.data[DOMAIN]["api"]
|
||||
name = config.get(CONF_NAME)
|
||||
monitored_conditions = config.get(
|
||||
CONF_MONITORED_CONDITIONS, SENSOR_TYPES.keys())
|
||||
@ -45,7 +44,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
devices = []
|
||||
for octo_type in monitored_conditions:
|
||||
new_sensor = OctoPrintBinarySensor(
|
||||
octoprint.OCTOPRINT, octo_type, SENSOR_TYPES[octo_type][2],
|
||||
octoprint_api, octo_type, SENSOR_TYPES[octo_type][2],
|
||||
name, SENSOR_TYPES[octo_type][3], SENSOR_TYPES[octo_type][0],
|
||||
SENSOR_TYPES[octo_type][1], 'flags')
|
||||
devices.append(new_sensor)
|
||||
@ -98,6 +97,3 @@ class OctoPrintBinarySensor(BinarySensorDevice):
|
||||
except requests.exceptions.ConnectionError:
|
||||
# Error calling the api, already logged in api.update()
|
||||
return
|
||||
|
||||
if self._state is None:
|
||||
_LOGGER.warning("Unable to locate value for %s", self.sensor_type)
|
||||
|
@ -17,8 +17,6 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DOMAIN = 'octoprint'
|
||||
|
||||
OCTOPRINT = None
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
vol.Required(CONF_API_KEY): cv.string,
|
||||
@ -32,14 +30,15 @@ def setup(hass, config):
|
||||
base_url = 'http://{}/api/'.format(config[DOMAIN][CONF_HOST])
|
||||
api_key = config[DOMAIN][CONF_API_KEY]
|
||||
|
||||
global OCTOPRINT
|
||||
hass.data[DOMAIN] = {"api": None}
|
||||
|
||||
try:
|
||||
OCTOPRINT = OctoPrintAPI(base_url, api_key)
|
||||
OCTOPRINT.get('printer')
|
||||
OCTOPRINT.get('job')
|
||||
octoprint_api = OctoPrintAPI(base_url, api_key)
|
||||
hass.data[DOMAIN]["api"] = octoprint_api
|
||||
octoprint_api.get('printer')
|
||||
octoprint_api.get('job')
|
||||
except requests.exceptions.RequestException as conn_err:
|
||||
_LOGGER.error("Error setting up OctoPrint API: %r", conn_err)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@ -54,6 +53,11 @@ class OctoPrintAPI(object):
|
||||
'X-Api-Key': key}
|
||||
self.printer_last_reading = [{}, None]
|
||||
self.job_last_reading = [{}, None]
|
||||
self.job_available = False
|
||||
self.printer_available = False
|
||||
self.available = False
|
||||
self.printer_error_logged = False
|
||||
self.job_error_logged = False
|
||||
|
||||
def get_tools(self):
|
||||
"""Get the dynamic list of tools that temperature is monitored on."""
|
||||
@ -62,6 +66,7 @@ class OctoPrintAPI(object):
|
||||
|
||||
def get(self, endpoint):
|
||||
"""Send a get request, and return the response as a dict."""
|
||||
# Only query the API at most every 30 seconds
|
||||
now = time.time()
|
||||
if endpoint == "job":
|
||||
last_time = self.job_last_reading[1]
|
||||
@ -73,28 +78,52 @@ class OctoPrintAPI(object):
|
||||
if last_time is not None:
|
||||
if now - last_time < 30.0:
|
||||
return self.printer_last_reading[0]
|
||||
|
||||
url = self.api_url + endpoint
|
||||
try:
|
||||
response = requests.get(
|
||||
url, headers=self.headers, timeout=30)
|
||||
url, headers=self.headers, timeout=9)
|
||||
response.raise_for_status()
|
||||
if endpoint == "job":
|
||||
self.job_last_reading[0] = response.json()
|
||||
self.job_last_reading[1] = time.time()
|
||||
self.job_available = True
|
||||
elif endpoint == "printer":
|
||||
self.printer_last_reading[0] = response.json()
|
||||
self.printer_last_reading[1] = time.time()
|
||||
self.printer_available = True
|
||||
self.available = self.printer_available and self.job_available
|
||||
if self.available:
|
||||
self.job_error_logged = False
|
||||
self.printer_error_logged = False
|
||||
return response.json()
|
||||
except (requests.exceptions.ConnectionError,
|
||||
requests.exceptions.HTTPError) as conn_exc:
|
||||
_LOGGER.error("Failed to update OctoPrint status. Error: %s",
|
||||
conn_exc)
|
||||
requests.exceptions.HTTPError,
|
||||
requests.exceptions.ReadTimeout) as conn_exc:
|
||||
log_string = "Failed to update OctoPrint status. " + \
|
||||
" Error: %s" % (conn_exc)
|
||||
# Only log the first failure
|
||||
if endpoint == "job":
|
||||
log_string = "Endpoint: job " + log_string
|
||||
if not self.job_error_logged:
|
||||
_LOGGER.error(log_string)
|
||||
self.job_error_logged = True
|
||||
self.job_available = False
|
||||
elif endpoint == "printer":
|
||||
log_string = "Endpoint: printer " + log_string
|
||||
if not self.printer_error_logged:
|
||||
_LOGGER.error(log_string)
|
||||
self.printer_error_logged = True
|
||||
self.printer_available = False
|
||||
self.available = False
|
||||
return None
|
||||
|
||||
def update(self, sensor_type, end_point, group, tool=None):
|
||||
"""Return the value for sensor_type from the provided endpoint."""
|
||||
response = self.get(end_point)
|
||||
if response is not None:
|
||||
return get_value_from_json(response, sensor_type, group, tool)
|
||||
return response
|
||||
|
||||
|
||||
# pylint: disable=unused-variable
|
||||
@ -111,3 +140,5 @@ def get_value_from_json(json_dict, sensor_type, group, tool):
|
||||
elif tool is not None:
|
||||
if sensor_type in json_dict[group][tool]:
|
||||
return json_dict[group][tool][sensor_type]
|
||||
|
||||
return None
|
||||
|
@ -13,13 +13,12 @@ from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (
|
||||
TEMP_CELSIUS, CONF_NAME, CONF_MONITORED_CONDITIONS)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.loader import get_component
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['octoprint']
|
||||
|
||||
DOMAIN = "octoprint"
|
||||
DEFAULT_NAME = 'OctoPrint'
|
||||
|
||||
SENSOR_TYPES = {
|
||||
@ -38,7 +37,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
# pylint: disable=unused-argument
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the available OctoPrint sensors."""
|
||||
octoprint = get_component('octoprint')
|
||||
octoprint_api = hass.data[DOMAIN]["api"]
|
||||
name = config.get(CONF_NAME)
|
||||
monitored_conditions = config.get(CONF_MONITORED_CONDITIONS)
|
||||
|
||||
@ -46,16 +45,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
types = ["actual", "target"]
|
||||
for octo_type in monitored_conditions:
|
||||
if octo_type == "Temperatures":
|
||||
for tool in octoprint.OCTOPRINT.get_tools():
|
||||
for tool in octoprint_api.get_tools():
|
||||
for temp_type in types:
|
||||
new_sensor = OctoPrintSensor(
|
||||
octoprint.OCTOPRINT, temp_type, temp_type, name,
|
||||
octoprint_api, temp_type, temp_type, name,
|
||||
SENSOR_TYPES[octo_type][3], SENSOR_TYPES[octo_type][0],
|
||||
SENSOR_TYPES[octo_type][1], tool)
|
||||
devices.append(new_sensor)
|
||||
else:
|
||||
new_sensor = OctoPrintSensor(
|
||||
octoprint.OCTOPRINT, octo_type, SENSOR_TYPES[octo_type][2],
|
||||
octoprint_api, octo_type, SENSOR_TYPES[octo_type][2],
|
||||
name, SENSOR_TYPES[octo_type][3], SENSOR_TYPES[octo_type][0],
|
||||
SENSOR_TYPES[octo_type][1])
|
||||
devices.append(new_sensor)
|
||||
@ -116,7 +115,3 @@ class OctoPrintSensor(Entity):
|
||||
except requests.exceptions.ConnectionError:
|
||||
# Error calling the api, already logged in api.update()
|
||||
return
|
||||
|
||||
if self._state is None and self.sensor_type != "completion":
|
||||
_LOGGER.warning("Unable to locate value for %s", self.sensor_type)
|
||||
return
|
||||
|
Loading…
x
Reference in New Issue
Block a user