-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
156 lines (129 loc) · 5.7 KB
/
server.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
from ast import While
from dataclasses import dataclass
from email import header
from paho.mqtt import client as mqtt_client
from datetime import datetime
from datetime import timedelta
from dotenv import load_dotenv, find_dotenv
import requests
import json
import hashlib
import random
import time
import os
print ("Starting program")
#load .env variables
load_dotenv()
USERNAME = os.getenv('USERNAME', "")
USERPASSWORD = os.getenv('USERPASSWORD',"")
MQTT_HOST_ADDRESS = os.getenv('MQTT_HOST_ADDRESS',"")
MQTT_USERNAME = os.getenv('MQTT_USERNAME',"")
MQTT_PASSWORD = os.getenv('MQTT_PASSWORD',"")
MQTT_PORT = int(os.getenv('MQTT_PORT', 1883))
API_FREQUENCY_CHECK = int(os.getenv('API_FREQUENCY_CHECK',900))
print ("Using MQTT Server: " + MQTT_HOST_ADDRESS)
print ("On port: " + str(MQTT_PORT))
print ("Checking every " + str(API_FREQUENCY_CHECK) + " seconds for new data from Hoymiles")
print ("Checking now...")
class Energy:
def __init__(self, username, password):
self.username = username
self.password = hashlib.md5(bytes(password,"utf-8")).hexdigest()
self.today = ""
self.this_month = ""
self.this_year = ""
self.lifetime_energy = ""
self.current_power = ""
self.last_update = ""
self.cookie = self.authentication_cookie()
self.update()
def authentication_cookie(self):
response_auth = json.loads(requests.post("https://global.hoymiles.com/platform/api/gateway/iam/auth_login", data={'user_name': self.username, 'password': self.password}).text)
token = response_auth["data"]["token"]
headers = {"hm_token": token + "; Path=/; Expires=Sat, 18 Mar 2023 19:00:41 GMT;"}
self.cookie = headers
print ("Authentication token received!")
return headers
def get_sid(self):
response = json.loads(requests.post("https://global.hoymiles.com/platform/api/gateway/pvm/station_select_by_page", cookies=self.cookie).text)
if response["message"] == "success":
site_list = response["data"]["list"]
site_dict = site_list[0]
site_id = str(site_dict["id"])
return site_id
elif response["message"] == "token verify error.":
print ("Authentication token not valid. Requesting new token...")
self.cookie = self.authentication_cookie()
return False
else:
print ("No valid return from API")
return False
def update(self):
sid = self.get_sid()
if sid == False:
return False
data = { "sid": sid }
response = json.loads(requests.post("https://global.hoymiles.com/platform/api/gateway/pvm-data/data_count_station_real_data", cookies=self.cookie, json=data).text)
if response["message"] == "success":
self.today = str(response["data"]["today_eq"])
self.this_month = str(response["data"]["month_eq"])
self.this_year = str(response["data"]["year_eq"])
self.lifetime_energy = str(response["data"]["total_eq"])
self.current_power = str(response["data"]["real_power"])
self.last_update = str(response["data"]["last_data_time"])
elif response["message"] == "token verify error.":
print ("Authentication token not valid. Requesting new token...")
self.cookie = self.authentication_cookie()
return False
else:
print ("No valid return from API")
return False
def connect_mqtt(broker, port, mqtt_username, mqtt_password):
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect to mqtt, return code %d\n", rc)
return False
client_id = f'hoymiles-mqtt-{random.randint(0, 1000)}'
client = mqtt_client.Client(client_id)
client.username_pw_set(mqtt_username, mqtt_password)
client.on_connect = on_connect
client.connect(broker, port)
return client
def publish(client, topic, message):
result = client.publish(topic, message, retain=True)
status = result[0]
if status == 0:
print(f"Sent `{message}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
client = connect_mqtt(MQTT_HOST_ADDRESS, MQTT_PORT, MQTT_USERNAME, MQTT_PASSWORD)
client.loop_start()
hoymiles = Energy(USERNAME,USERPASSWORD)
lastUpdate = ""
energytoday = 0
while 1<2:
current_time = datetime.now().strftime("%D %H:%M:%S")
#if lastUpdate != hoymiles.last_update or energytoday != hoymiles.today:
if energytoday != hoymiles.today:
print ("Update at: ", current_time)
publish(client, "hoymiles/energy_today", hoymiles.today)
publish(client, "hoymiles/energy_this_month", hoymiles.this_month)
publish(client, "hoymiles/energy_this_year", hoymiles.this_year)
publish(client, "hoymiles/energy_lifetime_energy", hoymiles.lifetime_energy)
publish(client, "hoymiles/current_power", hoymiles.current_power)
publish(client, "hoymiles/last_update", hoymiles.last_update)
lastUpdate = hoymiles.last_update
energytoday = hoymiles.today
else:
print ("No new information at: ", current_time)
#thisUpdateTime = datetime.now()
#followingUpdateTime = datetime.now() + timedelta(seconds=API_FREQUENCY_CHECK)
#if thisUpdateTime.day != followingUpdateTime.day:
# print ("Following update will be after midnight. Setting day-total to 0.")
# publish(client, "hoymiles/energy_today", "0")
time.sleep(API_FREQUENCY_CHECK)
result = hoymiles.update()
if result == False:
print ("Error happened. Data not updated!")