Here’s a new version.
Creates binary_sensors.
The sensors will contain both interactions as the previous version
Furthermore there will be a “clicks” properties that contain the number of clicks in a timespan defined in the configuration.
type or paste #
# Swint
#
# V1.0
# Create a sensor for each switch passed as input containing
# Value:
# True and Then False upon Switch Interaction (Physical/Automation/UI). You can use as a kind of event to catch in your automations
#
# Attributes:
# Interaction Type
# Automation : The switch was toggled via an automation
# Physical : The switch was toggled via physical interaction
# UI : The switch was toggled via User Interface
# User
# User that interacted in case of UI. Unknown for physical or automation interaction
# Clicks
# The number of clicks registered on the switch, starting from the first and within a maxtime seconds window
#
# Interaction decoding based on
# ID combos: https://community.home-assistant.io/t/work-with-triggered-by-in-automations/400352/8
#interaction id parent_id user_id
#Physical Not Null Null Null
#Automation Not Null Not Null Null
#UI Not Null Null Not Null
#
# Sample config section for apps.yaml:
#switchint:
# module: switchint
# class: switchint
# switches:
# - light.light1
# - light.light2
# - light.light3
# - light.light4
# usersid_users:
# c600656764c74eeeb08a964843fa8771: user1
# 8bfa609e73d644a9bf2e119bb7040491: user2
# maxtime: 5
# logging: logging level 0 none, higher more verbose
# TODO: better input check on entities, translate userid to friendly name of user
import hassapi as hass
from datetime import datetime, timedelta
class swint(hass.Hass):
def initialize(self):
try:
self.loglevel = self.args.get("loglevel",4)
except:
self.log("Error opening parameters!")
return
self.mylog("*******************",0)
self.mylog("Initializing swint.",0)
self.mylog("*******************",0)
self.mylog("Log Level:".format(self.loglevel),0)
try:
self.switches = list(self.args["switches"])
self.usersid_users_dict = dict(self.args.get('usersid_users', None))
self.maxtime = self.args.get("maxtime")
except:
self.log("Error opening parameters")
return
self.switchclicks = { listel : 0 for listel in self.switches }
self.mylog("Switches {}".format(self.switches),1)
self.mylog("Maxtime {}".format(self.maxtime),1)
self.mylog("Switchclicks {}".format(self.switchclicks),1)
for switch in self.switches:
self.mylog("Listening interactions for : {}".format(switch),1)
self.listen_state(self.updatecontext, switch)
self.mylog("Created Entity {}.".format("binary_sensor.il_"+switch.replace(".","_")),1)
self.set_state("binary_sensor.il_"+switch.replace(".","_"), state ="off",
attributes={
"device_class": None,
"unique_id": "binary_sensor.il_"+switch.replace(".","_"),
"name": switch.replace(".","_"),
"last_changed": self.datetime().replace(microsecond=0).isoformat(),
"clicks": 0 }
)
self.switchclicks[switch] = 0
self.listen_state(self.listenclicks, switch)
self.listen_state(self.updatecontext, switch)
self.mylog("Now ListeningG to events.",1)
def updatecontext(self, entity, attribute, old, new, kwargs):
context=self.get_state(entity, attribute="context")
self.id=context["id"]
self.parent_id=context["parent_id"]
self.user_id=context["user_id"]
self.mylog("Current Entity : {} {}".format(entity, context),1)
self.mylog("ID : {}".format(self.id),1)
self.mylog("parent_id : {}".format(self.parent_id),1)
self.mylog("user_id : {}".format(self.user_id),1)
if self.id is not None and self.parent_id is None and self.user_id is None:
self.interaction="physical"
self.user="unknown"
if self.id is not None and self.parent_id is not None and self.user_id is None:
self.interaction="automation"
self.user="unknown"
if self.id is not None and self.parent_id is None and self.user_id is not None:
self.interaction="ui"
self.user=self.user_id
self.mylog("interaction : {}".format(self.interaction),1)
self.mylog("Sensor : {}".format("binary_sensor.il_"+entity),1)
self.set_state("binary_sensor.il_"+entity.replace(".","_"), state ="off", attributes = { "interaction" : self.interaction })
if self.user_id is not None:
self.set_state("binary_sensor.il_"+entity.replace(".","_"), state ="off", attributes = { "user" : self.usersid_users_dict[self.user_id] })
else:
self.set_state("binary_sensor.il_"+entity.replace(".","_"), state ="off", attributes = { "user" : "unknown" })
self.mylog("In Update Context Entity {} Clicks {}".format(entity,self.switchclicks[entity]),1)
def listenclicks(self, entity, attribute, old, new, kwargs):
self.mylog("Listening for Entity {}".format(entity),1)
self.mylog("Current switchclicks {}".format(self.switchclicks[entity]),1)
if self.switchclicks[entity] == 0:
self.switchclicks[entity] = 1
self.mylog("Set callback for Entity {} in {}".format(entity, self.maxtime),1)
self.run_in(self.clickcount, self.maxtime, myentity = entity)
else:
self.switchclicks[entity] = self.switchclicks[entity] + 1
self.mylog("In Listenclcks Entity {} Clicks {}".format(entity,self.switchclicks[entity]),1)
def clickcount(self, myentity):
self.mylog("switchclicks {} ".format(self.switchclicks),1)
self.mylog("MyEntity {} ".format(myentity),1)
self.mylog("Final Clicks for {} : {}".format("binary_sensor.il_"+myentity["myentity"].replace(".","_"), self.switchclicks[myentity["myentity"]]),1)
self.set_state("binary_sensor.il_"+myentity["myentity"].replace(".","_"),
state="on",
attributes={
"device_class": None,
"unique_id": myentity["myentity"]+"_Interaction",
"name": myentity["myentity"]+" Interaction",
"last_changed": self.datetime().replace(microsecond=0).isoformat(),
"clicks": self.switchclicks[myentity["myentity"]] }
)
# self.fire_event("clicks", entity=myentity["myentity"], clicks=self.switchclicks[myentity["myentity"]])
self.mylog("RiRiFinal Clicks {}".format(self.switchclicks[myentity["myentity"]]),1)
self.switchclicks[myentity["myentity"]]=0
self.set_state("binary_sensor.il_"+myentity["myentity"].replace(".","_"), state="off")
def mylog(self,logtxt,thislevel):
if self.loglevel >= thislevel:
self.log(logtxt,log="dev_log")
config
##========================================================================================
## ##
## Swint ##
## ##
##========================================================================================
swint:
module: swint
class: swint
switches:
- light.luce_cucina
- light.led_pensili
usersid_users:
c600656764c74eeeb08a964843fa8771: Alessandro
8bfa609e73d644a9bf2e119bb7040491: admin
loglevel: 3
maxtime: 2
should be self explaining