Advertisement
Guest User

Trendsensor

a guest
Aug 31st, 2020
1,510
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.95 KB | None | 0 0
  1. import hassapi as hass
  2.  
  3. # App to track the trend of a sensor
  4.  
  5. # Args:
  6.  
  7. # sensor: The sensor entity to track. Any entity that has a value in its state may be used.
  8. # trend: The entity to set to either or "on" or "off". A state of "on" indicates an increasing trend and
  9. #        a state of "off" indicates a decreasing trend. Any entity that can be turned on or off may be used.
  10. # samples: Number of samples to use. Must be a number and not an entity id
  11.  
  12. # the app only reads "live" samples and does not read samples from the HA history when the app is instantiated
  13. # For fast changing sensors, increase the number of samples to get a more accurate indication of the trend. For a slow
  14. # changing system like the indoor temperature, 4 samples will be sufficient.
  15.  
  16. # Example configuration to put in apps.yaml
  17. #   trendsensor:
  18. #       module: trend
  19. #       class: trendsensor
  20. #       sensor: sensor.temperature
  21. #       samples: 4
  22. #       trend: input_boolean.temperature_trend
  23.  
  24. # Author: Tomas Jansson
  25. # Version 1.0
  26. # Version date: 2017-11-21
  27.  
  28. # todo: Read samples from history when instantiated
  29.  
  30. class trendsensor(hass.Hass):
  31.     SENSOR      = "sensor"
  32.     SAMPLES     = "samples"
  33.     TREND       = "trend"
  34.     STATE_ON    = "on"
  35.     STATE_OFF   = "off"
  36. # Listen for state changes for the sensor.
  37.     def initialize(self):
  38.         self.listen_state(self.sensor_change, self.args[self.SENSOR])
  39.         self.index = 0
  40.         self.samples = [0] * self.args[self.SAMPLES]
  41.  
  42.     def sensor_change(self, entity, attribute, old, new, kwargs):
  43. #       Rotate the list left one step.
  44.         self.samples = self.rotate(self.samples,1)
  45. #       Add the new sensor value to the end of the list.
  46.         self.samples[self.args[self.SAMPLES]-1] = (self.to_float(self.SENSOR))
  47. #       Get the number of items in samples.
  48.         x = range(1,len(self.samples)+1)
  49.         self.log(self.samples)
  50.         if self.beta(x,self.samples) == self.STATE_ON:
  51.             self.turn_on(self.args[self.TREND])
  52.         else:
  53.             self.turn_off(self.args[self.TREND])
  54.  
  55.     def var(self,X):
  56.         S = 0.0
  57.         SS = 0.0
  58.         for x in X:
  59.             S += x
  60.             SS += x*x
  61.         xbar = S/float(len(X))
  62.         return (SS - len(X) * xbar * xbar) / (len(X) -1.0)
  63.  
  64.     def cov(self,X,Y):
  65.         n = len(X)
  66.         xbar = sum(X) / n
  67.         ybar = sum(Y) / n
  68.         return sum([(x-xbar)*(y-ybar) for x,y in zip(X,Y)])/(n-1)
  69.  
  70.     def beta(self,x,y):
  71.         if (self.cov(x,y) / self.var(x)) > 0:
  72.             return self.STATE_ON
  73.         else:
  74.             return self.STATE_OFF
  75.  
  76. # Returns the value of the state of an entity in the args list as a float.
  77.     def to_float(self, arg):
  78.         return float(self.get_state(self.args[arg]))
  79.  
  80. # Returns the state of an entity in the args list
  81.     def to_state(self, arg):
  82.         return self.get_state(self.args[arg])
  83.  
  84. # Rotates a list n steps to the left.
  85.     def rotate(self,l, n):
  86.         return l[n:] + l[:n]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement