Skip to content

Commit

Permalink
Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
aneisch committed May 3, 2023
1 parent 0bd3882 commit 8165938
Show file tree
Hide file tree
Showing 38 changed files with 1,068 additions and 742 deletions.
42 changes: 21 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
[![Build Status](https://github.com/aneisch/home-assistant-config/actions/workflows/check-ha-release-compatibility.yml/badge.svg)](https://github.com/aneisch/home-assistant-config/actions)
[![GitHub last commit](https://img.shields.io/github/last-commit/aneisch/home-assistant-config)](https://github.com/aneisch/home-assistant-config/commits/master)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/y/aneisch/home-assistant-config)](https://github.com/aneisch/home-assistant-config/graphs/commit-activity)
[![HA Version](https://img.shields.io/badge/Running%20Home%20Assistant-2023.4.4%20(Latest)-brightgreen)](https://github.com/home-assistant/home-assistant/releases/latest)
[![HA Version](https://img.shields.io/badge/Running%20Home%20Assistant%20-2023.5.0b8%20(Out%20of%20Date)-Red)](https://github.com/home-assistant/home-assistant/releases/latest)
<br><a href="https://www.buymeacoffee.com/aneisch" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-black.png" width="150px" height="35px" alt="Buy Me A Coffee" style="height: 35px !important;width: 150px !important;" ></a>


Expand Down Expand Up @@ -57,50 +57,50 @@ Also using Grafana/Influx for graphing, both running in Docker containers on NUC
Description | value
-- | --
Lines of ESPHome YAML | 2380
Lines of Home Assistant YAML | 7080
[Integrations](https://www.home-assistant.io/integrations/) in use | 44
Lines of Home Assistant YAML | 7079
[Integrations](https://www.home-assistant.io/integrations/) in use | 45
Zigbee devices in [`zha`](https://www.home-assistant.io/integrations/zha/) | 26
Z-Wave devices in [`zwave_js`](https://www.home-assistant.io/integrations/zwave_js/) | 37

Description | value
-- | --
Entities in the [`person`](https://www.home-assistant.io/components/person) domain | 2
Entities in the [`setter`](https://www.home-assistant.io/components/setter) domain | 1
Entities in the [`group`](https://www.home-assistant.io/components/group) domain | 13
Entities in the [`plant`](https://www.home-assistant.io/components/plant) domain | 1
Entities in the [`timer`](https://www.home-assistant.io/components/timer) domain | 1
Entities in the [`group`](https://www.home-assistant.io/components/group) domain | 13
Entities in the [`counter`](https://www.home-assistant.io/components/counter) domain | 1
Entities in the [`sun`](https://www.home-assistant.io/components/sun) domain | 1
Entities in the [`zone`](https://www.home-assistant.io/components/zone) domain | 6
Entities in the [`counter`](https://www.home-assistant.io/components/counter) domain | 1
Entities in the [`input_text`](https://www.home-assistant.io/components/input_text) domain | 4
Entities in the [`input_datetime`](https://www.home-assistant.io/components/input_datetime) domain | 31
Entities in the [`timer`](https://www.home-assistant.io/components/timer) domain | 1
Entities in the [`input_select`](https://www.home-assistant.io/components/input_select) domain | 19
Entities in the [`input_datetime`](https://www.home-assistant.io/components/input_datetime) domain | 31
Entities in the [`input_number`](https://www.home-assistant.io/components/input_number) domain | 4
Entities in the [`input_text`](https://www.home-assistant.io/components/input_text) domain | 4
Entities in the [`input_boolean`](https://www.home-assistant.io/components/input_boolean) domain | 24
Entities in the [`scene`](https://www.home-assistant.io/components/scene) domain | 2
Entities in the [`sensor`](https://www.home-assistant.io/components/sensor) domain | 335
Entities in the [`automation`](https://www.home-assistant.io/components/automation) domain | 86
Entities in the [`sensor`](https://www.home-assistant.io/components/sensor) domain | 333
Entities in the [`automation`](https://www.home-assistant.io/components/automation) domain | 87
Entities in the [`vacuum`](https://www.home-assistant.io/components/vacuum) domain | 1
Entities in the [`alarm_control_panel`](https://www.home-assistant.io/components/alarm_control_panel) domain | 3
Entities in the [`switch`](https://www.home-assistant.io/components/switch) domain | 149
Entities in the [`camera`](https://www.home-assistant.io/components/camera) domain | 15
Entities in the [`weather`](https://www.home-assistant.io/components/weather) domain | 2
Entities in the [`switch`](https://www.home-assistant.io/components/switch) domain | 150
Entities in the [`light`](https://www.home-assistant.io/components/light) domain | 39
Entities in the [`script`](https://www.home-assistant.io/components/script) domain | 37
Entities in the [`weather`](https://www.home-assistant.io/components/weather) domain | 2
Entities in the [`binary_sensor`](https://www.home-assistant.io/components/binary_sensor) domain | 84
Entities in the [`binary_sensor`](https://www.home-assistant.io/components/binary_sensor) domain | 83
Entities in the [`camera`](https://www.home-assistant.io/components/camera) domain | 15
Entities in the [`media_player`](https://www.home-assistant.io/components/media_player) domain | 12
Entities in the [`fan`](https://www.home-assistant.io/components/fan) domain | 3
Entities in the [`cover`](https://www.home-assistant.io/components/cover) domain | 5
Entities in the [`number`](https://www.home-assistant.io/components/number) domain | 55
Entities in the [`button`](https://www.home-assistant.io/components/button) domain | 64
Entities in the [`device_tracker`](https://www.home-assistant.io/components/device_tracker) domain | 4
Entities in the [`button`](https://www.home-assistant.io/components/button) domain | 84
Entities in the [`cover`](https://www.home-assistant.io/components/cover) domain | 5
Entities in the [`fan`](https://www.home-assistant.io/components/fan) domain | 3
Entities in the [`siren`](https://www.home-assistant.io/components/siren) domain | 1
Entities in the [`calendar`](https://www.home-assistant.io/components/calendar) domain | 1
Entities in the [`climate`](https://www.home-assistant.io/components/climate) domain | 1
Entities in the [`device_tracker`](https://www.home-assistant.io/components/device_tracker) domain | 4
Entities in the [`calendar`](https://www.home-assistant.io/components/calendar) domain | 1
Entities in the [`select`](https://www.home-assistant.io/components/select) domain | 20
Entities in the [`lock`](https://www.home-assistant.io/components/lock) domain | 2
Entities in the [`update`](https://www.home-assistant.io/components/update) domain | 25
Entities in the [`vacuum`](https://www.home-assistant.io/components/vacuum) domain | 1
**Total state objects** | **1054**
**Total state objects** | **1073**
## The HACS integrations/plugins that I use:
**Appdaemon**:<br>
[aneisch/follow_me_appdaemon](https://github.com/aneisch/follow_me_appdaemon)<br>
Expand Down
44 changes: 27 additions & 17 deletions automations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@
trigger:
platform: webhook
webhook_id: !secret panic_script_webhook
local_only: false
action:
- service: media_player.volume_set
data:
Expand All @@ -299,6 +300,7 @@
trigger:
- platform: webhook
webhook_id: !secret cellular_modem_power_toggle_webhook
local_only: false
- platform: state
entity_id: sensor.cellular_modem_power
from: "on"
Expand All @@ -312,6 +314,7 @@
trigger:
platform: webhook
webhook_id: !secret github_recipes_webhook
local_only: false
action:
- service: shell_command.pull_recipes

Expand Down Expand Up @@ -699,23 +702,26 @@
- platform: webhook
webhook_id: !secret signal_bvst_contact_webhook_id
id: contact
- platform: webhook
webhook_id: !secret signal_bvst_intake_webhook_id
id: intake_forms
local_only: false
# - platform: webhook
# webhook_id: !secret signal_bvst_intake_webhook_id
# id: intake_forms
# local_only: false
- platform: webhook
webhook_id: !secret signal_bvst_insurance_webhook_id
id: insurance
local_only: false
action:
- if: "{{ trigger.id == 'contact' }}"
then:
- service: notify.signal_bvst
data:
message: "{{ trigger.json['message'] }}"
- if: "{{ trigger.id == 'intake_forms' }}"
then:
- service: notify.signal_self
data:
message: "Intake forms sent to {{ trigger.json['email'] }}"
# - if: "{{ trigger.id == 'intake_forms' }}"
# then:
# - service: notify.signal_self
# data:
# message: "Intake forms sent to {{ trigger.json['email'] }}"
- if: "{{ trigger.id == 'insurance' }}"
then:
- service: notify.signal_bvst_ins
Expand Down Expand Up @@ -889,16 +895,20 @@
- service: lock.unlock
entity_id: lock.front_door

- alias: "Attic Pi Health"
id: "attic_pi_health"
- alias: "Turn off AC Fan"
# In case I manually turned on the fan to clear stale air
id: "turn_off_ac_fan"
trigger:
- platform: state
entity_id: binary_sensor.attic_pi
from: on
to: off
entity_id: sensor.thermostat_state
to: "Idle Fan"
for:
minutes: 5
minutes: 30
action:
service: script.notify_wrapper
data:
message: "Attic Pi Offline"
- service: script.notify_wrapper
data:
message: "AC fan on idle for 30 minutes, setting back to auto"
- service: climate.set_fan_mode
entity_id: climate.thermostat
data:
fan_mode: auto
19 changes: 0 additions & 19 deletions binary_sensor.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,3 @@
# Doors moved to ESPHome

# - platform: digital_ocean
# droplets:
# - !secret DO_host

- platform: workday
country: US
workdays: [mon, tue, wed, thu, fri]
excludes: [sat, sun]
# add_holidays:
# - "2020-02-24"
# - "2020-04-25"

- platform: ping
name: Thermostat Online
host: 10.0.0.29
Expand All @@ -22,11 +8,6 @@
host: 10.0.1.27
count: 2

- platform: ping
name: Attic Pi
host: 10.0.1.3
count: 2

# - platform: ping
# name: Kurt Tunnel
# host: 192.168.88.1
Expand Down
2 changes: 1 addition & 1 deletion custom_components/aarlo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from .pyaarlo.constant import DEFAULT_AUTH_HOST, DEFAULT_HOST, SIREN_STATE_KEY

__version__ = "0.7.4b9"
__version__ = "0.7.4b11"

_LOGGER = logging.getLogger(__name__)

Expand Down
2 changes: 1 addition & 1 deletion custom_components/aarlo/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"dependencies": ["ffmpeg"],
"codeowners": ["@twrecked"],
"requirements": ["unidecode","cloudscraper>=1.2.64", "paho-mqtt"],
"version": "0.7.4b9",
"version": "0.7.4b11",
"iot_class": "cloud_push"
}
6 changes: 3 additions & 3 deletions custom_components/aarlo/pyaarlo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

_LOGGER = logging.getLogger("pyaarlo")

__version__ = "0.7.4b9"
__version__ = "0.7.4b11"


class PyArlo(object):
Expand Down Expand Up @@ -348,9 +348,9 @@ def _refresh_locations(self):
self.warning("No locations returned from " + url)
else:
for user_location in location_data.get("userLocations", []):
self._locations.append(ArloLocation(self, user_location))
self._locations.append(ArloLocation(self, user_location, True))
for shared_location in location_data.get("sharedLocations", []):
self._locations.append(ArloLocation(self, shared_location))
self._locations.append(ArloLocation(self, shared_location, False))

self.vdebug("locations={}".format(pprint.pformat(self._locations)))

Expand Down
53 changes: 29 additions & 24 deletions custom_components/aarlo/pyaarlo/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def _dump_activities(self, msg):
)

# Media library has updated, reload today's events.
def _update_media(self):
def _update_from_media_library(self):
self._arlo.debug("reloading cache for " + self._name)
count, videos = self._arlo.ml.videos_for(self)
if videos:
Expand All @@ -158,7 +158,7 @@ def _update_media(self):
self._cache_count = count
self._cached_videos = videos

# signal video up!
# Tell anyone listening about the new capture and how it affects things.
self._save_and_do_callbacks(CAPTURED_TODAY_KEY, captured_today)
if last_captured is not None:
self._save_and_do_callbacks(LAST_CAPTURE_KEY, last_captured)
Expand All @@ -167,18 +167,24 @@ def _update_media(self):
# new snapshot?
snapshot = self._arlo.ml.snapshot_for(self)
if snapshot is not None:
self._arlo.debug("snapshot updated for media " + self.name)
self._save(SNAPSHOT_KEY, snapshot.image_url)
self._arlo.bg.run_low(self._update_snapshot)
if self._load(SNAPSHOT_KEY, None) != snapshot.image_url:
self._arlo.debug("snapshot updated for media " + self.name)
self._save(SNAPSHOT_KEY, snapshot.image_url)
self._arlo.bg.run_low(self._update_image_from_snapshot)
else:
self._arlo.debug("snapshot already done " + self.name)

# new image?
# New image? Then fetch it an update image details.
if last_image is not None:
self._arlo.debug("image updated for media " + self.name)
self._save(LAST_IMAGE_KEY, last_image)
self._arlo.bg.run_low(self._update_image)
if self._load(LAST_IMAGE_KEY, None) != last_image:
self._arlo.debug("image updated for media " + self.name)
self._save(LAST_IMAGE_KEY, last_image)
self._arlo.bg.run_low(self._update_image_from_capture)
else:
self._arlo.debug("image already done " + self.name)

# Update last captured image.
def _update_image(self):
def _update_image_from_capture(self):
# Get image and date, if fails ignore
img, date = http_get_img(self._load(LAST_IMAGE_KEY, None))
if img is None:
Expand All @@ -191,14 +197,13 @@ def _update_image(self):
date = date.strftime(self._arlo.cfg.last_format)
self._arlo.debug(f"updating image for {self.name} ({date})")
self._save_and_do_callbacks(LAST_IMAGE_SRC_KEY, "capture/" + date)
self._save_and_do_callbacks(LAST_CAPTURE_KEY, date)
self._save_and_do_callbacks(LAST_IMAGE_DATA_KEY, img)
else:
date = date.strftime(self._arlo.cfg.last_format)
self._arlo.vdebug(f"ignoring image for {self.name} ({date})")

# Update the last snapshot
def _update_snapshot(self, ignore_date=False):
def _update_image_from_snapshot(self, ignore_date=False):
# Get image and date, if fails ignore.
img, date = http_get_img(self._load(SNAPSHOT_KEY, None), ignore_date)
if img is None:
Expand Down Expand Up @@ -256,7 +261,7 @@ def _queue_media_updates(self):
for retry in self._arlo.cfg.media_retry:
self._arlo.debug("queueing update in {}".format(retry))
self._arlo.bg.run_in(
self._arlo.ml.queue_update, retry, cb=self._update_media
self._arlo.ml.queue_update, retry, cb=self._update_from_media_library
)

def _mark_as_idle(self):
Expand Down Expand Up @@ -357,20 +362,20 @@ def _event_handler(self, resource, event):
if LAST_IMAGE_KEY in event:
if not self.is_taking_snapshot:
self._arlo.debug("{} -> thumbnail changed".format(self.name))
self._arlo.bg.run_low(self._update_image)
self._arlo.bg.run_low(self._update_image_from_capture)
else:
self._arlo.debug(
"{} -> snapshot(thumbnail) ready".format(self.name)
)
self._save(SNAPSHOT_KEY, event.get(LAST_IMAGE_KEY, ""))
self._arlo.bg.run_low(self._update_snapshot, ignore_date=True)
self._arlo.bg.run_low(self._update_image_from_snapshot, ignore_date=True)

# Recording has stopped so a new video is available. Queue an
# media update, this could later trigger a snapshot or image
# update.
if event.get(RECORDING_STOPPED_KEY, False):
self._arlo.debug("{} -> recording stopped".format(self.name))
self._arlo.ml.queue_update(self._update_media)
self._arlo.ml.queue_update(self._update_from_media_library)

# Examine the URL passed; snapshots contain `/snapshots/` and
# recordings contain `recordings`. For snapshot, save URL and queue
Expand All @@ -380,7 +385,7 @@ def _event_handler(self, resource, event):
if "/snapshots/" in value:
self._arlo.debug("{} -> snapshot1 ready".format(self.name))
self._save(SNAPSHOT_KEY, value)
self._arlo.bg.run_low(self._update_snapshot)
self._arlo.bg.run_low(self._update_image_from_snapshot)
if "/recordings/" in value:
self._arlo.debug("{} -> new recording ready".format(self.name))

Expand Down Expand Up @@ -429,15 +434,15 @@ def _event_handler(self, resource, event):
if value is not None:
self._arlo.debug("{} -> snapshot2 ready".format(self.name))
self._save(SNAPSHOT_KEY, value)
self._arlo.bg.run_low(self._update_snapshot)
self._arlo.bg.run_low(self._update_image_from_snapshot)

# Non subscription...
if event.get("action", "") == "lastImageSnapshotAvailable":
value = event.get("properties", {}).get("presignedLastImageUrl", None)
if value is not None:
self._arlo.debug("{} -> snapshot3 ready".format(self.name))
self._save(SNAPSHOT_KEY, value)
self._arlo.bg.run_low(self._update_snapshot)
self._arlo.bg.run_low(self._update_image_from_snapshot)

# Ambient sensors update, decode and push changes.
if resource.endswith("/ambientSensors/history"):
Expand Down Expand Up @@ -674,10 +679,10 @@ def update_media(self, wait=None):
wait = self._arlo.cfg.synchronous_mode
if wait:
self._arlo.debug("doing media update")
self._update_media()
self._update_from_media_library()
else:
self._arlo.debug("queueing media update")
self._arlo.bg.run_low(self._update_media)
self._arlo.bg.run_low(self._update_from_media_library)

def update_last_image(self, wait=None):
"""Requests last thumbnail from the backend server.
Expand All @@ -691,10 +696,10 @@ def update_last_image(self, wait=None):
wait = self._arlo.cfg.synchronous_mode
if wait:
self._arlo.debug("doing image update")
self._update_image()
self._update_image_from_capture()
else:
self._arlo.debug("queueing image update")
self._arlo.bg.run_low(self._update_image)
self._arlo.bg.run_low(self._update_image_from_capture)

def update_ambient_sensors(self):
"""Requests the latest temperature, humidity and air quality settings.
Expand Down Expand Up @@ -782,7 +787,7 @@ def request_snapshot(self):
for check in self._arlo.cfg.snapshot_checks:
self._arlo.debug("queueing snapshot check in {}".format(check))
self._arlo.bg.run_in(
self._arlo.ml.queue_update, check, cb=self._update_media
self._arlo.ml.queue_update, check, cb=self._update_from_media_library
)

self._arlo.vdebug("handle dodgy cameras")
Expand Down
Loading

0 comments on commit 8165938

Please sign in to comment.