diff --git a/custom_components/octoprint/__init__.py b/custom_components/octoprint/__init__.py new file mode 100644 index 0000000..734f609 --- /dev/null +++ b/custom_components/octoprint/__init__.py @@ -0,0 +1,292 @@ +"""Support for monitoring OctoPrint 3D printers.""" +import logging +import time + +from aiohttp.hdrs import CONTENT_TYPE +import requests +import voluptuous as vol + +from homeassistant.components.discovery import SERVICE_OCTOPRINT +from homeassistant.const import ( + CONF_API_KEY, + CONF_BINARY_SENSORS, + CONF_HOST, + CONF_MONITORED_CONDITIONS, + CONF_NAME, + CONF_PATH, + CONF_PORT, + CONF_SENSORS, + CONF_SSL, + CONTENT_TYPE_JSON, + TEMP_CELSIUS, + TIME_SECONDS, + UNIT_PERCENTAGE, +) +from homeassistant.helpers import discovery +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.discovery import load_platform +from homeassistant.util import slugify as util_slugify + +_LOGGER = logging.getLogger(__name__) + +CONF_BED = "bed" +CONF_NUMBER_OF_TOOLS = "number_of_tools" + +DEFAULT_NAME = "OctoPrint" +DOMAIN = "octoprint" + + +def has_all_unique_names(value): + """Validate that printers have an unique name.""" + names = [util_slugify(printer["name"]) for printer in value] + vol.Schema(vol.Unique())(names) + return value + + +def ensure_valid_path(value): + """Validate the path, ensuring it starts and ends with a /.""" + vol.Schema(cv.string)(value) + if value[0] != "/": + value = f"/{value}" + if value[-1] != "/": + value += "/" + return value + + +BINARY_SENSOR_TYPES = { + # API Endpoint, Group, Key, unit + "Printing": ["printer", "state", "printing", None], + "Printing Error": ["printer", "state", "error", None], +} + +BINARY_SENSOR_SCHEMA = vol.Schema( + { + vol.Optional( + CONF_MONITORED_CONDITIONS, default=list(BINARY_SENSOR_TYPES) + ): vol.All(cv.ensure_list, [vol.In(BINARY_SENSOR_TYPES)]), + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + } +) + +SENSOR_TYPES = { + # API Endpoint, Group, Key, unit, icon + "Temperatures": ["printer", "temperature", "*", TEMP_CELSIUS], + "Current State": ["printer", "state", "text", None, "mdi:printer-3d"], + "Job Percentage": [ + "job", + "progress", + "completion", + UNIT_PERCENTAGE, + "mdi:file-percent", + ], + "Time Remaining": [ + "job", + "progress", + "printTimeLeft", + TIME_SECONDS, + "mdi:clock-end", + ], + "Time Elapsed": ["job", "progress", "printTime", TIME_SECONDS, "mdi:clock-start"], + "User":["job", "job", "user", None, "mdi:printer-3d"], + "File":["job", "job", "file", None, "mdi:printer-3d"], +} + +SENSOR_SCHEMA = vol.Schema( + { + vol.Optional(CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)): vol.All( + cv.ensure_list, [vol.In(SENSOR_TYPES)] + ), + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + } +) + +CONFIG_SCHEMA = vol.Schema( + { + DOMAIN: vol.All( + cv.ensure_list, + [ + vol.Schema( + { + vol.Required(CONF_API_KEY): cv.string, + vol.Required(CONF_HOST): cv.string, + vol.Optional(CONF_SSL, default=False): cv.boolean, + vol.Optional(CONF_PORT, default=80): cv.port, + vol.Optional(CONF_PATH, default="/"): ensure_valid_path, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_NUMBER_OF_TOOLS, default=0): cv.positive_int, + vol.Optional(CONF_BED, default=False): cv.boolean, + vol.Optional(CONF_SENSORS, default={}): SENSOR_SCHEMA, + vol.Optional( + CONF_BINARY_SENSORS, default={} + ): BINARY_SENSOR_SCHEMA, + } + ) + ], + has_all_unique_names, + ) + }, + extra=vol.ALLOW_EXTRA, +) + + +def setup(hass, config): + """Set up the OctoPrint component.""" + printers = hass.data[DOMAIN] = {} + success = False + + def device_discovered(service, info): + """Get called when an Octoprint server has been discovered.""" + _LOGGER.debug("Found an Octoprint server: %s", info) + + discovery.listen(hass, SERVICE_OCTOPRINT, device_discovered) + + if DOMAIN not in config: + # Skip the setup if there is no configuration present + return True + + for printer in config[DOMAIN]: + name = printer[CONF_NAME] + ssl = "s" if printer[CONF_SSL] else "" + base_url = "http{}://{}:{}{}api/".format( + ssl, printer[CONF_HOST], printer[CONF_PORT], printer[CONF_PATH] + ) + api_key = printer[CONF_API_KEY] + number_of_tools = printer[CONF_NUMBER_OF_TOOLS] + bed = printer[CONF_BED] + try: + octoprint_api = OctoPrintAPI(base_url, api_key, bed, number_of_tools) + printers[base_url] = 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) + continue + + sensors = printer[CONF_SENSORS][CONF_MONITORED_CONDITIONS] + load_platform( + hass, + "sensor", + DOMAIN, + {"name": name, "base_url": base_url, "sensors": sensors}, + config, + ) + b_sensors = printer[CONF_BINARY_SENSORS][CONF_MONITORED_CONDITIONS] + load_platform( + hass, + "binary_sensor", + DOMAIN, + {"name": name, "base_url": base_url, "sensors": b_sensors}, + config, + ) + success = True + + return success + + +class OctoPrintAPI: + """Simple JSON wrapper for OctoPrint's API.""" + + def __init__(self, api_url, key, bed, number_of_tools): + """Initialize OctoPrint API and set headers needed later.""" + self.api_url = api_url + self.headers = {CONTENT_TYPE: CONTENT_TYPE_JSON, "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 + self.bed = bed + self.number_of_tools = number_of_tools + + def get_tools(self): + """Get the list of tools that temperature is monitored on.""" + tools = [] + if self.number_of_tools > 0: + for tool_number in range(0, self.number_of_tools): + tools.append(f"tool{tool_number!s}") + if self.bed: + tools.append("bed") + if not self.bed and self.number_of_tools == 0: + temps = self.printer_last_reading[0].get("temperature") + if temps is not None: + tools = temps.keys() + return tools + + 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] + if last_time is not None: + if now - last_time < 30.0: + return self.job_last_reading[0] + elif endpoint == "printer": + last_time = self.printer_last_reading[1] + 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=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 Exception as conn_exc: # pylint: disable=broad-except + log_string = "Failed to update OctoPrint status. Error: %s" % conn_exc + # Only log the first failure + if endpoint == "job": + log_string = f"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 = f"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 + + +def get_value_from_json(json_dict, sensor_type, group, tool): + """Return the value for sensor_type from the JSON.""" + if group not in json_dict: + return None + + if sensor_type in json_dict[group]: + if sensor_type == "target" and json_dict[sensor_type] is None: + return 0 + if sensor_type == "file": + return json_dict[group][sensor_type]["name"] + return json_dict[group][sensor_type] + + if tool is not None: + if sensor_type in json_dict[group][tool]: + return json_dict[group][tool][sensor_type] + + return None \ No newline at end of file diff --git a/custom_components/octoprint/binary_sensor.py b/custom_components/octoprint/binary_sensor.py new file mode 100644 index 0000000..a866319 --- /dev/null +++ b/custom_components/octoprint/binary_sensor.py @@ -0,0 +1,83 @@ +"""Support for monitoring OctoPrint binary sensors.""" +import logging + +import requests + +from homeassistant.components.binary_sensor import BinarySensorDevice + +from . import BINARY_SENSOR_TYPES, DOMAIN as COMPONENT_DOMAIN + +_LOGGER = logging.getLogger(__name__) + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Set up the available OctoPrint binary sensors.""" + if discovery_info is None: + return + + name = discovery_info["name"] + base_url = discovery_info["base_url"] + monitored_conditions = discovery_info["sensors"] + octoprint_api = hass.data[COMPONENT_DOMAIN][base_url] + + devices = [] + for octo_type in monitored_conditions: + new_sensor = OctoPrintBinarySensor( + octoprint_api, + octo_type, + BINARY_SENSOR_TYPES[octo_type][2], + name, + BINARY_SENSOR_TYPES[octo_type][3], + BINARY_SENSOR_TYPES[octo_type][0], + BINARY_SENSOR_TYPES[octo_type][1], + "flags", + ) + devices.append(new_sensor) + add_entities(devices, True) + + +class OctoPrintBinarySensor(BinarySensorDevice): + """Representation an OctoPrint binary sensor.""" + + def __init__( + self, api, condition, sensor_type, sensor_name, unit, endpoint, group, tool=None + ): + """Initialize a new OctoPrint sensor.""" + self.sensor_name = sensor_name + if tool is None: + self._name = f"{sensor_name} {condition}" + else: + self._name = f"{sensor_name} {condition}" + self.sensor_type = sensor_type + self.api = api + self._state = False + self._unit_of_measurement = unit + self.api_endpoint = endpoint + self.api_group = group + self.api_tool = tool + _LOGGER.debug("Created OctoPrint binary sensor %r", self) + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def is_on(self): + """Return true if binary sensor is on.""" + return bool(self._state) + + @property + def device_class(self): + """Return the class of this sensor, from DEVICE_CLASSES.""" + return None + + def update(self): + """Update state of sensor.""" + try: + self._state = self.api.update( + self.sensor_type, self.api_endpoint, self.api_group, self.api_tool + ) + except requests.exceptions.ConnectionError: + # Error calling the api, already logged in api.update() + return \ No newline at end of file diff --git a/custom_components/octoprint/manifest.json b/custom_components/octoprint/manifest.json new file mode 100644 index 0000000..28e09cc --- /dev/null +++ b/custom_components/octoprint/manifest.json @@ -0,0 +1,7 @@ +{ + "domain": "octoprint", + "name": "OctoPrint", + "documentation": "https://www.home-assistant.io/integrations/octoprint", + "after_dependencies": ["discovery"], + "codeowners": [] +} diff --git a/custom_components/octoprint/sensor.py b/custom_components/octoprint/sensor.py new file mode 100644 index 0000000..337ed8e --- /dev/null +++ b/custom_components/octoprint/sensor.py @@ -0,0 +1,139 @@ +"""Support for monitoring OctoPrint sensors.""" +import logging + +import requests + +from homeassistant.const import TEMP_CELSIUS, UNIT_PERCENTAGE +from homeassistant.helpers.entity import Entity + +from . import DOMAIN as COMPONENT_DOMAIN, SENSOR_TYPES + +_LOGGER = logging.getLogger(__name__) + +NOTIFICATION_ID = "octoprint_notification" +NOTIFICATION_TITLE = "OctoPrint sensor setup error" + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Set up the available OctoPrint sensors.""" + if discovery_info is None: + return + + name = discovery_info["name"] + base_url = discovery_info["base_url"] + monitored_conditions = discovery_info["sensors"] + octoprint_api = hass.data[COMPONENT_DOMAIN][base_url] + tools = octoprint_api.get_tools() + + if "Temperatures" in monitored_conditions: + if not tools: + hass.components.persistent_notification.create( + "Your printer appears to be offline.
" + "If you do not want to have your printer on
" + " at all times, and you would like to monitor
" + "temperatures, please add
" + "bed and/or number_of_tools to your configuration
" + "and restart.", + title=NOTIFICATION_TITLE, + notification_id=NOTIFICATION_ID, + ) + + devices = [] + types = ["actual", "target"] + for octo_type in monitored_conditions: + if octo_type == "Temperatures": + for tool in tools: + for temp_type in types: + new_sensor = OctoPrintSensor( + 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_api, + octo_type, + SENSOR_TYPES[octo_type][2], + name, + SENSOR_TYPES[octo_type][3], + SENSOR_TYPES[octo_type][0], + SENSOR_TYPES[octo_type][1], + None, + SENSOR_TYPES[octo_type][4], + ) + devices.append(new_sensor) + add_entities(devices, True) + + +class OctoPrintSensor(Entity): + """Representation of an OctoPrint sensor.""" + + def __init__( + self, + api, + condition, + sensor_type, + sensor_name, + unit, + endpoint, + group, + tool=None, + icon=None, + ): + """Initialize a new OctoPrint sensor.""" + self.sensor_name = sensor_name + if tool is None: + self._name = f"{sensor_name} {condition}" + else: + self._name = "{} {} {} {}".format(sensor_name, condition, tool, "temp") + self.sensor_type = sensor_type + self.api = api + self._state = None + self._unit_of_measurement = unit + self.api_endpoint = endpoint + self.api_group = group + self.api_tool = tool + self._icon = icon + _LOGGER.debug("Created OctoPrint sensor %r", self) + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def state(self): + """Return the state of the sensor.""" + sensor_unit = self.unit_of_measurement + if sensor_unit in (TEMP_CELSIUS, UNIT_PERCENTAGE): + # API sometimes returns null and not 0 + if self._state is None: + self._state = 0 + return round(self._state, 2) + return self._state + + @property + def unit_of_measurement(self): + """Return the unit of measurement of this entity, if any.""" + return self._unit_of_measurement + + def update(self): + """Update state of sensor.""" + try: + self._state = self.api.update( + self.sensor_type, self.api_endpoint, self.api_group, self.api_tool + ) + except requests.exceptions.ConnectionError: + # Error calling the api, already logged in api.update() + return + + @property + def icon(self): + """Icon to use in the frontend.""" + return self._icon \ No newline at end of file diff --git a/custom_components/services.yaml b/custom_components/services.yaml new file mode 100644 index 0000000..e69de29 diff --git a/logging.yaml b/logging.yaml index dd4d15a..e86ed04 100644 --- a/logging.yaml +++ b/logging.yaml @@ -18,12 +18,12 @@ logs: homeassistant.helpers.script: warning homeassistant.helpers.entity: warning homeassistant.components.wemo: critical + homeassistant.components.sensor: critical homeassistant.components.cloud.iot: warning homeassistant.components.hue: critical homeassistant.components.http: warning homeassistant.components.camera: warning homeassistant.components.zwave: warning - homeassistant.components.sensor: warning homeassistant.components.image_processing: warning homeassistant.components.homekit: warning custom_components.sensor.life360: warning @@ -39,3 +39,4 @@ logs: homeassistant.components.emulated_hue: warning homeassistant.components.device_tracker: warning homeassistant.components.camera.generic: warning + homeassistant.components.automation.update_zwave_battery_levels: critical diff --git a/lovelace/00_myhome_view.yaml b/lovelace/00_myhome_view.yaml index 9093b42..77942d4 100644 --- a/lovelace/00_myhome_view.yaml +++ b/lovelace/00_myhome_view.yaml @@ -81,6 +81,7 @@ cards: title: 3D Printer show_header_toggle: false entities: + - sensor.octoprint_file - binary_sensor.octoprint_printing - binary_sensor.octoprint_printing_error - sensor.octoprint_actual_bed_temp @@ -92,16 +93,6 @@ cards: - sensor.octoprint_time_elapsed - sensor.octoprint_time_remaining - - type: entities - title: Tile Devices - show_header_toggle: false - entities: - - device_tracker.tile_08beea8370ec23b7 - - device_tracker.tile_43a0d518532978f8 - - device_tracker.tile_49318f5ab14343a5 - - device_tracker.tile_63ca05b6a3619232 - - device_tracker.tile_p_32c03dc7f21001d36d16b47646e4c421 - # - type: glance # show_icon: true # show_name: true @@ -281,15 +272,6 @@ cards: tap_action: action: more-info - - type: entities - title: Light Levels - show_header_toggle: false - entities: - - sensor.downstairs_multi_sensor_luminance - - sensor.front_room_multi_sensor_luminance - - sensor.tv_multi_sensor_luminance - - sensor.upstairs_multi_sensor_luminance - - type: entities title: Xiaomi Motion Sensors show_header_toggle: false @@ -400,39 +382,10 @@ cards: yellow: 4 red: 7 - - type: entities - title: Z-Wave Batteries - show_header_toggle: false - entities: - - input_label.audio_detector - - input_label.back_door_sensor - - input_label.zwave_front_door_sensor - - input_label.basement_door_sensor - - input_label.downstairs_multi_sensor - - input_label.front_room_multi_sensor - - input_label.garage_door_sensor - - input_label.kitchen_motion_sensor - - input_label.single_car_garage_door_tilt_sensor - - input_label.stairs_motion_sensor - - input_label.tv_multi_sensor - - input_label.two_car_garage_door_tilt_sensor - - input_label.upstairs_multi_sensor - - input_label.wallmote - - type: entities title: Motion Counters show_header_toggle: false entities: - - input_label.aeotec_zw120_door_window_sensor_gen5_sensor - - input_label.back_door_sensor_sensor - - input_label.basement_door_sensor_sensor - - input_label.garage_door_sensor_sensor - - input_label.single_car_garage_door_tilt_sensor_sensor - - input_label.two_car_garage_door_tilt_sensor_sensor - - input_label.downstairs_multi_sensor_sensor - - input_label.front_room_multi_sensor_sensor - - input_label.front_room_window_sensor_sensor - - input_label.kitchen_motion_sensor_sensor - input_label.motion_sensor_158d00016c2d0e - input_label.motion_sensor_158d00016db6d2 - input_label.motion_sensor_158d0001a25041 @@ -446,5 +399,3 @@ cards: - input_label.motion_sensor_158d000272bf48 - input_label.motion_sensor_158d000272bfd7 - input_label.garage_motion - - input_label.stairs_motion_sensor_sensor - - input_label.upstairs_multi_sensor_sensor diff --git a/lovelace/01_lights_view.yaml b/lovelace/01_lights_view.yaml index 974f82f..a97d0f8 100644 --- a/lovelace/01_lights_view.yaml +++ b/lovelace/01_lights_view.yaml @@ -27,7 +27,6 @@ cards: - switch.basement_right - switch.kitchen - switch.office_room - - switch.zwave_smart_switch_switch - light.hue_color_lamp_1 - light.hue_color_lamp_2 - light.hue_color_lamp_3 diff --git a/lovelace/02_climate_view.yaml b/lovelace/02_climate_view.yaml index bed3092..3e433dd 100644 --- a/lovelace/02_climate_view.yaml +++ b/lovelace/02_climate_view.yaml @@ -36,31 +36,3 @@ cards: - sensor.dining_room_thermostat_operation_mode - sensor.dining_room_thermostat_target - sensor.dining_room_thermostat_temperature - - # - type: history-graph - # title: "Temperature" - # entities: - # - entity: sensor.dark_sky_apparent_temperature - # name: Outside - # - entity: sensor.dining_room_thermostat_temperature - # name: Inside - - - type: entities - title: Temperature Levels - show_header_toggle: false - entities: - - entity: sensor.audio_detector_temperature - name: Hallway Temperature - - sensor.downstairs_multi_sensor_temperature - - sensor.front_room_multi_sensor_temperature - - sensor.tv_multi_sensor_temperature - - sensor.upstairs_multi_sensor_temperature - - - type: entities - title: Humidity Levels - show_header_toggle: false - entities: - - sensor.downstairs_multi_sensor_relative_humidity - - sensor.front_room_multi_sensor_relative_humidity - - sensor.tv_multi_sensor_relative_humidity - - sensor.upstairs_multi_sensor_relative_humidity diff --git a/lovelace/03_camera_view.yaml b/lovelace/03_camera_view.yaml index 876a5f8..1cd0798 100644 --- a/lovelace/03_camera_view.yaml +++ b/lovelace/03_camera_view.yaml @@ -79,7 +79,6 @@ cards: entities: - switch.frontyard_light - binary_sensor.frontdoor_camera_motion - - binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor - type: picture-glance id: camera_patio_camera @@ -92,7 +91,6 @@ cards: entities: - switch.wemobackyardlightswitch - binary_sensor.patio_camera_motion - - binary_sensor.back_door_sensor_sensor - type: picture-glance id: camera_driveway_camera @@ -105,8 +103,6 @@ cards: entities: - switch.frontyard_light - binary_sensor.driveway_camera_motion - - binary_sensor.single_car_garage_door_tilt_sensor_sensor - - binary_sensor.two_car_garage_door_tilt_sensor_sensor - type: picture-glance id: camera_playarea_camera @@ -119,7 +115,6 @@ cards: entities: - switch.wemobackyardlightswitch - binary_sensor.playarea_camera_motion - - binary_sensor.back_door_sensor_sensor - type: picture-glance id: camera_garage_camera @@ -131,8 +126,6 @@ cards: action: more-info entities: - switch.garage - - binary_sensor.single_car_garage_door_tilt_sensor_sensor - - binary_sensor.two_car_garage_door_tilt_sensor_sensor - type: picture-glance id: camera_3dprinter_camera @@ -145,28 +138,3 @@ cards: entities: - binary_sensor.motion_sensor_158d00016c2d0e - binary_sensor.octoprint_printing - - # - type: picture-glance - # id: camera_kitchen_camera - # title: Kitchen Camera - # entity: camera.kitchen_camera - # camera_image: camera.kitchen_camera - # show_info: true - # tap_action: - # action: more-info - # entities: - # - switch.kitchen - # - binary_sensor.kitchen_camera_motion - # - binary_sensor.back_door_sensor_sensor - - # - type: picture-glance - # id: camera_frontroom_camera - # title: FrontDoor Camera - # entity: camera.frontroom_camera - # camera_image: camera.frontroom_camera - # show_info: true - # tap_action: - # action: more-info - # entities: - # - binary_sensor.frontdoor_camera_motion - # - binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor diff --git a/lovelace/06_tesla_view.yaml b/lovelace/06_tesla_view.yaml index 75257a8..3119e7c 100644 --- a/lovelace/06_tesla_view.yaml +++ b/lovelace/06_tesla_view.yaml @@ -42,7 +42,6 @@ cards: entities: - device_tracker.tesla_model_3_010610_location_tracker - binary_sensor.mahasri_tesla_online_sensor - - device_tracker.mahasri_tesla_location_tracker - binary_sensor.tesla_model_3_parking_brake_sensor - lock.tesla_model_3_door_lock - sensor.tesla_model_3_mileage_sensor diff --git a/lovelace/15_3d_printer.yaml b/lovelace/15_3d_printer.yaml index 100b53b..239f36e 100644 --- a/lovelace/15_3d_printer.yaml +++ b/lovelace/15_3d_printer.yaml @@ -26,6 +26,7 @@ cards: title: Octoprint show_header_toggle: false entities: + - sensor.octoprint_file - binary_sensor.octoprint_printing - sensor.octoprint_current_state - binary_sensor.octoprint_printing_error diff --git a/packages/3dprinting.yaml b/packages/3dprinting.yaml index a7c1806..94f73f4 100644 --- a/packages/3dprinting.yaml +++ b/packages/3dprinting.yaml @@ -12,22 +12,18 @@ homeassistant: input_boolean: twenty_five_percent: name: "25%" - initial: "off" icon: mdi:radiobox-blank fifty_percent: name: "50%" - initial: "off" icon: mdi:brightness-3 seventy_five_percent: name: "75%" - initial: "off" icon: mdi:brightness-2 hundred_percent: name: "100%" - initial: "off" icon: mdi:brightness-1 power_off_when_complete: @@ -88,7 +84,12 @@ sensor: sensors: print_completion: value_template: > - {{ (now().strftime('%s') |int + states('sensor.octoprint_time_remaining')|int ) | timestamp_custom("%A %D %H:%M %p") }} + {% set seconds = states('sensor.octoprint_time_remaining')|int %} + {% if now().strftime('%s')|int | timestamp_custom("%A %D") == (now().strftime('%s') |int + seconds) | timestamp_custom("%A %D") %} + Today at {{- now().strftime('%s')|int | timestamp_custom("%l:%M %p") }} + {% else %} + {{ (now().strftime('%s') |int + seconds) | timestamp_custom("%A %D %l:%M %p") }} + {% endif %} - platform: template sensors: @@ -199,6 +200,7 @@ automation: platform: state entity_id: input_boolean.twenty_five_percent, input_boolean.fifty_percent, input_boolean.seventy_five_percent, input_boolean.hundred_percent to: "on" + from: "off" action: - service: script.notify_me data_template: diff --git a/packages/daily_routines.yaml b/packages/daily_routines.yaml index 59ba024..bcfe71b 100644 --- a/packages/daily_routines.yaml +++ b/packages/daily_routines.yaml @@ -214,8 +214,6 @@ automation: entity_id: light.master_bedroom_2 brightness: 25 color_temp: 366 - - service: switch.turn_on - entity_id: switch.zwave_smart_switch_switch - service: switch.turn_on entity_id: switch.kids_bed_accent - service: switch.turn_on diff --git a/packages/emergency.yaml b/packages/emergency.yaml index cdfe0a7..b99f720 100644 --- a/packages/emergency.yaml +++ b/packages/emergency.yaml @@ -271,7 +271,6 @@ # - switch.office_room # - switch.smart_outlet_1 # - switch.kitchen -# - switch.zwave_smart_switch_switch # - switch.rf_switch_five # - switch.rf_switch_four # - switch.rf_switch_one diff --git a/packages/homeassistant.yaml b/packages/homeassistant.yaml index d85b97c..b874098 100644 --- a/packages/homeassistant.yaml +++ b/packages/homeassistant.yaml @@ -29,10 +29,6 @@ sensor: name: Home Assistant Up Time unit_of_measurement: hours - - platform: whois - domain: !secret namecheap_domain_name - name: My Domain - - platform: rest resource: http://icanhazip.com name: external_ip diff --git a/packages/lights.yaml b/packages/lights.yaml index e011bd7..f0492c2 100644 --- a/packages/lights.yaml +++ b/packages/lights.yaml @@ -36,13 +36,6 @@ homeassistant: emulated_hue_name: Guest Bedroom 2 homebridge_name: Guest Bedroom 2 - switch.zwave_smart_switch_switch: - friendly_name: Office Room Accent Lights - emulated_hue_name: Office Room Accent Lights - homebridge_name: Office Room Accent Lights - assumed_state: false - icon: mdi:lightbulb - switch.kids_bed_accent: friendly_name: Hasika's Bed Accent Lights assumed_state: false diff --git a/packages/motion_timers.yaml b/packages/motion_timers.yaml index 0ad3554..9b9eb6f 100644 --- a/packages/motion_timers.yaml +++ b/packages/motion_timers.yaml @@ -64,8 +64,6 @@ automation: entity_id: switch.office_room - condition: template value_template: "{{ states('sun.sun') == 'below_horizon' }}" - - service: homeassistant.turn_on - entity_id: switch.zwave_smart_switch_switch - alias: Officeroom Timer Elapsed initial_state: true @@ -77,8 +75,6 @@ automation: action: - service: switch.turn_off entity_id: switch.office_room - - service: homeassistant.turn_off - entity_id: switch.zwave_smart_switch_switch # # Front Room: # # Motion Detected - Turn ON the light and extend timer @@ -95,28 +91,9 @@ automation: entity_id: timer.timer_frontroom - condition: template value_template: "{{ states('sun.sun') == 'below_horizon' }}" - - service: homeassistant.turn_on - entity_id: switch.zwave_smart_switch_switch - service: switch.turn_on entity_id: switch.front_room - # Front Room: - # Timer Elapsed - Turn OFF lights - ############################################################################### - - alias: Frontroom Timer Elapsed - initial_state: true - trigger: - - platform: event - event_type: timer.finished - event_data: - entity_id: timer.timer_frontroom - condition: - - condition: template - value_template: "{{ states('input_boolean.working_in_office_room') == 'off' }}" - action: - - service: homeassistant.turn_off - entity_id: switch.zwave_smart_switch_switch - # Kitchen: # Motion Detected - Turn ON the light and extend timer ############################################################################### diff --git a/packages/tesla.yaml b/packages/tesla.yaml index 7c838dd..ce752b4 100644 --- a/packages/tesla.yaml +++ b/packages/tesla.yaml @@ -1,32 +1,5 @@ homeassistant: - customize: - binary_sensor.tesla_model_3_charger_sensor: - friendly_name: Charger - binary_sensor.tesla_model_3_parking_brake_sensor: - friendly_name: Parking Break - climate.tesla_model_3_hvac_climate_system: - friendly_name: Tesla Climate - device_tracker.mahasri_tesla_location_tracker: - friendly_name: Tesla - lock.tesla_model_3_charger_door_lock: - friendly_name: Tesla Door Lock - sensor.tesla_model_3_battery_sensor: - friendly_name: Battery Percentage - icon: mdi:battery - sensor.tesla_model_3_mileage_sensor: - friendly_name: Total Mileage - sensor.tesla_model_3_range_sensor: - friendly_name: Battery Range - sensor.tesla_model_3_temperature_sensor_inside: - friendly_name: Temperature Inside - sensor.tesla_model_3_temperature_sensor_outside: - friendly_name: Temperature Outside - switch.tesla_model_3_charger_switch: - friendly_name: Charger Switch - switch.tesla_model_3_maxrange_switch: - friendly_name: Max Range Switch - switch.tesla_model_3_update_switch: - friendly_name: Update Tesla +# customize: # The scan_interval is now set to 6 hours # Leaving it to the default (which is 5 minutes, or 300 seconds) will drain battery at a rate of @@ -36,7 +9,6 @@ tesla: username: !secret tesla_username password: !secret tesla_password scan_interval: 21600 - ############################################################################### # _ _ _ # /\ | | | | (_) diff --git a/packages/tile.yaml b/packages/tile.yaml deleted file mode 100644 index edbe516..0000000 --- a/packages/tile.yaml +++ /dev/null @@ -1,23 +0,0 @@ -############################################################################### -# @author : Mahasri Kalavala -# @date : 02/05/2020 -# @package : Tile -# @description : Tile Package -############################################################################### -homeassistant: - customize: - device_tracker.tile_08beea8370ec23b7: - friendly_name: Back Pack - device_tracker.tile_43a0d518532978f8: - friendly_name: Passport Bag - device_tracker.tile_49318f5ab14343a5: - friendly_name: Suresh's Laptop Bag - device_tracker.tile_63ca05b6a3619232: - friendly_name: Mallika's Purse - device_tracker.tile_p_32c03dc7f21001d36d16b47646e4c421: - friendly_name: Tile Tracker - -device_tracker: - - platform: tile - username: !secret tile_username - password: !secret tile_password diff --git a/packages/watchdog.yaml b/packages/watchdog.yaml index ed014a0..ec298c9 100644 --- a/packages/watchdog.yaml +++ b/packages/watchdog.yaml @@ -111,7 +111,6 @@ automation: - switch.kitchen - switch.prayer_room - switch.upstairs_fragrance - - switch.zwave_smart_switch_switch - light.hue_color_lamp_1 - light.hue_color_lamp_2 - light.hue_color_lamp_3 diff --git a/packages/xiaomi_aqara.yaml b/packages/xiaomi_aqara.yaml index 60cb708..4b2d4b0 100644 --- a/packages/xiaomi_aqara.yaml +++ b/packages/xiaomi_aqara.yaml @@ -81,11 +81,10 @@ homeassistant: friendly_name: Hasika's Bedroom Cube (Xiaomi) binary_sensor.cube_158d00027cf60d: friendly_name: Srinika's Bedroom Cube (Xiaomi) - -xiaomi_aqara: - discovery_retry: 5 - gateways: - - key: !secret xiaomi_key +# xiaomi_aqara: +# discovery_retry: 5 +# gateways: +# - key: !secret xiaomi_key # - service: xiaomi_aqara.play_ringtone # gw_mac: !secret xiaomi_mac # ringtone_id: 8 diff --git a/packages/xiaomi_magic_cubes.yaml b/packages/xiaomi_magic_cubes.yaml index a4279b1..77ffc79 100644 --- a/packages/xiaomi_magic_cubes.yaml +++ b/packages/xiaomi_magic_cubes.yaml @@ -121,19 +121,6 @@ automation: - service_template: switch.toggle entity_id: switch.front_room - # Flip 180: Toggle Office Room Accent Lights - - alias: Front Room Cube Event flip180 - initial_state: true - trigger: - platform: event - event_type: xiaomi_aqara.cube_action - event_data: - entity_id: binary_sensor.cube_158d00027c0276 - action_type: flip180 - action: - - service: switch.toggle - entity_id: switch.zwave_smart_switch_switch - # Move: Toggle Office Room Light - alias: Front Room Cube Event Move initial_state: true diff --git a/packages/zwave_batteries.yaml b/packages/zwave_batteries.yaml index b3af18e..406a23e 100644 --- a/packages/zwave_batteries.yaml +++ b/packages/zwave_batteries.yaml @@ -21,6 +21,13 @@ input_label: two_car_garage_door_tilt_sensor: upstairs_multi_sensor: wallmote: + ecolink_motion_detector: + ecolink_firefighter: + ecolink_door_window_sensor_2: + aeon_labs_zw100_multisensor_6_2: + aeon_labs_zw100_multisensor_6: + ecolink_door_window_sensor: + ecolink_garage_door_tilt_sensor: suresh_battery: mallika_battery: diff --git a/templates/away_status.yaml b/templates/away_status.yaml index ecc072d..bfd70c7 100644 --- a/templates/away_status.yaml +++ b/templates/away_status.yaml @@ -94,8 +94,7 @@ "switch.kids_bedroom", "switch.kitchen", "switch.office_room", - "switch.wemobackyardlightswitch", - "switch.zwave_smart_switch_switch"] %} + "switch.wemobackyardlightswitch"] %} {% for item in lights_switches -%} {%- if states[item.split('.')[0]][item.split('.')[1]].state == "on" -%} {%- set friendly_name = states[item.split('.')[0]][item.split('.')[1]].attributes.friendly_name -%} diff --git a/templates/goodnight.yaml b/templates/goodnight.yaml index 031461b..0e7f149 100644 --- a/templates/goodnight.yaml +++ b/templates/goodnight.yaml @@ -28,8 +28,7 @@ "switch.kids_bedroom", "switch.kitchen", "switch.office_room", - "switch.wemobackyardlightswitch", - "switch.zwave_smart_switch_switch"] %} + "switch.wemobackyardlightswitch"] %} {%- for item in lights_switches -%} {%- if states[item.split('.')[0]][item.split('.')[1]].state == "on" -%} {%- set friendly_name = states[item.split('.')[0]][item.split('.')[1]].attributes.friendly_name %} diff --git a/zwcfg_0xd89c4f0c.xml b/zwcfg_0xd89c4f0c.xml index 32c691c..72c2ea5 100644 --- a/zwcfg_0xd89c4f0c.xml +++ b/zwcfg_0xd89c4f0c.xml @@ -11,36 +11,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -152,7 +122,7 @@ - + @@ -163,7 +133,7 @@ - + @@ -178,7 +148,7 @@ - + @@ -198,8 +168,8 @@ - - + + @@ -289,8 +259,8 @@ - - + + @@ -575,11 +545,11 @@ - - - + + + - + @@ -749,7 +719,7 @@ - + @@ -758,8 +728,8 @@ - - + + @@ -779,21 +749,6 @@ - - - - - - - - - - - - - - - @@ -1169,27 +1124,6 @@ - - - - - - - - - - - - - - - - - - - - - @@ -1205,7 +1139,7 @@ - + @@ -1299,7 +1233,7 @@ - + @@ -1405,7 +1339,7 @@ - + @@ -1423,8 +1357,8 @@ - - + + @@ -1605,7 +1539,7 @@ - + @@ -1678,72 +1612,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -