Skip to content

Instantly share code, notes, and snippets.

@blidegn
Last active August 2, 2020 07:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blidegn/641e8a1a3922b1dfdee959164b2f665e to your computer and use it in GitHub Desktop.
Save blidegn/641e8a1a3922b1dfdee959164b2f665e to your computer and use it in GitHub Desktop.
import hassapi as hass
import datetime
import requests
import json
import re
#
# Ecowater App used for fetching data from Ecowater website
#
# Args:
# dailyruntime (fetching data at the same time every day)
# hourlyruntime (fetching data at the same time every hour)
# runevery (fetching data every number of minutes)
# ecowater_website
# ecowater_user
# ecowater_password
# ecowater_dsn
class GetEcowaterData(hass.Hass):
def initialize(self):
# Schedule a daily callback if dailyruntime has been defined
if 'dailyruntime' in self.args:
# Create a time object
dailyruntime = datetime.time(self.args["dailyruntime"][0], self.args["dailyruntime"][1], self.args["dailyruntime"][2])
self.run_daily(self.run_callback, dailyruntime)
# Schedule hourly callback if hourlyruntime has been defined
if 'hourlyruntime' in self.args:
# Create a time object
hourlyruntime = datetime.time(self.args["hourlyruntime"][0], self.args["hourlyruntime"][1], self.args["hourlyruntime"][2])
self.run_hourly(self.run_callback, hourlyruntime)
# Schedule callback every number of minutes if runevery has been defined
if 'runevery' in self.args:
# Create a time object
startruntime = datetime.datetime.now() + datetime.timedelta(seconds=3)
self.run_every(self.run_callback, startruntime, self.args["runevery"] * 60)
def run_callback(self, kwargs):
self.log("Ecowater Get Data")
ecowateruser = self.args["ecowater_user"]
# Regex to match the hidden input on the initial log in page
request_validation_re = re.compile(r'<input name="__RequestVerificationToken" type="hidden" value="(.*?)" />')
# The serial number of your ecowater device
dsn = { "dsn": self.args["ecowater_dsn"] }
# The initial form data
payload = {
"Email" : self.args["ecowater_user"],
"Password" : self.args["ecowater_password"],
"Remember" : 'false'
}
# The headers needed for the JSON request
headers = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language' : 'en-US,en;q=0.5',
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0'
}
with requests.Session() as s:
# Initial GET request
g = s.get(self.args["ecowater_website"])
# Grab the token from the hidden input
tokens = request_validation_re.findall(g.text)
# Add the token to the form data payload
payload['__RequestVerificationToken'] = tokens[0]
# Log in to the site
login = s.post(self.args["ecowater_website"], data=payload)
# Add the correct Referer header
headers['Referer'] = login.url + '/' + dsn['dsn']
# Query the JSON endpoint for the data that we actually want
data = s.post('https://www.wifi.ecowater.com/Dashboard/UpdateFrequentData', data=dsn, headers=headers)
# Load the data in to json
jsonvar = json.loads(data.text)
waterunit = jsonvar['water_units']
waterflowunit= waterunit[0]+'PM'
waterunit = waterunit.lower()
# Delete the elements that we don't want
del jsonvar['water_units']
del jsonvar['time']
del jsonvar['recharge']
# Format each piece of json data update sensor data
for d in jsonvar:
if (d == 'online') or (d == 'rechargeEnabled'):
sensor = 'binary_sensor.ecowater_'+d
if jsonvar[d]:
jsonvar[d]='on'
else:
jsonvar[d]='off'
else:
sensor = 'sensor.ecowater_'+d
choices = {'online': {"friendly_name": "Online"},
'salt_level': {"friendly_name": "Salt Level"},
'salt_level_percent': {"friendly_name": "Salt Level Percentage", "unit_of_measurement": "%"},
'out_of_salt': {"friendly_name": "Out of salt", "icon": "mdi:clock"},
'out_of_salt_days': {"friendly_name": "Out of salt days","unit_of_measurement": "days"},
'water_today': {"friendly_name": "Water Today", "unit_of_measurement": waterunit, "icon": "mdi:water"},
'water_avg': {"friendly_name": "Water Average", "unit_of_measurement": waterunit, "icon": "mdi:water"},
'water_avail': {"friendly_name": "Water Available","unit_of_measurement": waterunit, "icon": "mdi:water"},
'water_flow': {"friendly_name": "Water Flow","unit_of_measurement": waterflowunit, "icon": "mdi:water-pump"},
'rechargeEnabled': {"friendly_name": "Recharge Enabled", "icon": "mdi:recycle"}}
sensorattributes = choices.get(d, {"friendly_name": d})
# Set sensor state
self.set_state(sensor, state=jsonvar[d], attributes = sensorattributes)
# Output sensor data to log Appdaemon log file
self.log(sensor + ': ' + str(jsonvar[d]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment