Skip to content

Commit

Permalink
Reduce the load on the Emporia server by introducing a cache proxy
Browse files Browse the repository at this point in the history
This is related: magico13/PyEmVue#19

Signed-off-by: Jeremy Compostella <[email protected]>
  • Loading branch information
jeremy-compostella committed Aug 23, 2021
1 parent 2220623 commit 63919ee
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 1 deletion.
74 changes: 74 additions & 0 deletions emporia_proxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
#
# Author: Jeremy Compostella <[email protected]>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.

import os

from datetime import datetime, timedelta
from multiprocessing.connection import Listener

from pyemvue.enums import Scale

from sensor import MyVue2
from tools import debug, init

def main():
prefix = os.path.splitext(__file__)[0]
config = init(prefix + '.log')

vue = MyVue2(config['Emporia'])
cache = {}
listener = Listener((config['EmporiaProxy']['host'],
int(config['EmporiaProxy']['port'])))
debug("... is now ready to run")
while True:
conn = listener.accept()
scale = conn.recv()
data = {}
if scale not in cache or datetime.now() > cache[scale]['expiration_time']:
try:
debug('Reading with scale %s' % scale)
data = vue.read(scale)
except:
debug('Failed to read from Emporia servers')
pass
if data:
cache[scale] = { 'data':data }
if scale == Scale.SECOND.value:
cache[scale]['expiration_time'] = \
datetime.now() + timedelta(seconds=15)
else:
cache[scale]['expiration_time'] = \
datetime.now().replace(second=0, microsecond=0) + \
timedelta(minutes=1)
else:
data = cache[scale]['data']
conn.send(data)
conn.close()

if __name__ == "__main__":
main()
17 changes: 17 additions & 0 deletions emporia_proxy.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[Unit]
Description=Emporia Proxy Service
DefaultDependencies=no
After=network.target

[Service]
Type=simple
User=pi
Group=pi
ExecStart=/home/pi/emporia_proxy.sh
TimeoutStartSec=0
RemainAfterExit=yes
Restart=on-failure
RestartSec=15s

[Install]
WantedBy=default.target
5 changes: 5 additions & 0 deletions emporia_proxy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/sh

cd /home/pi/
python3 emporia_proxy.py

7 changes: 6 additions & 1 deletion home.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[general]
sensor_db=sensor.csv
sensors=Emporia,OpenWeather,Ecobee,WirelessTag,CarData
sensors=EmporiaProxy,OpenWeather,Ecobee,WirelessTag,CarData
producers=SolarPanels
consumers=Pool,Aquanta,Ecobee,Range,Wallbox,Dryer
utility=SRP
Expand All @@ -12,6 +12,11 @@ token_file = keys.json
map=net,water heater,dryer,air handler,EV,range,A/C,solar,pool
class=MyVue2

[EmporiaProxy]
class=EmporiaProxy
host=localhost
port=6001

[SolarPanels]
sensors=solar
description=Solar Panels
Expand Down
14 changes: 14 additions & 0 deletions sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,20 @@ def read(self, scale=Scale.MINUTE.value):
self.usage[self.mapping[i]] = usage[i].usage * factor[scale]
return self.usage

class EmporiaProxy(Sensor):
def __init__(self, config):
self.address = (config['host'], int(config['port']))

def read(self, scale=Scale.MINUTE.value):
try:
proxy = Client(self.address)
proxy.send(scale)
data = proxy.recv()
proxy.close()
return data
except:
return {}

class MyWirelessTag(Sensor):
expirationTime = None

Expand Down

0 comments on commit 63919ee

Please sign in to comment.