-
Notifications
You must be signed in to change notification settings - Fork 0
/
serv.py
132 lines (132 loc) · 4.93 KB
/
serv.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
from pyhtcc import PyHTCC
from flask import Flask, render_template, request, jsonify
from dotenv import load_dotenv
import os
import time
import json
app = Flask(__name__, static_folder='static', static_url_path='/static')
load_dotenv()
username = os.getenv('PYHTCC_EMAIL')
password = os.getenv('PYHTCC_PASS')
port = int(os.getenv('PORT', 5000))
print("Username:", username, " Password set:", bool(password))
p = PyHTCC(username, password)
zones_info = p.get_zones_info()
print("Zones info:", zones_info)
if zones_info:
zone = zones_info[0]
print(f"Connected to zone: {zone['Name']}")
else:
print("No zones found")
exit(1)
def read_thermostat(zone_name):
zones_info = p.get_zones_info()
zone_info = next((z for z in zones_info if z['Name'] == zone_name), None)
if zone_info:
temp = zone_info['DispTemp']
running = zone_info['IsFanRunning']
system_mode = zone_info['latestData']['uiData']['SystemSwitchPosition']
mode = 'heat' if system_mode == 1 else 'cool' if system_mode == 3 else 'off'
heat_setpoint = zone_info['latestData']['uiData']['HeatSetpoint']
cool_setpoint = zone_info['latestData']['uiData']['CoolSetpoint']
setpoint = heat_setpoint if system_mode == 1 else cool_setpoint if system_mode == 3 else 'off'
return temp, setpoint, mode, running
return None, None, None, None
thermostat = {
'temp': None,
'setpoint': None,
'mode': None,
'running': None,
}
update_status = {
'last_update': None,
'update_status': None
}
@app.route('/read_thermostat')
def read_thermostat_route():
global thermostat, update_status
temp, setpoint, mode, running = read_thermostat(zone['Name'])
thermostat.update({
'temp': temp,
'setpoint': setpoint,
'mode': mode,
'running': running
})
if update_status['last_update']:
time_since_update = time.time() - update_status['last_update']['timestamp']
if time_since_update < 300:
if (update_status['last_update']['setpoint'] == setpoint and
update_status['last_update']['mode'] == mode):
update_status['update_status'] = 'confirmed'
if update_status.get('last_update_confirmation') != update_status['last_update']['timestamp']:
print(f"Update confirmed at {time.strftime('%H:%M:%S', time.localtime(update_status['last_update']['timestamp']))}: mode={mode}, setpoint={setpoint}")
update_status['last_update_confirmation'] = update_status['last_update']['timestamp']
else:
update_status['update_status'] = 'pending'
else:
update_status['last_update'] = None
update_status['update_status'] = None
return jsonify(thermostat)
def set_thermostat(zone_name, setpoint, mode):
try:
zone = p.get_zone_by_name(zone_name)
if mode == 'cool':
zone.set_permanent_cool_setpoint(setpoint)
elif mode == 'heat':
zone.set_permanent_heat_setpoint(setpoint)
except Exception as e:
print(f"Error: {e}")
@app.route('/set_thermostat', methods=['POST'])
def set_thermostat_route():
global thermostat
new_setpoint = request.form['setpoint']
new_mode = request.form['mode']
current_setpoint = thermostat['setpoint']
current_mode = thermostat['mode']
if (new_mode != current_mode or new_setpoint != current_setpoint):
try:
set_thermostat(zone['Name'], new_setpoint, new_mode)
update_status['last_update'] = {
'setpoint': new_setpoint,
'mode': new_mode,
'timestamp': time.time()
}
update_status['update_status'] = 'pending'
print(f"Update sent mode={new_mode}, setpoint={new_setpoint}")
return jsonify(success=True, updated=True)
except Exception as e:
print(f"Error: {e}")
return jsonify(success=False, error=str(e), updated=False), 500
else:
return jsonify(success=True, updated=False)
app_state = {}
@app.route('/app_state', methods=['GET', 'POST'])
def handle_app_state():
global app_state
if request.method == 'GET':
return jsonify(app_state)
elif request.method == 'POST':
new_app_state = request.json
app_state.update(new_app_state)
save_app_state()
return jsonify(success=True)
def save_app_state():
with open('app-state.json', 'w') as f:
json.dump(app_state, f)
def load_app_state():
global app_state
try:
with open('app-state.json', 'r') as f:
app_state = json.load(f)
except FileNotFoundError:
try:
with open('default-app-state.json', 'r') as f:
app_state = json.load(f)
except FileNotFoundError:
app_state = {}
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
load_app_state()
app.run(debug=False, port=port)