Skip to content

Instantly share code, notes, and snippets.

@bokub
Last active June 6, 2017 17:07
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 bokub/f4b8c71c11886d146ae791413485e87d to your computer and use it in GitHub Desktop.
Save bokub/f4b8c71c11886d146ae791413485e87d to your computer and use it in GitHub Desktop.
Weekly report script for home-assistant
import datetime
import json
import optparse
import requests
""" EDIT THE FOLLOWING LINES: """
api_password = 'my_password'
server_url = 'http://localhost:8123'
ifttt_event = 'weekly_report'
""" ========================= """
days = 7
offset = 0
entity_id = None
report_name = None
def get_data():
"""
Get data using the homeassistant REST API
:return:
"""
global api_password
global server_url
global entity_id
global days
now = datetime.datetime.now()
start = now - datetime.timedelta(days=days + 1)
now_str = now.strftime('%Y-%m-%dT%H:%M:%S')
start_str = start.strftime('%Y-%m-%dT%H:%M:%S')
url = server_url + '/api/history/period/' + start_str
url += '?filter_entity_id=' + entity_id + '&end_time=' + now_str
headers = {'x-ha-access': api_password}
r = requests.get(url, headers=headers)
try:
data = r.json()
return data
except json.decoder.JSONDecodeError:
print("Cannot decode response: " + r.text)
return None
def parse_data(data):
"""
Transform raw data into a day:time map
:param data:
:return:
"""
result = {}
for state in data[0]:
dt = state['last_updated'][:10]
result[dt] = state['attributes']['value']
return result
def format_email(result):
"""
Create an e-mail based on the data
:param result:
:return:
"""
global days
global report_name
global offset
now = datetime.datetime.now()
text = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" ' \
'"http://www.w3.org/TR/REC-html40/loose.dtd"><html><head></head>' \
'<body><p style="font-family: sans-serif;">Hi,<br>Here is the <b>' \
+ report_name + '</b>:</p><br><table>'
for day in range(1, days + 1):
report_date = now - datetime.timedelta(days=days + 1) + \
datetime.timedelta(days=day)
value_date = report_date + datetime.timedelta(days=offset)
key = value_date.strftime('%Y-%m-%d')
nice = report_date.strftime('%A %d %B')
text += '<tr><td style="font-family: sans-serif; padding: 3px 15px;">'
text += nice
text += '</td><td style="font-family: sans-serif; padding: 3px 15px;">'
if key in result:
text += result[key]
else:
text += 'no data'
text += '</td></tr>'
text += '</tbody></table><br><p style="font-family: sans-serif;">' \
'Have a good week!</p></body></html>'
return text
def generate_payload(body):
"""
Generate a payload to send to IFTTT
:param body:
:return:
"""
global report_name
global ifttt_event
return json.dumps({
'event': ifttt_event,
'value1': report_name,
'value2': body
})
def send_event(payload):
"""
Send a payload to IFTTT using the homeassistant REST API
:param payload:
:return:
"""
global ifttt_api_key
global ifttt_event
url = server_url + '/api/services/ifttt/trigger'
headers = {'content-type': 'application/json', 'x-ha-access': api_password}
r = requests.post(url, data=payload, headers=headers)
print(r.status_code, r.text)
return
def parse_options():
"""
Get entity id and report name using the options
:return:
"""
global entity_id
global report_name
global offset
parser = optparse.OptionParser()
parser.add_option('-e', '--entity')
parser.add_option('-n', '--name')
parser.add_option('-o', '--offset')
options, args = parser.parse_args()
report_name = options.name
entity_id = options.entity
if options.offset is not None:
offset = int(options.offset)
def run():
"""
Main function
:return:
"""
data = get_data()
if data is not None:
result = parse_data(data)
body = format_email(result)
payload = generate_payload(body)
send_event(payload)
def abort():
"""
Abort script if options are missings
:return:
"""
if entity_id is None:
print('arguments --entity is missing')
if report_name is None:
print('arguments --name is missing')
if __name__ == '__main__':
parse_options()
if entity_id is not None and report_name is not None:
run()
else:
abort()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment