here we go, no secrets in there after all…
##########################################################################################
## Resources:
## https://github.com/maattdiy/home-assistant-config @Mviezzer
## https://home-assistant.io/components/python_script/
## https://home-assistant.io/docs/configuration/state_object/
##########################################################################################
debug = False
show_badges = True
show_card = True
group_count = 0
group_desc = ''
summary = ''
idx = 0
dt_prevstate = None
if debug:
event = data.get('event')
logger.error("\n\nSUMMARY: " + str(event))
##########################################################################################
## Group count
## Groups config:
## Entities summary by group name
# groups = need to have same member_count
# groups_format = # Message prefix
# groups_filter = # Filter to list
# groups_badge = # Badge 'belt' (unit_of_measurement)
# groups_badge_pic = # none, one, or a list of pictures (picture position = match the count)
# groups_min_show = # Mininum count to show
# groups_theme = # Theme template
# groups_desc = # Can set the default description, for use in case count = 0
# themes build up or down according to counted value
##########################################################################################
on_theme ='red_badge|yellow_badge|grey_badge|blue_badge|orange_badge|brown_badge|black_badge|green_badge'
off_theme ='green_badge|black_badge|brown_badge|orange_badge|blue_badge|yellow_badge|grey_badge|red_badge'
groups = ['group.family','group.binary_sensors_active_template',
'group.hubs_binary_pinged','group.critical_devices_state',
'group.media_player_media','group.device_tracker_media']
groups_format = ['+- Home: {} -- {}','#- Active: {} -- {}','!|-> Offline: {} -- {}',
'!|-> Status - Critical device offline: {} -- {}','#- Playing: {} -- {}','#- Tracked: {} -- {}']
groups_filter = ['home', 'home|playing|on', 'off|idle|not_home',
'off|idle|unknown|not_home', 'home|playing|on', 'home|playing|on']
groups_badge = ['Home', 'Active', 'Hubs', 'Status', 'Play', 'Track']
groups_badge_pic = ['', '', 'ok|bug|critical', 'ok|bug|critical', '', '']
groups_min_show = [0, 0, 0, 0, 0, 0]
groups_theme = [on_theme, on_theme, off_theme, off_theme, on_theme, on_theme]
groups_desc = ['!|-> Nobody home since ', '%|-> No Appliances active', '+- Hubs: all online',
'+- Status: all online', '%|-> Nothing playing', '%|-> Nothing tracked']
groups_count = [0, 0, 0, 0, 0, 0]
for group in groups:
group_count = 0
group_desc = ''
for entity_id in hass.states.get(group).attributes['entity_id']:
state = hass.states.get(entity_id)
filter = groups_filter[idx]
if (state.state in filter.split('|') or debug):
dt = state.last_changed
dt = dt + datetime.timedelta(hours=+1)
time = '%02d:%02d' % (dt.hour, dt.minute)
# If state changed in the past days show the date too
if dt.date() < datetime.datetime.now().date():
time = '{} {}'.format('%02d/%02d' % (dt.day, dt.month), time)
group_count = group_count + 1
group_desc = '{} {} ({}), '.format(group_desc, state.name, time)
else:
if (dt_prevstate is None):
dt_prevstate = state.last_changed
else:
if (not state.last_changed is None):
if (state.last_changed > dt_prevstate):
dt_prevstate = state.last_changed
# Final format for this group
if (group_count >= groups_min_show[idx]):
if (group_count == 0):
group_desc = groups_desc[idx]
# If there is none 'On/Home' state in group, show since
if (group_desc.find(' since ') > 0): #if (group_desc != ''):
dt = dt_prevstate + datetime.timedelta(hours=+1)
group_desc = '{} {}'.format(group_desc, '%02d:%02d' % (dt.hour, dt.minute))
else:
group_desc = groups_format[idx].format(group_count, group_desc[:-2])
groups_desc[idx] = group_desc
groups_count[idx] = group_count
idx = idx + 1
##########################################################################################
## Badges updates
##########################################################################################
idx = 0
order = 2
if show_badges:
for badge in groups_badge:
if (badge != ''):
entity_id = 'sensor.{}_badge'.format(badge.replace(' ', '').lower());
hidden = False if (groups_count[idx] >= groups_min_show[idx] or debug) else True
fname = groups_desc[idx] if debug else ' '
picture = groups_badge_pic[idx].replace(' ', '').lower()
theme = groups_theme[idx].replace('value', \
'entities["{}"].state'.format(entity_id)) \
if (groups_theme[idx] != '') else 'default'
# Check for theme X index/count
if (theme.find('|') > 0):
list = theme.split('|')
if (len(list) in [1, groups_count[idx]]):
theme = list[len(list)-1]
else:
theme = list[groups_count[idx]]
# Check for picture X index/count
if (picture != ''):
list = picture.split('|')
if (len(list) in [1, groups_count[idx]]):
picture = list[len(list)-1]
else:
picture = list[groups_count[idx]]
if (picture != ''):
picture = '/local/badges/{}.png'.format(picture)
hass.states.set(entity_id, groups_count[idx], {
'friendly_name': fname,
'unit_of_measurement': badge,
'entity_picture': picture,
# 'state_card_mode': 'badges',
'hidden': hidden,
'templates': { 'theme': theme },
'order': order
})
order = order + 1
idx = idx + 1
##########################################################################################
## Alarm clock
## https://github.com/maattdiy/home-assistant-config/blob/master/config/packages/alarmclock.yaml
##########################################################################################
#alarms_prefix = ['alarmclock_wd', 'alarmclock_we']
#alarms_wfilter = ['1|2|3|4|5', '6|7']
#alarms_desc = ''
#idx = 0
#alarms_uom = []
#alarms_picture = []
#alarms_fn = []
#for entity_id in alarms_prefix:
# state = hass.states.get('input_boolean.{}_enabled'.format(entity_id))
# if state:
# if state.state is 'on':
# # Show the alarm for the next day
# if (str(datetime.datetime.now().isoweekday()) in alarms_wfilter[idx].split('|')):
# state = hass.states.get('sensor.{}_time_template'.format(entity_id))
# alarms_desc = '{}{}, '.format(alarms_desc, state.state)
# idx = idx + 1
#if (alarms_desc == ''):
# alarms_fn = 'Relax'
# alarms_desc = '%- Alarm clock is not set, relax'
# alarms_uom = 'Off'
# alarms_picture = '/local/badges/alarm_off.png'
#else:
# alarms_fn = alarms_desc[:-2]
# alarms_desc = '/- Alarm clock set at ' + alarms_desc[:-2]
# alarms_uom = 'On'
# alarms_picture = '/local/badges/alarm.png'
#hass.states.set('sensor.alarms_badge',state.state, {
# 'entity_picture': alarms_picture,
# 'friendly_name': alarms_fn,
# 'unit_of_measurement': alarms_uom,
# 'hidden': hidden,
# 'order': order
# })
#from datetime import datetime
alarms_prefix = ['alarmclock_wd', 'alarmclock_we']
alarms_wfilter = [range(1,6), range(6,8)]
alarms_desc = ''
mydict = {'hidden':hidden, 'order':order}
for entity_id, filter in zip(alarms_prefix, alarms_wfilter):
state = hass.states.get('input_boolean.{}_enabled'.format(entity_id))
if state:
if state.state is 'on' and datetime.datetime.now().isoweekday() in filter:
state = hass.states.get('sensor.{}_time_template'.format(entity_id))
alarms_desc = '{}{}, '.format(alarms_desc, state.state)
if (alarms_desc == ''):
mydict['entity_picture'] = '/local/badges/alarm_off.png'
mydict['friendly_name'] = 'Relax'
mydict['unit_of_measurement'] = 'Off'
mydict['theme'] = 'grey_badge'
alarms_desc = '%- Alarm clock is not set, relax'
else:
mydict['entity_picture'] = '/local/badges/alarm.png'
mydict['friendly_name'] = alarms_desc[:-2]
mydict['unit_of_measurement'] = 'On'
mydict['theme'] = 'orange_badge'
alarms_desc = '/- Alarm clock set at ' + alarms_desc[:-2]
hass.states.set('sensor.alarms_badge', '', mydict)
##########################################################################################
## Mode:
## General package: https://github.com/maattdiy/home-assistant-config/blob/master/config/packages/profiles.yaml
## Developer package: https://github.com/maattdiy/home-assistant-config/blob/master/config/packages/developer.yaml
## Badges images: /config/www/badges
##########################################################################################
mode_desc = ''
state = hass.states.get('input_select.mode')
# Get info
#dt = datetime.datetime.now()
#time = "%02d:%02d" % (dt.hour, dt.minute)
if state:
hidden = False #if (state.state != 'Normal') else True
if state.state is not 'Unknown':
dt = hass.states.get('automation.mode_selection').attributes.get('last_triggered')
if dt:
# time = dt.strftime("%H:%M")
time = "%02d:%02d" % (dt.hour+1, dt.minute)
hass.states.set('sensor.mode_badge',state.state, {
'entity_picture': '/local/modes/{''}.png'.format(state.state.replace(' ','').lower()),
'friendly_name': time,
'unit_of_measurement': 'Mode',
'hidden': hidden,
'order': order
})
if state.state is not 'Hidden':
mode_desc = '{}*- {} mode selected at: {}\n'.format(summary, state.state, time)
##########################################################################################
## Activity:
##
##########################################################################################
activity_desc = ''
## Get activity description
state = hass.states.get('input_select.activity')
state_value = hass.states.get('input_select.activity').state
#time = '?'
# Get info
#dt = state.attributes.get('last_triggered')
#time = '%02d:%02d' % (dt.hour, dt.minute)
if not state is None:
hidden = False #if (state.state != 'Normal') else True
if state.state != 'Unknown':
dt = hass.states.get('automation.activity_selection').attributes.get('last_triggered')
if not dt is None:
time = "%02d:%02d" % (dt.hour+1, dt.minute)
if not hidden:
activity_desc = '{}$- {} activity selected at: {}\n'.format(summary, state.state, time)
hass.states.set('sensor.activity_badge', state_value, {
'friendly_name': time, #state_value,
'entity_picture': '/local/activities/{' '}.png'.format(state_value.replace(' ','').lower()),
'unit_of_measurement': 'Act'
})
##########################################################################################
## Lights:
##########################################################################################
lights_group = 'group.all_lights_only'
#show only lights, not light groups
excluded = ['light.custom_group_for_group','light.custom_group_for_lights_2']
lights_message = []
sensor_lights_message = []
sensor_lights_desc = []
lights_desc = []
lights_on = []
lights_picture = []
lights_uom = []
total_on = hass.states.get('input_boolean.anything_on').attributes.get('lights_on')
for entity_id in hass.states.get(lights_group).attributes['entity_id']:
dt = hass.states.get('automation.sense_lights_change').attributes.get('last_triggered')
dt = dt + datetime.timedelta(hours=+1)
time = '%02d:%02d' % (dt.hour, dt.minute)
if hass.states.get(entity_id).state is 'on' and entity_id not in excluded:
lights_on.append(hass.states.get(entity_id).attributes["friendly_name"])
state = hass.states.get(entity_id)
if len(lights_on) > 0:
lights_picture = '/local/lights/hue_pl.png'
lights_message = ', '.join(lights_on)
sensor_lights_message = 'Lights on: ' +', '.join(lights_on)
lights_desc = '=- Lights on: {} -- {} since {}'.format(total_on,lights_message,time)
lights_uom = 'Lights'
if len(lights_on) == 1:
lights_uom = 'Light'
else:
lights_picture = '/local/lights/bulboff.png'
lights_message= ''
sensor_lights_message= 'No lights on'
lights_desc = '!|-> No lights on since {}'.format(time)
lights_uom = 'Lights'
sensor_lights_desc = '{}'.format(sensor_lights_message)
hass.states.set('sensor.lights_badge', total_on, {
# 'custom_ui_state_card': 'state-card-value_only',
'text': sensor_lights_message,
'unit_of_measurement': lights_uom,
'friendly_name': time,
'entity_picture': lights_picture
})
##########################################################################################
## Switches:
##########################################################################################
switches_group = 'group.iungo_switch_switches_template'
switches_message = []
sensor_switches_message = []
sensor_switches_desc = []
switches_desc = []
switches_on = []
switches_picture = []
switches_uom = []
total_on = hass.states.get('input_boolean.anything_on').attributes.get('switches_on')
for entity_id in hass.states.get(switches_group).attributes['entity_id']:
dt = hass.states.get('automation.sense_switches_change').attributes.get('last_triggered')
dt = dt + datetime.timedelta(hours=+1)
time = '%02d:%02d' % (dt.hour, dt.minute)
if hass.states.get(entity_id).state is 'on' and entity_id not in excluded:
switches_on.append(hass.states.get(entity_id).attributes["friendly_name"])
state = hass.states.get(entity_id)
if len(switches_on) > 0:
switches_picture = '/local/buttons/button_power_on.png'
switches_message = ', '.join(switches_on)
sensor_switches_message = 'Switches on: ' +', '.join(switches_on)
switches_desc = '#- Switches on: {} -- {} since {}'.format(total_on,switches_message,time)
switches_uom = 'Switches'
if len(switches_on) == 1:
switches_uom = 'Switch'
else:
switches_picture = '/local/buttons/button_power_off.png'
switches_message= ''
sensor_switches_message= 'No switches on'
switches_desc = '!|-> No switches on since {}'.format(time)
switches_uom = 'Switches'
sensor_switches_desc = '{}'.format(sensor_switches_message)
hass.states.set('sensor.switches_badge', total_on, {
# 'custom_ui_state_card': 'state-card-value_only',
'text': sensor_switches_message,
'unit_of_measurement': switches_uom,
'friendly_name': time,
'entity_picture': switches_picture
})
##########################################################################################
## Appliances:
##########################################################################################
appliances_group = 'group.iungo_switch_appliances_template'
appliances_message = []
sensor_appliances_message = []
sensor_aplliances_desc = []
appliances_desc = []
appliances_on = []
appliances_picture = []
appliances_uom = []
total_on = hass.states.get('input_boolean.anything_on').attributes.get('appliances_on')
for entity_id in hass.states.get(appliances_group).attributes['entity_id']:
dt = hass.states.get('automation.sense_appliances_change').attributes.get('last_triggered')
dt = dt + datetime.timedelta(hours=+1)
time = '%02d:%02d' % (dt.hour, dt.minute)
if hass.states.get(entity_id).state is 'on' and entity_id not in excluded:
appliances_on.append(hass.states.get(entity_id).attributes["friendly_name"])
state = hass.states.get(entity_id)
if len(appliances_on) > 0:
appliances_picture = '/local/buttons/button_power_on.png'
appliances_message = ', '.join(appliances_on)
sensor_appliances_message = 'Appliances on: ' +', '.join(appliances_on)
appliances_desc = '#- Appliances on: {} -- {} since {}'.format(total_on,appliances_message,time)
appliances_uom = 'Appliances'
if len(appliances_on) == 1:
appliances_uom = 'Appliance'
else:
appliances_picture = '/local/buttons/button_power_off.png'
appliances_message= ''
sensor_appliances_message= 'No appliances on'
appliances_desc = '!|-> No appliances on since {}'.format(time)
appliances_uom = 'Appliances'
sensor_appliances_desc = '{}'.format(sensor_appliances_message)
hass.states.set('sensor.appliances_badge', total_on, {
# 'custom_ui_state_card': 'state-card-value_only',
'text': sensor_appliances_message,
'unit_of_measurement': appliances_uom,
'friendly_name': time,
'entity_picture': appliances_picture
})
##########################################################################################
## Summary update
## Custom card: /custom_ui/state-card-value_only.html
##########################################################################################
for group_desc in groups_desc:
if group_desc != '' and not group_desc.endswith(': '):
summary = '{}{}\n'.format(summary, group_desc)
## Add to final summary
summary = '{}\n{}\n{}\n{}\n{}\n{}\n{}'.format(summary, alarms_desc, activity_desc, mode_desc,\
lights_desc, switches_desc, appliances_desc)
if show_card:
hass.states.set('sensor.summary', '', {
'custom_ui_state_card': 'state-card-value_only',
'text': summary
})
##########################################################################################
## Codes for text_colors declared in
## Custom card: /custom_ui/state-card-value_only.html
##########################################################################################
# case "*": return "bold";
# case "/": return "italic";
# case "!": return "red";
# case "+": return "green";
# case "=": return "yellow";
# case "%": return "grey";
# case "$": return "brown";
# case "#": return "blue";
# default: return "normal";