Advertisement
Guest User

BS440domoticz.py

a guest
Aug 15th, 2018
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.16 KB | None | 0 0
  1. #-----------------------------------------------------------------------------------------
  2. # BS440 plugin BS440domoticz.py
  3. # About:
  4. # Updates scae values to virtual sensors in Domoticz Home automation system
  5. #
  6. # Uses BS440domoticz.ini for plugin parameters
  7. #
  8. # Author: Tristan79
  9. # Edited by: Sjoerd91
  10. #
  11. #------------------------------------------------------------------------------------------
  12. from ConfigParser import *
  13. import os
  14. import urllib
  15. import base64
  16. import logging
  17. import time
  18. import traceback
  19. import json
  20.  
  21. __author__ = 'Tristan79'
  22.  
  23.  
  24. class Plugin:
  25.  
  26.     def __init__(self):
  27.         # put any commands here you would like to be run to initialize your plugin
  28.         return
  29.  
  30.  
  31.     def open_url(self, url):
  32.         global log
  33.         log.debug('Opening url: %s' % (url))
  34.         try:
  35.             response = urllib.urlopen(url)
  36.         except Exception, e:
  37.             log.error('open_url: Failed to send data to Domoticz (%s)' % (url))
  38.             return 'None'
  39.         return response
  40.  
  41.  
  42.     def exists_hardware(self, name):
  43.         global url_hardware
  44.         global domoticzurl
  45.         response = self.open_url(url_hardware % (domoticzurl))
  46.         if response == 'None':
  47.             return 'None'
  48.         data = json.loads(response.read())
  49.         if 'result' in data:
  50.             for i in range(0,len(data['result'])):
  51.                 if name == data['result'][i]['Name']:
  52.                     return data['result'][i]['idx']
  53.         return 'None'
  54.        
  55.        
  56.     def rename_sensors(self, sensorid,name):
  57.         global url_sensor_ren
  58.         global domoticzurl
  59.         try:
  60.             response = self.open_url(url_sensor_ren % (domoticzurl,sensorid,name))
  61.         except:
  62.             pass
  63.  
  64.  
  65.     def exists_sensor(self, name):
  66.         global url_sensor
  67.         global domoticzurl
  68.         global hardwareid
  69.         global query
  70.         global data
  71.         global log
  72.         if query:
  73.             response = self.open_url(url_sensor % (domoticzurl))
  74.             if response == 'None':
  75.                 return 'None'
  76.             data = json.loads(response.read())
  77.             query = False
  78.         if 'result' in data:
  79.             for i in range(0,len(data['result'])):
  80.                 if name == data['result'][i]['Name'] and int(hardwareid) == data['result'][i]['HardwareID']:
  81.                     return data['result'][i]['idx']
  82.         return 'None'
  83.  
  84.  
  85.     def exists_id(self, sensorid):
  86.         global url_sensor
  87.         global domoticzurl
  88.         global query
  89.         global data
  90.         global hardwareid
  91.         global log
  92.         if query:
  93.             response = self.open_url(url_sensor % (domoticzurl))
  94.             if response == 'None':
  95.                 return False
  96.             data = json.loads(response.read())
  97.             query = False
  98.         if 'result' in data:
  99.             for i in range(0,len(data['result'])):
  100.                 if sensorid == data['result'][i]['idx'] and int(hardwareid) == data['result'][i]['HardwareID']:
  101.                     return True
  102.         return False
  103.  
  104.  
  105.     def exists_realid(self, realid):
  106.         global url_sensor
  107.         global domoticzurl
  108.         global query
  109.         global data
  110.         global hardwareid
  111.         if query:
  112.             response = self.open_url(url_sensor % (domoticzurl))
  113.             if response == 'None':
  114.                 return ["",""]
  115.             data = json.loads(response.read())
  116.             query = False
  117.         if 'result' in data:
  118.             for i in range(0,len(data['result'])):
  119.                 if str(realid) == data['result'][i]['ID'] and int(hardwareid) == data['result'][i]['HardwareID']:
  120.                     return [data['result'][i]['idx'],data['result'][i]['Name']]
  121.         return ["",""]
  122.  
  123.  
  124.     def rename_realid(self, id, newname):
  125.         global query
  126.         query = True
  127.         d = self.exists_realid(id)
  128.         if d[1] == "Unknown":
  129.             self.rename_sensors(d[0],newname)
  130.             query = True
  131.  
  132.  
  133.     def use_virtual_sensor(self, name, type, options=''):
  134.         global hardwareid
  135.         global domoticzurl
  136.         global url_sensor_add
  137.         global query
  138.         global log
  139.         sensorid = self.exists_sensor(name)
  140.         if 'None' != sensorid:
  141.             return sensorid
  142.         if 'None' == sensorid:
  143.             url = url_sensor_add % (domoticzurl, hardwareid, name.replace(' ', '%20'),str(type))
  144.             if options != '':
  145.                 url = url + '&sensoroptions=' + options
  146.             response = self.open_url(url)
  147.             query = True
  148.             return self.exists_sensor(name)
  149.  
  150.  
  151.     # create or discover sensors
  152.     def get_id(self, iniid, text, type, options=""):
  153.         global user
  154.         global personsection
  155.         global pluginconfig
  156.         global log
  157.         try:
  158.             rid = pluginconfig.get(personsection, iniid)
  159.             if not self.exists_id(rid):
  160.                 raise Exception
  161.         except:
  162.             rid = self.use_virtual_sensor(user + ' ' + text,type,options)
  163.             pluginconfig.set(personsection, iniid, rid)
  164.             write_config = True
  165.         return rid
  166.        
  167.  
  168.     def get_realid(self, iniid,default):
  169.         global personsection
  170.         global pluginconfig
  171.         try:
  172.             return pluginconfig.get(personsection, iniid)
  173.         except:
  174.             write_config = True
  175.             pluginconfig.set(personsection, iniid, str(default))
  176.             return default
  177.                
  178.  
  179.     def execute(self, globalconfig, persondata, weightdata, bodydata):
  180.         global url_hardware
  181.         global domoticzurl
  182.         global url_sensor_ren
  183.         global url_sensor
  184.         global hardwareid
  185.         global query
  186.         global data
  187.         global url_sensor_add
  188.         global user
  189.         global personsection
  190.         global log
  191.         global pluginconfig
  192.         # --- part of plugin skeleton
  193.         # your plugin receives the config details from BS440.ini as well as
  194.         # all the data received from the scale
  195.         log = logging.getLogger(__name__)
  196.         log.info('Starting plugin: ' + __name__)
  197.         #read ini file from same location as plugin resides, named [pluginname].ini
  198.         configfile = os.path.dirname(os.path.realpath(__file__)) + '/' + __name__ + '.ini'
  199.         pluginconfig = SafeConfigParser()
  200.         pluginconfig.read(configfile)
  201.         log.info('ini read from: ' + configfile)
  202.  
  203.  
  204.         write_config = False
  205.         data = '{}'
  206.         query = True
  207.         SensorPercentage = 2
  208.         SensorCustom = 1004
  209.         SensorScale = 93
  210.  
  211.         domoticzurl = pluginconfig.get('Domoticz', 'domoticz_url')   
  212.         try:
  213.             hardwarename = pluginconfig.get('Domoticz', 'hardware_name')
  214.         except:
  215.             hardwarename = "Medisana"
  216.  
  217.         domoticzuser = ""
  218.         domoticzpwd = ""
  219.      
  220.         # read user's name
  221.         personsection = 'Person' + str(weightdata[0]['person'])
  222.         if pluginconfig.has_section(personsection):
  223.             user = pluginconfig.get(personsection, 'username')
  224.         else:
  225.             log.error('Unable to update Domoticz: No details found in ini file '
  226.                       'for person %d' % (weightdata[0]['person']))
  227.             return
  228.        
  229.         url_mass = 'http://%s/json.htm?type=command&param=udevice&hid=%s&' \
  230.                   'idx=%s&dunit=%s&dtype=93&dsubtype=1&nvalue=0&svalue=%s'
  231.         url_per = 'http://%s/json.htm?type=command&param=udevice&idx=%s&nvalue=0&svalue=%s'
  232.         url_hardware_add = 'http://%s/json.htm?type=command&param=addhardware&htype=15&port=1&name=%s&enabled=true'
  233.         url_hardware = 'http://%s/json.htm?type=hardware'
  234.         url_sensor = 'http://%s/json.htm?type=devices&filter=utility&order=Name'
  235.         url_sensor_add = 'http://%s/json.htm?type=createvirtualsensor&idx=%s&sensorname=%s&sensortype=%s'
  236.         url_sensor_ren = 'http://%s/json.htm?type=command&param=renamedevice&idx=%s&name=%s'
  237.  
  238.  
  239.         # Check if hardware exists and add if not..
  240.         hardwareid = self.exists_hardware(hardwarename)
  241.         if 'None' == hardwareid:
  242.             response = self.open_url(url_hardware_add % (domoticzurl, hardwarename.replace(' ', '%20')))
  243.             hardwareid = self.exists_hardware(hardwarename)
  244.             if 'None' == hardwareid:
  245.                 log.error('Unable to access or create Domoticz hardware')
  246.                 return
  247.  
  248.         try:
  249.             try:
  250.                 pluginconfig.add_section(personsection)
  251.             except DuplicateSectionError:
  252.                 pass
  253.             fatid = self.get_id('fat_per_id','Fat Percentage',SensorPercentage)
  254.             bmrid = self.get_id('bmr_id','BMR',SensorCustom,'1;Calories')
  255.             muscleid = self.get_id('muscle_per_id','Muscle Percentage',SensorPercentage)
  256.             boneid = self.get_id('bone_per_id','Bone Percentage',SensorPercentage)
  257.             waterid = self.get_id('water_per_id','Water Percentage',SensorPercentage)
  258.             lbmperid = self.get_id('lbm_per_id','Water Percentage',SensorPercentage)
  259.             bmiid = self.get_id('bmi_id','BMI',SensorCustom,'1;')
  260.            
  261.             # Mass
  262.             weightid = self.get_id('weight_id', 'Weight', SensorScale)
  263.             fatmassid = self.get_id('fat_mass_id', 'Fat Mass', SensorScale)
  264.             watermassid = self.get_id('watermass_id', 'Water Mass', SensorScale)
  265.             musclemassid = self.get_id('muscle_mass_id', 'Muscle Mass', SensorScale)
  266.             bonemassid = self.get_id('bone_mass_id', 'Bone Mass', SensorScale)
  267.             lbmid = self.get_id('lbm_id', 'Lean Body Mass', SensorScale)
  268.            
  269.             """
  270.             weightid = self.get_realid('weight_id',79)
  271.             fatmassid = self.get_realid('fat_mass_id',80)
  272.             watermassid = self.get_realid('watermass_id',81)
  273.             musclemassid = self.get_realid('muscle_mass_id',82)
  274.             bonemassid = self.get_realid('bone_mass_id',83)
  275.             lbmid = self.get_realid('lbm_id',84)
  276.             """
  277.             weightunit = self.get_realid('weight_unit',1)
  278.             fatmassunit = self.get_realid('fatmass_unit',1)
  279.             watermassunit = self.get_realid('watermass_unit',1)
  280.             musclemassunit = self.get_realid('musclemass_unit',1)
  281.             bonemassunit = self.get_realid('bonemass_unit',1)
  282.             lbmunit = self.get_realid('lbm_unit',1)
  283.            
  284.         except:
  285.             log.error('Unable to access Domoticz sensors')
  286.             return
  287.  
  288.         write_config = True
  289.  
  290.         if write_config:
  291.             fconfigfile = open(configfile, 'wb')
  292.             pluginconfig.write(fconfigfile)
  293.             fconfigfile.close()
  294.             write_config = False
  295.             """
  296.             with open(configfile, 'wb') as fconfigfile:
  297.                 fpluginconfig.write(configfile)
  298.                 configfile.close()
  299.                 write_config = False
  300.             """
  301.  
  302.         try:
  303.             # calculate and populate variables
  304.             weight = weightdata[0]['weight']
  305.             fat_per = bodydata[0]['fat']
  306.             fat_mass = weight * (fat_per / 100.0)
  307.             water_per = bodydata[0]['tbw']
  308.             water_mass = weight * (water_per / 100.0)
  309.             muscle_per = bodydata[0]['muscle']
  310.             muscle_mass = (muscle_per / 100) * weight
  311.             bone_mass = bodydata[0]['bone']
  312.             bone_per = (bone_mass / weight) * 100
  313.             lbm = weight - (weight * (fat_per / 100.0))
  314.             lbm_per = (lbm / weight) * 100
  315.             kcal = bodydata[0]['kcal']
  316.             bmi = 0
  317.             for p in persondata:
  318.                 if p['person'] == bodydata[0]['person']:
  319.                     size = p['size'] / 100.0
  320.                     bmi = weight / (size * size)
  321.  
  322.             log_update = 'Updating Domoticz for user %s at index %s with '
  323.  
  324.             # Mass
  325.  
  326.             log.info((log_update+'weight %s') % (user, weightid, weight))
  327.             self.open_url(url_mass % (domoticzurl, hardwareid, weightid, weightunit, weight))
  328.  
  329.             log.info((log_update+'fat mass %s') % (user, fatmassid, fat_mass))
  330.             self.open_url(url_mass % (domoticzurl, hardwareid, fatmassid, fatmassunit, fat_mass))
  331.  
  332.             log.info((log_update+'water mass %s') % (user, watermassid, water_mass))
  333.             self.open_url(url_mass % (domoticzurl, hardwareid, watermassid, watermassunit, water_mass))
  334.  
  335.             log.info((log_update+'muscle mass %s') % (user, musclemassid, muscle_mass))
  336.             self.open_url(url_mass % (domoticzurl, hardwareid, musclemassid, musclemassunit, muscle_mass))
  337.  
  338.             log.info((log_update+'bone mass %s') % (user, bonemassid, bone_mass))
  339.             self.open_url(url_mass % (domoticzurl, hardwareid, bonemassid, bonemassunit, bone_mass))
  340.  
  341.             log.info((log_update+'lean body mass %s') % (user, lbmid, lbm))
  342.             self.open_url(url_mass % (domoticzurl, hardwareid, lbmid, lbmunit, lbm))
  343.  
  344.             # Percentage
  345.  
  346.             log.info((log_update+'fat percentage %s') % (user, fatid, fat_per))
  347.             self.open_url(url_per % (domoticzurl, fatid, fat_per))
  348.  
  349.             log.info((log_update+'water percentage %s') % (user, waterid, water_per))
  350.             self.open_url(url_per % (domoticzurl, waterid, water_per))
  351.                    
  352.             log.info((log_update+'muscle percentage %s') % (user, muscleid, muscle_per))
  353.             self.open_url(url_per % (domoticzurl, muscleid, muscle_per))
  354.  
  355.             log.info((log_update+'bone percentage %s') % (user, boneid, bone_per))
  356.             self.open_url(url_per % (domoticzurl, boneid, bone_per))
  357.  
  358.             log.info((log_update+'lean body mass percentage %s') % (user, lbmperid, lbm_per))
  359.             self.open_url(url_per % (domoticzurl, lbmperid, lbm_per))
  360.            
  361.             # Other
  362.  
  363.             log.info((log_update+'basal metabolic rate calories %s') % (user, bmrid, kcal))
  364.             self.open_url(url_per  % (domoticzurl, bmrid, kcal))
  365.                
  366.             log.info((log_update+'body mass index %s') % (user, bmiid, bmi))
  367.             self.open_url(url_per  % (domoticzurl, bmiid, bmi))
  368.  
  369.             self.rename_realid(weightid,user + " " + 'Weight')
  370.             self.rename_realid(fatmassid,user + " " + 'Fat Mass')
  371.             self.rename_realid(musclemassid,user + " " + 'Muscle Mass')
  372.             self.rename_realid(watermassid,user + " " + 'Water Mass')
  373.             self.rename_realid(bonemassid,user + " " + 'Bone Mass')
  374.             self.rename_realid(lbmid,user + " " + 'Lean Body Mass')
  375.  
  376.             log.info('Domoticz succesfully updated')
  377.  
  378.         except:
  379.             log.error('Unable to update Domoticz: Error sending data.')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement