Esempio n. 1
0
 def __init__(self, slave_keys):
     ## Logger object for formatting and printing logs
     self.logger = Logger(DEBUG_MODE, LOG_FILE);
     ## SQL object for managing database
     self.sql = MasterSql();
     self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
     ## Object containing AES keys for encrypted communications
     self.aes_slave_keys = slave_keys;
Esempio n. 2
0
 def __init__(self, daemon):
     ## Logger object for formatting and printing logs
     self.logger = Logger(False, LOG_FILE)
     ## SQL object for managing database
     self.sql = MasterSql()
     ## Instance of the slave daemon
     self.daemon = daemon
     ## Trigger list
     self.triggers_list = ''
     self.update_triggers_list()
Esempio n. 3
0
 def __init__(self, daemon):
     Thread.__init__(self)
     ## Logger object for formatting and printing logs
     self.logger = Logger(False, LOG_FILE)
     ## SQL object for managing slave daemon database
     self.sql = MasterSql()
     ## Instance of the slave daemon
     self.daemon = daemon
     ## List of scenarios
     self.scenarios_list = {}
     self.update_scenarios_list()
Esempio n. 4
0
 def remote_sql(self, json_obj, connection):
     """
     Execute sql command from configurator
     """
     db = MasterSql();
     req = json_obj['data'].split(';');
     for item in req:
         if item != '':
             db.mysql_handler_personnal_query(item);
     connection.close();
     return;
Esempio n. 5
0
 def __init__(self, slave_keys):
     ## Logger object for formatting and printing
     self.logger = Logger(DEBUG_MODE, LOG_FILE)
     ## SQL manager for the master daemon
     self.sql = MasterSql()
     self._parser = DaemonConfigParser('/etc/domoleaf/master.conf')
     ## Object containing the AES keys for encrypted communications
     self.aes_slave_keys = slave_keys
     ## Array containing functions associated with IDs
     self.functions_transform = {
         0: utils.convert_none,
         4: utils.eno_onoff
     }
Esempio n. 6
0
    def __init__(self, daemon):
        ## The logger used for formating and printing
        self.logger = Logger(False, LOG_FILE);
        self.logger.debug('Init CalcLogs');

        ## SQL manager
        self.sql = MasterSql();

        ## The instance of the slave daemon
        self.daemon = daemon;

        ## List of the devices
        self.devices_list = {};
        self.devices_list_update();
Esempio n. 7
0
class EnOceanManager:

    ## The constructor.
    #
    # @param slave_keys The aes keys of the slaves.
    def __init__(self, slave_keys):
        ## Logger object for formatting and printing
        self.logger = Logger(DEBUG_MODE, LOG_FILE);
        ## SQL manager for the master daemon
        self.sql = MasterSql();
        self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
        ## Object containing the AES keys for encrypted communications
        self.aes_slave_keys = slave_keys;
        ## Array containing functions associated with IDs
        self.functions_transform = {
              0: utils.convert_none,
              4: utils.eno_onoff
        };

    ## Updates the table room_device_option with EnOcean values.
    #
    # @param daemon_id The ID of the daemon.
    # @param json_obj JSON object containing the source address of the EnOcean device.
    # @param db The database handler.
    #
    # @return The result of the query.
    def update_room_device_option(self, daemon_id, json_obj, db):
        query = ''.join(["SELECT room_device_option.option_id, room_device.room_device_id, addr_plus, function_answer, room_device_option.dpt_id ",
              "FROM room_device_option JOIN room_device ON room_device_option.room_device_id=room_device.room_device_id ",
              "JOIN dpt_optiondef ON dpt_optiondef.option_id=room_device_option.option_id AND ",
              "dpt_optiondef.protocol_id=room_device.protocol_id AND dpt_optiondef.dpt_id=room_device_option.dpt_id ",
              "WHERE daemon_id=", str(daemon_id), " AND room_device_option.addr=\"", str(json_obj['src_addr']), "\""]);
        res = self.sql.mysql_handler_personnal_query(query, db);
        result = []
        append = result.append
        if not res:
            query = ''.join(["SELECT room_device_option.option_id, room_device.room_device_id, addr_plus, function_answer, room_device_option.dpt_id ",
                  "FROM room_device_option JOIN room_device ON room_device_option.room_device_id=room_device.room_device_id ",
                  "JOIN dpt_optiondef ON dpt_optiondef.option_id=room_device_option.option_id AND ",
                  "dpt_optiondef.protocol_id=room_device.protocol_id AND dpt_optiondef.dpt_id=room_device_option.dpt_id ",
                  "WHERE daemon_id=", str(daemon_id), " AND  room_device_option.addr_plus=\"", str(json_obj['src_addr']), "\""]);
            res = self.sql.mysql_handler_personnal_query(query, db);
        for r in res:
            val = self.functions_transform[r[3]](int(json_obj['value']), r[4]);
            if val is not None:
                append(r)
                up = ''.join(["UPDATE room_device_option SET opt_value=\"", str(val),
                      "\" WHERE room_device_id=", str(r[1]), " AND option_id=\"", str(r[0]), "\""]);
                self.sql.mysql_handler_personnal_query(up, db);
        return result
Esempio n. 8
0
 def __init__(self, daemon):
     self.logger = Logger(False, LOG_FILE);
     self.sql = MasterSql();
     self.daemon = daemon;
     self.schedules_list = '';
     self.full_schedules_list = '';
     self.update_schedules_list();
Esempio n. 9
0
class SlaveReceiver(Thread):
    def __init__(self, connection, hostname, daemon):
        """
        Threaded class for reading from a slave and send the data to the treatment function
        """
        Thread.__init__(self);
        self.connection = connection;
        self.daemon = daemon;
        self.connected_host = hostname;
        self.sql = MasterSql();

    def run(self):
        """
        Thread run function overload
        """
        res = self.sql.mysql_handler_personnal_query('SELECT serial, secretkey FROM daemon WHERE serial=\'' + self.connected_host + '\'');
        aes_key = '';
        for r in res:
            if r[0] == self.connected_host:
                aes_key = r[1];
                break;
        if aes_key == '':
            return None;
        data = self.connection.recv(MasterDaemon.MAX_DATA_LENGTH);
        decrypt_IV = data[:16].decode();
        decode_obj = AES.new(aes_key, AES.MODE_CBC, decrypt_IV);
        data2 = decode_obj.decrypt(data[16:]).decode();
        flag = False;
        obj = data2;
        self.daemon.parse_data(obj, self.connection);
Esempio n. 10
0
 def __init__(self, daemon):
     self.logger = Logger(False, LOG_FILE);
     self.logger.debug('Init CalcLogs');
     self.sql = MasterSql();
     self.daemon = daemon;
     self.devices_list = {};
     self.devices_list_update();
Esempio n. 11
0
class Smartcommand:

    def __init__(self, daemon, smartcmd_id = 0):
        self.logger = Logger(False, LOG_FILE);
        self.logger.info('Started SMARTCMD');
        self.smartcmd_id = smartcmd_id;
        self.sql = MasterSql();
        self.daemon = daemon;

    def launch_smartcmd(self, json_obj, connection):
        if (self.smartcmd_id == 0):
            self.logger.error('Invalid Smartcommand');
            return;

        query = 'SELECT room_device_id, option_id, option_value, time_lapse FROM smartcommand_elems WHERE smartcommand_id ="'+ str(self.smartcmd_id) +'" ORDER BY exec_id';
        res = self.sql.mysql_handler_personnal_query(query);
        delay_color = 0;
        for r in res:
            obj = {};
            obj['sync'] = 0;
            data = {};
            data['room_device_id'] = r[0];
            data['option_id'] = r[1];
            data['value'] = r[2];
            obj['data'] = data;
            obj['packet_type'] = 'smartcmd_launch';
            delay = r[3];
            if (data['option_id'] ==  392 or data['option_id'] ==  393 or data['option_id'] ==  394):
                delay_color = delay_color + 1;
            if (delay > 0 and delay_color <= 1):
                time.sleep(delay);
            if (delay_color >= 3):
                delay_color = 0;
            self.daemon.send_to_device(obj, connection);
Esempio n. 12
0
 def __init__(self, daemon):
     Thread.__init__(self);
     self.logger = Logger(False, LOG_FILE);
     self.sql = MasterSql();
     self.daemon = daemon;
     self.scenarios_list = {};
     self.update_scenarios_list();
Esempio n. 13
0
class Scenario:

    def __init__(self, daemon):
        self.logger = Logger(False, LOG_FILE);
        self.sql = MasterSql();
        self.daemon = daemon;
        self.scenarios_list = {};
        self.update_scenarios_list();

    def get_scenarios_tab(self, scenarios):
        scenarios_tab = {};
        self.logger.debug('\n\nGETTING SCENARIOS TAB\n');
        for d in scenarios:
            scHash = str(d[4])+'_'+str(d[5])
            if (scHash not in scenarios_tab):
                scenarios_tab[scHash] = [];
            scenarios_tab[scHash].append(d)
        return scenarios_tab;
    
    def update_scenarios_list(self):
        self.logger.debug('UPDATING SCENARIOS');

        query = ('SELECT id_scenario, trigger_events_conditions.id_trigger, id_schedule, '
                 'id_smartcmd, trigger_events_conditions.room_device_id, id_option '
                 'FROM trigger_events_conditions '
                 'JOIN scenarios_list '
                 'ON trigger_events_conditions.id_trigger=scenarios_list.id_trigger '
                 'WHERE activated = 1 && scenarios_list.id_trigger IS NOT NULL '
                 'ORDER BY id_scenario');
        scenarios_list = self.sql.mysql_handler_personnal_query(query);
        
        self.logger.debug('S LIST = ' + str(scenarios_list) + '\n');
        self.scenarios_list = self.get_scenarios_tab(scenarios_list);
        self.logger.debug('S TAB = ' + str(self.scenarios_list) + '\n\n\n');
        
    def check_all_scenarios(self, global_state, trigger, schedule, connection, doList):
        self.logger.debug('CHECKING ALL SCENARIOS');
        self.logger.debug('SCENARIOS LIST = ');
        self.logger.debug(self.scenarios_list);
        self.logger.debug('\n');
        for do in doList:
            slist = self.scenarios_list[str(do[1])+'_'+str(do[0])];
            self.logger.debug('SLIST = ');
            self.logger.debug(slist);
            for scenario in slist:
                self.logger.error(scenario);
                self.logger.debug('Scenario : ' + str(scenario) + '\n\n');
                if trigger.test_trigger(scenario[1], global_state) == 1:
                    self.logger.debug('Trigger OK');
                    if (scenario[2] is None or
                        scenario[2] is not None and schedule.test_schedule(scenario[2]) ==  1):
                        self.launch_scenario(scenario[3], connection);
    
    def launch_scenario(self, id_smartcmd, connection):
        self.logger.debug('LAUNCH !!!');
        jsonString = json.JSONEncoder().encode({
            "data": id_smartcmd
        });
        data = json.JSONDecoder().decode(jsonString);
        self.daemon.smartcmd_launch(data, connection);
Esempio n. 14
0
class EnOceanManager:
    """
    KNX management class
    """
    def __init__(self, slave_keys):
        self.logger = Logger(DEBUG_MODE, LOG_FILE);
        self.sql = MasterSql();
        self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
        self.aes_slave_keys = slave_keys;
        self.functions_transform = {
              0: utils.convert_none,
              4: utils.eno_onoff
        };
    
    def update_room_device_option(self, daemon_id, json_obj):
        """
        Update of the table room_device_option with EnOcean value
        """
        query  = "SELECT room_device_option.option_id, room_device.room_device_id, addr_plus, function_answer, room_device_option.dpt_id ";
        query += "FROM room_device_option ";
        query += "JOIN room_device ON room_device_option.room_device_id=room_device.room_device_id ";
        query += "JOIN dpt_optiondef ON dpt_optiondef.option_id=room_device_option.option_id AND ";
        query += "dpt_optiondef.protocol_id=room_device.protocol_id AND dpt_optiondef.dpt_id=room_device_option.dpt_id ";
        query += "WHERE daemon_id=" + str(daemon_id) + " AND room_device_option.addr=\"";
        query += str(json_obj['src_addr']) + "\"";
        res = self.sql.mysql_handler_personnal_query(query);
        result = []
        
        if len(res) == 0:
            query  = "SELECT room_device_option.option_id, room_device.room_device_id, addr_plus, function_answer, room_device_option.dpt_id ";
            query += "FROM room_device_option ";
            query += "JOIN room_device ON room_device_option.room_device_id=room_device.room_device_id ";
            query += "JOIN dpt_optiondef ON dpt_optiondef.option_id=room_device_option.option_id AND ";
            query += "dpt_optiondef.protocol_id=room_device.protocol_id AND dpt_optiondef.dpt_id=room_device_option.dpt_id ";
            query += "WHERE daemon_id=" + str(daemon_id) + " AND  room_device_option.addr_plus=\"";
            query += str(json_obj['src_addr']) + "\"";
            res = self.sql.mysql_handler_personnal_query(query);
        
        for r in res:
            val = self.functions_transform[r[3]](int(json_obj['value']), r[4]);
            if val is not None:
                result.append(r)
                up = "UPDATE room_device_option SET opt_value=\"" + str(val)
                up += "\" WHERE room_device_id=" + str(r[1]) + " AND option_id=\"" + str(r[0]) + "\"";
                self.sql.mysql_handler_personnal_query(up);
        return result
Esempio n. 15
0
 def __init__(self, slave_keys):
     self.logger = Logger(DEBUG_MODE, LOG_FILE);
     self.sql = MasterSql();
     self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
     self.aes_slave_keys = slave_keys;
     self.functions_transform = {
           0: utils.convert_none,
           4: utils.eno_onoff
     };
Esempio n. 16
0
 def __init__(self, connection, hostname, daemon):
     """
     Threaded class for reading from a slave and send the data to the treatment function
     """
     Thread.__init__(self);
     self.connection = connection;
     self.daemon = daemon;
     self.connected_host = hostname;
     self.sql = MasterSql();
Esempio n. 17
0
 def __init__(self, connection, hostname, daemon):
     ## Logger object for formatting and printing logs
     self.logger = Logger(log_flag, LOG_FILE);
     Thread.__init__(self);
     ## Connection object for communications
     self.connection = connection;
     ## Instance of Master daemon
     self.daemon = daemon;
     ## The hostname of the system
     self.connected_host = hostname.upper();
     ## SQL object for managing master database
     self.sql = MasterSql();
     ## Username for login to the database
     self.db_username = daemon.db_username;
     ## Password for login to the database
     self.db_passwd = daemon.db_passwd;
     ## Database name for login to the database
     self.db_dbname = daemon.db_dbname;
Esempio n. 18
0
 def __init__(self, daemon):
     ## Logger object for formatting and printing logs
     self.logger = Logger(False, LOG_FILE);
     ## SQL object for managing database
     self.sql = MasterSql();
     ## Instance of the slave daemon
     self.daemon = daemon;
     ## Trigger list
     self.triggers_list = '';
     self.update_triggers_list();
Esempio n. 19
0
 def __init__(self, daemon):
     Thread.__init__(self)
     ## Logger object for formatting and printing logs
     self.logger = Logger(False, LOG_FILE)
     ## SQL object for managing slave daemon database
     self.sql = MasterSql()
     ## Instance of the slave daemon
     self.daemon = daemon
     ## List of scenarios
     self.scenarios_list = {}
     self.update_scenarios_list()
Esempio n. 20
0
class SlaveReceiver(Thread):

    ## The constructor.
    #
    # @param connection Connection object used to communicate.
    # @param hostname The hostname.
    # @param daemon The MasterDaemon with the adapted treatment functions.
    def __init__(self, connection, hostname, daemon):
        ## Logger object for formatting and printing logs
        self.logger = Logger(log_flag, LOG_FILE);
        Thread.__init__(self);
        ## Connection object for communications
        self.connection = connection;
        ## Instance of Master daemon
        self.daemon = daemon;
        ## The hostname of the system
        self.connected_host = hostname.upper();
        ## SQL object for managing master database
        self.sql = MasterSql();
        ## Username for login to the database
        self.db_username = daemon.db_username;
        ## Password for login to the database
        self.db_passwd = daemon.db_passwd;
        ## Database name for login to the database
        self.db_dbname = daemon.db_dbname;

    ## Thread run function overload.
    #
    # @return None
    def run(self):
        ## Database handler to query master database
        self.db = MysqlHandler(self.db_username, self.db_passwd, self.db_dbname);
        self.logger.error('SELECT serial, secretkey, daemon_id FROM daemon WHERE serial=\''+self.connected_host+'\'');
        res = self.sql.mysql_handler_personnal_query('SELECT serial, secretkey, daemon_id FROM daemon WHERE serial=\''+self.connected_host+'\'', self.db);
        aes_key = '';
        for r in res:
            if r[0] == self.connected_host:
                aes_key = r[1];
                daemon_id = r[2];
                break;
        if not aes_key:
            return None;
        try:
            data = self.connection.recv(MasterDaemon.MAX_DATA_LENGTH);
            decrypt_IV = data[:16].decode();
            decode_obj = AES.new(aes_key, AES.MODE_CBC, decrypt_IV);
            data2 = decode_obj.decrypt(data[16:]).decode();
            flag = False;
            obj = data2;
            self.daemon.parse_data(obj, self.connection, daemon_id, self.db);
        except Exception as e:
            self.logger.error(e);
        self.db.close();
Esempio n. 21
0
 def __init__(self, log_flag):
     self.logger = Logger(log_flag, LOG_FILE);
     self.logger.info('Started Greenleaf Master Daemon');
     self.d3config = {};
     self.aes_slave_keys = {};
     self.aes_master_key = None;
     self.connected_clients = {};
     self.sql = MasterSql();
     self._parser = DaemonConfigParser(MASTER_CONF_FILE);
     self.get_aes_slave_keys();
     self.reload_camera(None, None);
     self.scanner = Scanner(HOSTS_CONF);
     self.scanner.scan(False);
     self.hostlist = self.scanner._HostList;
     self.sql.insert_hostlist_in_db(self.scanner._HostList);
     self.knx_manager = KNXManager(self.aes_slave_keys);
     self.reload_d3config(None, None);
     self.protocol_function = {
         PROTOCOL_KNX        : KNXManager.protocol_knx,
         PROTOCOL_ENOCEAN    : self.protocol_enocean,
         PROTOCOL_IP         : self.protocol_ip
     };
     self.upnp_function = {
         UPNP_PLAY           : self.upnp_set_play,
         UPNP_PAUSE          : self.upnp_set_pause,
         UPNP_NEXT           : self.upnp_set_next,
         UPNP_PREVIOUS       : self.upnp_set_prev,
         UPNP_STOP           : self.upnp_set_stop,
         UPNP_VOLUME_UP      : self.upnp_set_volume_up,
         UPNP_VOLUME_DOWN    : self.upnp_set_volume_down,
         UPNP_SET_VOLUME     : self.upnp_set_volume
     };
     self.enocean_function = {};
     self.data_function = {
         DATA_MONITOR_KNX            	  : self.monitor_knx,
         DATA_MONITOR_IP             	  : self.monitor_ip,
         DATA_MONITOR_ENOCEAN        	  : self.monitor_enocean,
         DATA_MONITOR_BLUETOOTH      	  : self.monitor_bluetooth,
         DATA_KNX_READ               	  : self.knx_read,
         DATA_KNX_WRITE_S            	  : self.knx_write_short,
         DATA_KNX_WRITE_L            	  : self.knx_write_long,
         DATA_SEND_TO_DEVICE         	  : self.send_to_device,
         DATA_CRON_UPNP             		  : self.cron_upnp,
         DATA_SEND_MAIL              	  : self.send_mail,
         DATA_CHECK_SLAVE            	  : self.check_slave,
         DATA_RELOAD_CAMERA          	  : self.reload_camera,
         DATA_RELOAD_D3CONFIG        	  : self.reload_d3config,
         DATA_BACKUP_DB_CREATE_LOCAL       : self.backup_db_create_local,
         DATA_BACKUP_DB_REMOVE_LOCAL       : self.backup_db_remove_local,
         DATA_BACKUP_DB_LIST_LOCAL         : self.backup_db_list_local,
         DATA_BACKUP_DB_RESTORE_LOCAL      : self.backup_db_restore_local,
         DATA_UPDATE                 	  : self.update
     };
Esempio n. 22
0
 def __init__(self, slave_keys):
     self.knx_function = {
         OPTION_ON_OFF       : self.send_knx_write_short_to_slave,
         OPTION_VAR          : self.send_knx_write_long_to_slave,
         OPTION_UP_DOWN      : self.send_knx_write_short_to_slave,
         OPTION_OPEN_CLOSE   : self.send_knx_write_short_to_slave,
         OPTION_STOP_UP_DOWN : self.send_knx_write_short_to_slave,
         OPTION_TEMPERATURE_W: self.send_knx_write_temp
     };
     self.sql = MasterSql();
     self._parser = DaemonConfigParser('/etc/greenleaf/master.conf');
     self.aes_slave_keys = slave_keys;
Esempio n. 23
0
 def __init__(self, daemon):
     ## Logger object for formatting and printing logs
     self.logger = Logger(False, LOG_FILE)
     ## SQL object for managing slave database
     self.sql = MasterSql()
     ## Instance of the slave daemon
     self.daemon = daemon
     ## Schedule list
     self.schedules_list = ""
     ## Full schedule list
     self.full_schedules_list = ""
     self.update_schedules_list(0)
Esempio n. 24
0
 def __init__(self, slave_keys):
     ## Logger object for formatting and printing
     self.logger = Logger(DEBUG_MODE, LOG_FILE);
     ## SQL manager for the master daemon
     self.sql = MasterSql();
     self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
     ## Object containing the AES keys for encrypted communications
     self.aes_slave_keys = slave_keys;
     ## Array containing functions associated with IDs
     self.functions_transform = {
           0: utils.convert_none,
           4: utils.eno_onoff
     };
Esempio n. 25
0
class Scenario(Thread):

    def __init__(self, daemon):
        Thread.__init__(self);
        self.logger = Logger(False, LOG_FILE);
        self.sql = MasterSql();
        self.daemon = daemon;
        self.scenarios_list = {};
        self.update_scenarios_list();

    def setValues(self, global_state, trigger, schedule, connection, doList):
        self.global_state = global_state;
        self.trigger = trigger;
        self.schedule = schedule;
        self.connection = connection;
        self.doList = doList;

    def run(self):
        check_all_scenarios(self);

    def get_scenarios_tab(self, scenarios):
        scenarios_tab = {};
        self.logger.debug('\n\nGETTING SCENARIOS TAB\n');
        for d in scenarios:
            scHash = ''.join([str(d[4]), '_', str(d[5])]);
            if scHash not in scenarios_tab:
                scenarios_tab[scHash] = [];
            scenarios_tab[scHash].append(d)
        return scenarios_tab;
    
    def update_scenarios_list(self, db=0):
        self.logger.debug('UPDATING SCENARIOS');
        query = ''.join(['SELECT id_scenario, trigger_events_conditions.id_trigger, id_schedule, ',
                 'id_smartcmd, trigger_events_conditions.room_device_id, id_option ',
                 'FROM trigger_events_conditions ',
                 'JOIN scenarios_list ',
                 'ON trigger_events_conditions.id_trigger=scenarios_list.id_trigger ',
                 'WHERE activated = 1 && scenarios_list.id_trigger IS NOT NULL ',
                 'ORDER BY id_scenario']);
        scenarios_list = self.sql.mysql_handler_personnal_query(query, db);
        self.logger.debug('S LIST = '+str(scenarios_list)+'\n');
        self.scenarios_list = self.get_scenarios_tab(scenarios_list);
        self.logger.debug('S TAB = '+str(self.scenarios_list)+'\n\n\n');
    
    def launch_scenario(self, id_smartcmd, connection):
        self.logger.debug('LAUNCH !!!');
        jsonString = json.JSONEncoder().encode({
            "data": id_smartcmd
        });
        data = json.JSONDecoder().decode(jsonString);
        self.daemon.smartcmd_launch(data, connection);
Esempio n. 26
0
class Smartcommand:

    def __init__(self, daemon, smartcmd_id = 0):
        self.logger = Logger(False, LOG_FILE);
        self.logger.debug('Started SMARTCMD');
        self.smartcmd_id = smartcmd_id;
        self.sql = MasterSql();
        self.daemon = daemon;

    def launch_smartcmd(self, json_obj, connection):
        if (self.smartcmd_id == 0):
            self.logger.error('Invalid Smartcommand');
            return;
        tab_except_http = [356, 357, 358, 359, 360, 361];
        query = ('SELECT smartcommand_elems.room_device_id, option_value, '
                 '       smartcommand_elems.option_id, time_lapse, opt_value, '
                 '       device_id '
                 'FROM smartcommand_elems '
                 'JOIN room_device_option ON room_device_option.room_device_id=smartcommand_elems.room_device_id AND room_device_option.option_id=smartcommand_elems.option_id '
                 'JOIN room_device ON room_device.room_device_id=smartcommand_elems.room_device_id '
                 'WHERE smartcommand_id ="'+ str(self.smartcmd_id) +'" '
                 'ORDER BY exec_id');
        res = self.sql.mysql_handler_personnal_query(query);
        delay_color = 0;
        for r in res:
            obj = {};
            obj['sync'] = 0;
            data = {};
            data['room_device_id'] = r[0];
            data['value'] = r[1];
            data['option_id'] = r[2];
            data['action'] = r[1];
            if r[5] == 86:
                data['value'] = r[4]
            elif data['option_id'] in tab_except_http:
                data['value'] = '';
            obj['data'] = data;
            obj['packet_type'] = 'smartcmd_launch';
            delay = r[3];
            if (data['option_id'] ==  392 or data['option_id'] ==  393 or data['option_id'] ==  394):
                delay_color = delay_color + 1;
            if (delay > 0 and delay_color <= 1):
                time.sleep(delay);
            if (delay_color >= 3):
                delay_color = 0;
            self.daemon.send_to_device(obj, connection);
Esempio n. 27
0
 def __init__(self, daemon, smartcmd_id=0):
     Thread.__init__(self)
     ## Logger object for formatting and printing logs
     self.logger = Logger(LOG_FLAG, LOG_FILE)
     self.logger.debug('Started SMARTCMD')
     ## The ID of the smart command
     self.smartcmd_id = smartcmd_id
     ## SQL object for managing database
     self.sql = MasterSql()
     ## Instance of the slave daemon
     self.daemon = daemon
     ## Array of option code for which the data is not important
     self.tab_except_http = [356, 357, 358, 359, 360, 361]
     ## Username to connect to the database
     self.db_username = daemon.db_username
     ## Password to connect to the database
     self.db_passwd = daemon.db_passwd
     ## Database name on which connect
     self.db_dbname = daemon.db_dbname
Esempio n. 28
0
 def __init__(self, slave_keys):
     self.knx_function = {
         OPTION_ON_OFF       : self.send_knx_write_short_to_slave,
         OPTION_VAR          : self.send_knx_write_long_to_slave,
         OPTION_UP_DOWN      : self.send_knx_write_short_to_slave,
         OPTION_OPEN_CLOSE   : self.send_knx_write_short_to_slave,
         OPTION_STOP_UP_DOWN : self.send_knx_write_short_to_slave,
         OPTION_SPEED_FAN_0  : self.send_knx_write_speed_fan,
         OPTION_SPEED_FAN_1  : self.send_knx_write_speed_fan,
         OPTION_SPEED_FAN_2  : self.send_knx_write_speed_fan,
         OPTION_SPEED_FAN_3  : self.send_knx_write_speed_fan,
         OPTION_SPEED_FAN_4  : self.send_knx_write_speed_fan,
         OPTION_SPEED_FAN_5  : self.send_knx_write_speed_fan,
         OPTION_SPEED_FAN_6  : self.send_knx_write_speed_fan,
         OPTION_TEMPERATURE_W: self.send_knx_write_temp,
         OPTION_COLOR_R      : self.send_knx_write_long_to_slave,
         OPTION_COLOR_G      : self.send_knx_write_long_to_slave,
         OPTION_COLOR_B      : self.send_knx_write_long_to_slave,
         OPTION_COLOR_W      : self.send_knx_write_long_to_slave
     };
     self.logger = Logger(True, LOG_FILE);
     self.sql = MasterSql();
     self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
     self.aes_slave_keys = slave_keys;
Esempio n. 29
0
class Scenario(Thread):

    ## The constructor.
    #
    # @param daemon The daemon which instanciated this class.
    def __init__(self, daemon):
        Thread.__init__(self)
        ## Logger object for formatting and printing logs
        self.logger = Logger(False, LOG_FILE)
        ## SQL object for managing slave daemon database
        self.sql = MasterSql()
        ## Instance of the slave daemon
        self.daemon = daemon
        ## List of scenarios
        self.scenarios_list = {}
        self.update_scenarios_list()

    ## Sets values of a scenario.
    #
    # @param global_state The new global state.
    # @param trigger The new trigger.
    # @param schedule The new schedule.
    # @param connection The new connection.
    # @param doList The new doList.
    # @return None
    def setValues(self, global_state, trigger, schedule, connection, doList):
        ## Global state object
        self.global_state = global_state
        ## The trigger for the scenario
        self.trigger = trigger
        ## The schedule for the scenario
        self.schedule = schedule
        ## The connection to something
        self.connection = connection
        ## The do list
        self.doList = doList

    ## Starts the thread.
    #
    # @return None
    def run(self):
        check_all_scenarios(self)

    ## Gets scenarios from a list.
    #
    # @param scenarios The scenarios list.
    #
    # @return An array of scenarios.
    def get_scenarios_tab(self, scenarios):
        scenarios_tab = {}
        self.logger.debug('\n\nGETTING SCENARIOS TAB\n')
        for d in scenarios:
            scHash = ''.join([str(d[4]), '_', str(d[5])])
            if scHash not in scenarios_tab:
                scenarios_tab[scHash] = []
            scenarios_tab[scHash].append(d)
        return scenarios_tab

    ## Updates the list of scenarios in database.
    #
    # @param db The database handler (default 0).
    # @return None
    def update_scenarios_list(self, db=0):
        self.logger.debug('UPDATING SCENARIOS')
        query = ''.join([
            'SELECT id_scenario, trigger_events_conditions.id_trigger, id_schedule, ',
            'id_smartcmd, trigger_events_conditions.room_device_id, id_option ',
            'FROM trigger_events_conditions ', 'JOIN scenarios_list ',
            'ON trigger_events_conditions.id_trigger=scenarios_list.id_trigger ',
            'WHERE activated = 1 && scenarios_list.id_trigger IS NOT NULL ',
            'ORDER BY id_scenario'
        ])
        scenarios_list = self.sql.mysql_handler_personnal_query(query, db)
        self.logger.debug('S LIST = ' + str(scenarios_list) + '\n')
        self.scenarios_list = self.get_scenarios_tab(scenarios_list)
        self.logger.debug('S TAB = ' + str(self.scenarios_list) + '\n\n\n')

    ## Starts a scenario.
    #
    # @param id_smartcmd ID of the smartcommand launching the scenario.
    # @param connection The connection used to communicate.
    # @return None
    def launch_scenario(self, id_smartcmd, connection):
        self.logger.debug('LAUNCH !!!')
        jsonString = json.JSONEncoder().encode({"data": id_smartcmd})
        data = json.JSONDecoder().decode(jsonString)
        self.daemon.smartcmd_launch(data, connection)
Esempio n. 30
0
class EnOceanManager:

    ## The constructor.
    #
    # @param slave_keys The aes keys of the slaves.
    def __init__(self, slave_keys):
        ## Logger object for formatting and printing
        self.logger = Logger(DEBUG_MODE, LOG_FILE)
        ## SQL manager for the master daemon
        self.sql = MasterSql()
        self._parser = DaemonConfigParser('/etc/domoleaf/master.conf')
        ## Object containing the AES keys for encrypted communications
        self.aes_slave_keys = slave_keys
        ## Array containing functions associated with IDs
        self.functions_transform = {
            0: utils.convert_none,
            4: utils.eno_onoff
        }

    ## Updates the table room_device_option with EnOcean values.
    #
    # @param daemon_id The ID of the daemon.
    # @param json_obj JSON object containing the source address of the EnOcean device.
    # @param db The database handler.
    #
    # @return The result of the query.
    def update_room_device_option(self, daemon_id, json_obj, db):
        query = ''.join([
            "SELECT room_device_option.option_id, room_device.room_device_id, addr_plus, function_answer, room_device_option.dpt_id ",
            "FROM room_device_option JOIN room_device ON room_device_option.room_device_id=room_device.room_device_id ",
            "JOIN dpt_optiondef ON dpt_optiondef.option_id=room_device_option.option_id AND ",
            "dpt_optiondef.protocol_id=room_device.protocol_id AND dpt_optiondef.dpt_id=room_device_option.dpt_id ",
            "WHERE daemon_id=",
            str(daemon_id), " AND room_device_option.addr=\"",
            str(json_obj['src_addr']), "\""
        ])
        res = self.sql.mysql_handler_personnal_query(query, db)
        result = []
        append = result.append
        if not res:
            query = ''.join([
                "SELECT room_device_option.option_id, room_device.room_device_id, addr_plus, function_answer, room_device_option.dpt_id ",
                "FROM room_device_option JOIN room_device ON room_device_option.room_device_id=room_device.room_device_id ",
                "JOIN dpt_optiondef ON dpt_optiondef.option_id=room_device_option.option_id AND ",
                "dpt_optiondef.protocol_id=room_device.protocol_id AND dpt_optiondef.dpt_id=room_device_option.dpt_id ",
                "WHERE daemon_id=",
                str(daemon_id), " AND  room_device_option.addr_plus=\"",
                str(json_obj['src_addr']), "\""
            ])
            res = self.sql.mysql_handler_personnal_query(query, db)
        for r in res:
            val = self.functions_transform[r[3]](int(json_obj['value']), r[4])
            if val is not None:
                append(r)
                up = ''.join([
                    "UPDATE room_device_option SET opt_value=\"",
                    str(val), "\" WHERE room_device_id=",
                    str(r[1]), " AND option_id=\"",
                    str(r[0]), "\""
                ])
                self.sql.mysql_handler_personnal_query(up, db)
        return result
Esempio n. 31
0
class KNXManager:

    ## The constructor.
    #
    # @param slave_keys Array containing the AES keys of all the slaves.
    # @return None
    def __init__(self, slave_keys):
        ## Logger object for formatting and printing logs
        self.logger = Logger(DEBUG_MODE, LOG_FILE);
        ## SQL object for managing database
        self.sql = MasterSql();
        self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
        ## Object containing AES keys for encrypted communications
        self.aes_slave_keys = slave_keys;

    ## Updates room_device_option table in database to set new values of the device described by json_obj.
    #
    # @param daemon_id The ID of a slave daemon.
    # @param json_obj JSON object containing the values to update.
    # @param db The database handler.
    #
    # @return The result of the query.
    def update_room_device_option(self, daemon_id, json_obj, db):
        if int(json_obj['type']) == KNX_RESPONSE:
            return self.sql.update_room_device_option_resp(json_obj, daemon_id, db);
        elif int(json_obj['type']) == KNX_WRITE_SHORT:
            return self.sql.update_room_device_option_write_short(json_obj, daemon_id, db);
        elif int(json_obj['type']) == KNX_WRITE_LONG:
            return self.sql.update_room_device_option_write_long(json_obj, daemon_id, db);

    ## Sends a JSON object to a slave daemon.
    #
    # @param json_str The data to send.
    # @param sock The socket used to send the data.
    # @param hostname The hostname of the slave daemon.
    # @param aes_key The AES key of the slave daemon to encrypt data.
    # @return None
    def send_json_obj_to_slave(self, json_str, sock, hostname, aes_key):
        hostname_key = '';
        if '.' in hostname:
            hostname_key = hostname.split('.')[0];
        else:
            hostname_key = hostname;
        AES.key_size = 32;
        aes_IV = AESManager.get_IV();
        encode_obj = AES.new(aes_key, AES.MODE_CBC, aes_IV);
        spaces = 16 - len(json_str) % 16;
        data2 = encode_obj.encrypt(json_str + (spaces * ' '));
        sock.send(bytes(aes_IV, 'utf-8') + data2);

    ## Changes the speed value of a fan.
    #
    # @param json_obj JSON object containing the values to write.
    # @param dev Object containing informations about the device.
    # @param hostname The hostname of the slave to who send the packet.
    # @return None
    def send_knx_write_speed_fan(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        sock = socket.create_connection((hostname, port));
        if not port:
            sys.exit(4);
        if json_obj['data']['value'] == '1':
            query = ''.join(['SELECT option_id, addr, dpt_id FROM room_device_option WHERE room_device_id=',
                           str(dev['room_device_id']),
                           ' AND option_id IN(400, 401, 402, 403, 404, 405, 406) AND status=1']);
            res = self.sql.mysql_handler_personnal_query(query);
            for line in res:
                if str(line[2]) == "51" and str(line[0]) == str(json_obj['data']['option_id']):
                    val = str(line[0]).split('40')[1];
                    json_str = json.JSONEncoder().encode(
                        {
                            "packet_type": "knx_write_long",
                            "addr_to_send": line[1],
                            "value": val
                        }
                    );
                    self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
                    return;
                elif str(line[2]) == "2" and str(line[0]) != str(json_obj['data']['option_id']):
                    json_str = json.JSONEncoder().encode(
                        {
                            "packet_type": "knx_write_short",
                            "addr_to_send": line[1],
                            "value": "0"
                        }
                    );
                    self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_short",
                "addr_to_send": str(dev['addr_dst']),
                "value": json_obj['data']['value']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();

    ## Converts absolute value of temperature (Celsius) in 2 hexadecimal values for sending to KNX device.
    #
    # @param json_obj JSON object containing the values to write.
    # @param dev Object describing the KNX device to who send the packet.
    # @param hostname The hostname of the slave daemon to who send the packet.
    # @return None
    def send_knx_write_temp(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        val_str = json_obj['data']['value'];
        if ',' in val_str:
            val_str = val_str.replace(',', '.')
        value = utils.convert_temperature_reverse(float(val_str));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_temp",
                "addr_to_send": str(dev['addr_dst']),
                "value": value[0] + ' ' + value[1]
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();

    ## Builds a "long write" request and sends it to "hostname".
    #
    # @param json_obj JSON object containing the new values.
    # @param dev The device to who send the request.
    # @param hostname The slave daemon to who send the packet.
    # @return None
    def send_knx_write_long_to_slave(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_long",
                "addr_to_send": str(dev['addr_dst']),
                "value": hex(int(json_obj['data']['value']))
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();

    ## Builds a "short read" request and sends it to "hostname".
    #
    # @param json_obj JSON object containing the new values.
    # @param dev The device to who send the request.
    # @param hostname The hostname of the slave daemon to who send the packet.
    # @return None
    def send_knx_write_short_to_slave(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_short",
                "addr_to_send": str(dev['addr_dst']),
                "value": json_obj['data']['value']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();

    ## Changes the value to send when it is supposed to be inverted and sends the packet to the slave.
    #
    # @param json_obj JSON object to change before sending.
    # @param dev The device to who send the request.
    # @param hostname The hostname of the slave daemon to who send the packet.
    # @return None.
    def send_knx_write_short_to_slave_reverse(self, json_obj, dev, hostname):
        json_obj['data']['value'] = (int(json_obj['data']['value']) + 1) % 2;
        self.send_knx_write_short_to_slave(json_obj, dev, hostname);
        
    ## Builds a "short read" request and sends it to the slave "hostname".
    #
    # @param hostname The slave daemon to who send the read request.
    # @param json_obj JSON object containing the data to send.
    # @return None
    def send_knx_read_request_to_slave(self, hostname, json_obj):
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_read_request",
                "addr_to_read": json_obj['data']['addr']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();

    ## Asks to send a "on" packet to a device.
    #
    # @param json_obj JSON object containing the new values.
    # @param dev The KNX device.
    # @param hostname The hostname of the slave daemon.
    # @return None
    def send_on(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_short",
                "addr_to_send": str(dev['addr_dst']),
                "value": "1"
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();
        return;

    ## Asks to send a "off" packet to a device.
    #
    # @param json_obj JSON object containing the new values.
    # @param dev The KNX device.
    # @param hostname The hostname of the slave daemon.
    # @return None
    def send_off(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_short",
                "addr_to_send": str(dev['addr_dst']),
                "value": "0"
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();
        return;

    ## Sends the new value of the temperature to thermostat.
    #
    # @param json_obj JSON object containing the new values.
    # @param dev The KNX device.
    # @param hostname The hostname of the slave daemon.
    # @return None
    def send_to_thermostat(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        if json_obj['data']['option_id'] == '412':
            val = 1;
        elif json_obj['data']['option_id'] == '413':
            val = 2;
        elif json_obj['data']['option_id'] == '414':
            val = 4;
        elif json_obj['data']['option_id'] == '415':
            val = 8;
        elif json_obj['data']['option_id'] == '416':
            val = 16;
        elif json_obj['data']['option_id'] == '417':
            val = 32;
        else:
            val = 0
        if val > 0:
            json_str = json.JSONEncoder().encode(
                {
                    "packet_type": "knx_write_long",
                    "addr_to_send": hex(int(dev['addr_dst'])),
                    "value": val
                }
            );
            sock = socket.create_connection((hostname, port));
            self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
            sock.close();
            return;

    ## Sends the new mode of the air conditioner.
    #
    # @param json_obj JSON object containing the new values.
    # @param dev The KNX device.
    # @param hostname The hostname of the slave daemon.
    # @return None
    def send_clim_mode(self, json_obj, dev, hostname):
        if json_obj['data']['option_id'] == '425': #Auto
            val = 0
        elif json_obj['data']['option_id'] == '426': #Heat
            val = 1
        elif json_obj['data']['option_id'] == '427': #Morning Warmup
            val = 2
        elif json_obj['data']['option_id'] == '428': #Cool
            val = 3
        elif json_obj['data']['option_id'] == '429': #Night Purge
            val = 4
        elif json_obj['data']['option_id'] == '430': #Precool
            val = 5
        elif json_obj['data']['option_id'] == '431': #Off
            val = 6
        elif json_obj['data']['option_id'] == '432': #Test
            val = 7
        elif json_obj['data']['option_id'] == '433': #Emergency Heat
            val = 8
        elif json_obj['data']['option_id'] == '434': #Fan only
            val = 9
        elif json_obj['data']['option_id'] == '435': #Free Cool
            val = 10
        elif json_obj['data']['option_id'] == '436': #Ice
            val = 11
        else:
            val = -1
        if val >= 0:
            json_str = json.JSONEncoder().encode(
                {
                    "packet_type": "knx_write_long",
                    "addr_to_send": str(dev['addr_dst']),
                    "value":  hex(int(val))
                }
            );
            sock = socket.create_connection((hostname, port));
            self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
            sock.close();
            return;

    ## Sends a value converted in percentages.
    #
    # @param json_obj Not used here.
    # @param dev Object describing the KNX device.
    # @param hostname Hostname of the slave daemon to who sent the packet.
    # @return None
    def send_knx_write_percent(self, json_obj, dev, hostname):
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_long",
                "addr_to_send": str(dev['addr_dst']),
                "value": hex(int(255*int(json_obj['data']['value'])/100))
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
        sock.close();
Esempio n. 32
0
class Trigger:

    ## The constructor.
    #
    # @param daemon The daemon object which instanciated this class.
    def __init__(self, daemon):
        ## Logger object for formatting and printing logs
        self.logger = Logger(False, LOG_FILE)
        ## SQL object for managing database
        self.sql = MasterSql()
        ## Instance of the slave daemon
        self.daemon = daemon
        ## Trigger list
        self.triggers_list = ''
        self.update_triggers_list()

    ## Updates the trigger list.
    #
    # @param db The database handler (default 0).
    # @return None
    def update_triggers_list(self, db=0):
        self.logger.debug('Updating Triggers')
        query = (
            'SELECT trigger_events_list.id_trigger, '
            'trigger_events_conditions.room_device_id, '
            'trigger_events_conditions.id_option, trigger_events_conditions.operator, trigger_events_conditions.value '
            'FROM trigger_events_list '
            'JOIN trigger_events_conditions '
            'ON trigger_events_list.id_trigger = trigger_events_conditions.id_trigger '
            'ORDER BY trigger_events_list.id_trigger')
        res = self.sql.mysql_handler_personnal_query(query, db)
        self.triggers_list = res
        self.logger.debug(res)

    ## Retrieves the trigger informations from its ID.
    #
    # @param id_trigger ID of the trigger.
    #
    # @return Array containing trigger informations.
    def get_trigger_info(self, id_trigger):
        triggers_list = self.triggers_list
        trigger = []
        append = trigger.append
        for condition in triggers_list:
            if (condition[0] == id_trigger):
                append(condition)
        return trigger

    ## Tests all the conditions in a trigger from its ID.
    #
    # @param id_trigger The ID of the trigger.
    # @param global_state Global state.
    #
    # @return 1 if the conditions are verified, else 0.
    def test_trigger(self, id_trigger, global_state):
        trigger = self.get_trigger_info(id_trigger)
        res = True
        for condition in trigger:
            res = res and self.test_condition(condition, global_state)
        if res:
            return 1
        return 0

    ## Gets a device state.
    #
    # @param room_device_id ID of the device.
    # @param option_id Option ID of the device.
    # @param global_state Global state.
    #
    # @return The state of the device.
    def get_device_state(self, room_device_id, option_id, global_state):
        device_state = []
        for elem in global_state:
            if elem[0] == room_device_id and elem[1] == option_id:
                device_state = elem
                return device_state
        return device_state

    ## Tests the equivalence between the value of a device and the value of a condition.
    #
    # @param val_device Value to test.
    # @param val_condition Value compared.
    #
    # @return True if the values are equal, else False.
    def test_equ(self, val_device, val_condition):
        if (val_device == val_condition):
            return True
        return False

    ## Tests the superiority or the equivalence between the value of a device and the value of a condition.
    #
    # @param val_device Value to test.
    # @param val_condition Value compared.
    #
    # @return True if val_device >= val_condition, else False.
    def test_sup_equ(self, val_device, val_condition):
        val_device = float(val_device)
        val_condition = float(val_condition)
        if (val_device >= val_condition):
            return True
        return False

    ## Tests the inferiority or the equivalence between the value of a device and the value of a condition.
    #
    # @param val_device Value to test.
    # @param val_condition Value compared.
    #
    # @return True if val_device <= val_condition, else False.
    def test_inf_equ(self, val_device, val_condition):
        val_device = float(val_device)
        val_condition = float(val_condition)
        if (val_device <= val_condition):
            return True
        return False

    ## Tests multiple conditions.
    #
    # @param condition Condition to test.
    # @param global_state Global state.
    #
    # @return Function to test
    def test_condition(self, condition, global_state):
        device_state = self.get_device_state(condition[1], condition[2],
                                             global_state)
        if not device_state:
            self.logger.error('No Device State')
            return False
        self.logger.debug(device_state)
        functab = {
            "0": self.test_equ,
            "1": self.test_sup_equ,
            "2": self.test_inf_equ
        }
        return functab[str(condition[3])](device_state[2], condition[4])
Esempio n. 33
0
class CalcLogs:

    ## The constructor.
    #
    # @param daemon The slave daemon which initialized this class instance.
    def __init__(self, daemon):
        ## The logger used for formating and printing
        self.logger = Logger(False, LOG_FILE);
        self.logger.debug('Init CalcLogs');

        ## SQL manager
        self.sql = MasterSql();

        ## The instance of the slave daemon
        self.daemon = daemon;

        ## List of the devices
        self.devices_list = {};
        self.devices_list_update();

    ## Updates the device list.
    #
    # Queries the database to fetch room_device and room_device_option.
    # The result is stored in a class variable.
    #
    # @return none
    def devices_list_update(self):
        self.logger.debug('Updating Logs');
        query = ('SELECT room_device.daemon_id, room_device_option.addr_plus, room_device_option.addr, '
                 'room_device.room_device_id, room_device_option.option_id, room_device.name '
                 'FROM room_device '
                 'JOIN room_device_option '
                 'ON room_device.room_device_id = room_device_option.room_device_id '
                 'WHERE daemon_id IS NOT NULL '
                 'ORDER BY room_device_id');
        res = self.sql.mysql_handler_personnal_query(query);
        self.devices_list = self.get_tab_devices_list(res);

    ## Stores the device list in an array and returns it.
    #
    # @param res Array containing all informations about room_device and room_device_option.
    #
    # @return An array containing informations about the devices, with daemon_id as index.
    def get_tab_devices_list(self, res):
        tab = {};
        for r in res:
            daemon_id = r[0];
            addr_plus = r[1];
            addr = r[2];
            if daemon_id not in tab:
                tab[daemon_id] = {};
            if addr_plus:
                if daemon_id in tab and addr_plus not in tab[daemon_id]:
                    tab[daemon_id][addr_plus] = [];
                    r = r[3:];
                    tab[daemon_id][addr_plus].append(r);
            else:
                if daemon_id in tab and addr not in tab[daemon_id]:
                    tab[daemon_id][addr] = [];
                    r = r[3:];
                    tab[daemon_id][addr].append(r);
        return tab;

    ## Stores only the logs of specific devices.
    #
    # @return an array containing the logs.
    def get_only_good_logs(self, res):
        tab = [];
        tab_append = tab.append;
        self.logger.debug(self.devices_list);
        for r in res:
            if (r[1] in self.devices_list[r[0]]):
                self.logger.debug(r);
                log = [];
                log_append = log.append;
                log_append(r[2]);
                log_append(r[3]);
                log_append(self.devices_list[r[0]][r[1]][0][0]);
                log_append(self.devices_list[r[0]][r[1]][0][1]);
                log_append(r[4]);
                log_append(r[5]);
                log_append(r[1]);
                log_append(r[0]);
                tab_append(log);
        return tab;

    ## Gets the devices for which logs will be done.
    #
    # @param res Array containing all the room devices informations.
    #
    # @return An array containing the room devices for who the logs will be done.
    def get_good_time_range(self, res):
        end_tr = time.time() - TIME_BEFORE_TIME_TO_CALC - 1;
        init_tr = end_tr - TIME_RANGE_TO_CALC + 1;
        tab = [];
        append = tab.append;
        for r in res:
            if (r[0] <= end_tr):
                append(r);
        return (tab);

    ## Cuts the logs array.
    #
    # @param tab The array to cut.
    #
    # @return The cut dictionnary.
    def cut_tab(self, tab):
        cut_tab = {};
        cut_dict = {};
        for log in tab:
            device_id = log[2];
            option_id = log[3];
            if (device_id not in cut_tab):
                cut_tab[device_id] = {};
            if (option_id not in cut_tab[device_id]):
                cut_tab[device_id][option_id] = [];
            cut_tab[device_id][option_id].append(log);
        for device in cut_tab:
            cut_dict[device] = {};
            for option in cut_tab[device]:
                cut_dict[device][option] = [];
                for log in cut_tab[device][option]:
                    cut_dict[device][option].append(log);
        return cut_dict;

    ## Calculates average values of some data logged.
    #
    # @param dictlogs Array containing the logs.
    #
    # @return An array containing the average values calculated.
    def calc_average_values(self, dictlogs):
        dictaverage = {};
        for time_r in dictlogs:
            dictaverage[time_r] = {};
            for device in dictlogs[time_r]:
                dictaverage[time_r][device] = {};
                for option in dictlogs[time_r][device]:
                    dictaverage[time_r][device][option] = [];
                    t0 = -1;
                    t1 = 0;
                    avg = 0;
                    avg_elem = [];
                    append = avg_elem.append;
                    val = 0;
                    for elem in dictlogs[time_r][device][option]:
                        if (t0 == -1):
                            t0 = elem[0];
                            val = elem[1];
                            append(t0);
                        else:
                            t1 = elem[0];
                            avg += (t1 - t0) * val;
                            t0 = t1;
                            val = elem[1];
                    append(int(avg / TIME_INTERVAL));
                    append(device);
                    append(option);
                    dictaverage[time_r][device][option].append(avg_elem);
        return (dictaverage);

    ## Gets all the logs from the database.
    #
    # @param db The database handler.
    #
    # @return An array containing all the logs of the database.
    def get_logs(self, db):
        query = ('SELECT daemon_id, addr_dest, t_date, knx_value, type, addr_src '
                 'FROM knx_log '
                 'ORDER BY t_date');
        return self.sql.mysql_handler_personnal_query(query, db);

    ## Cuts a dictionnay depending on the time.
    #
    # @param dictlogs The array to cut.
    #
    # @return An array of the logs corresponding the right time range.
    def cut_dict_time(self, dictlogs):
        end_tr = time.time() - TIME_BEFORE_TIME_TO_CALC - 1;
        init_tr = end_tr - TIME_RANGE_TO_CALC + 1;
        init = init_tr;
        end = init + TIME_INTERVAL - 1;
        dicttime = {};
        tmpdict = {};
        n = int(TIME_RANGE_TO_CALC / TIME_INTERVAL);
        for time_r in range(n):
            dicttime[time_r] = {};
            tmpdict[time_r] = {};
            for device in dictlogs:
                dicttime[time_r][device] = {};
                tmpdict[time_r][device] = {};
                for option in dictlogs[device]:
                    dicttime[time_r][device][option] = [];
                    tmpdict[time_r][device][option] = [];
                    first = tmpdict[time_r][device][option];
                    if (not first):
                        first = list(dictlogs[device][option][0]);
                        first[0] = init;
                    last = list(first);
                    dicttime[time_r][device][option].append(first);
                    for log in dictlogs[device][option]:
                        date = log[0];
                        if (date >= init and date <= end):
                            dicttime[time_r][device][option].append(log);
                            last = list(log);
                        if (date > end):
                            break;
                    last[0] = end + 1;
                    dicttime[time_r][device][option].append(last);
                    tmpdict[time_r][device][option] = list(last);
            init += TIME_INTERVAL;
            end += TIME_INTERVAL;
        return dicttime;

    ## Inserts a graphic log in the database.
    #
    # @param dictlogs Dictionnay containing all the logs.
    # @param db The database handler.
    # @return none
    def save_graph_logs(self, dictlogs, db):
        query = ('INSERT INTO graphic_log '
                 '(date, value, room_device_id, option_id) '
                 'VALUES ');
        for time_r in dictlogs:
            for device in dictlogs[time_r]:
                for option in dictlogs[time_r][device]:
                    for log in dictlogs[time_r][device][option]:
                        query += '('+str(log[0])+', '+str(log[1])+', '+str(log[2])+', '+str(log[3])+'), ';
        query = query[:-2];
        res = self.sql.mysql_handler_personnal_query(query, db);

    ## Deletes the KNX logs from the database.
    #
    # @param dictlogs Dictionnay containing all the logs for all devices.
    # @param db The database handler.
    # @return none
    def delete_knx_logs(self, dictlogs, db):
        end_tr = time.time() - TIME_BEFORE_TIME_TO_CALC;
        last_logs = [];
        append = last_logs.append;
        for device in dictlogs:
            for option in dictlogs[device]:
                log = dictlogs[device][option][-1];
                append(log);
        query = ('DELETE FROM knx_log '
                 'WHERE t_date < ' + str(end_tr));
        res = self.sql.mysql_handler_personnal_query(query, db);
        query = ('DELETE FROM enocean_log '
                 'WHERE t_date < ' + str(end_tr));
        res = self.sql.mysql_handler_personnal_query(query, db);
        query = ('INSERT INTO knx_log '
                 '(type, addr_src, addr_dest, knx_value, t_date, daemon_id) '
                 'VALUES ');
        for log in last_logs:
            query += ('( '+str(log[4])+', '+'\''+str(log[5])+'\', '+
                      '\''+str(log[6])+'\', '+str(log[1])+', '+
                      str(log[0])+', '+str(log[7])+'), ');
        query = query[:-2];
        res = self.sql.mysql_handler_personnal_query(query, db);

    ## Sorts the logs by calling multiple function to print only the wanted logs.
    #
    # @param connection Not used here.
    # @param db The database handler.
    # @return none
    def sort_logs(self, connection, db):
        self.logger.debug('\n\nSorting Logs : \n');
        try:
            logs = self.get_logs(db);
            if not logs:
                return;
            tablogs = self.get_only_good_logs(logs);
            self.logger.debug('TABLOGS 1 :\n'+str(tablogs)+'\n');
            tablogs = self.get_good_time_range(tablogs);
            if not tablogs:
                return;
            self.logger.debug('TABLOGS 2 :\n'+str(tablogs)+'\n');
            dictlogs = self.cut_tab(tablogs);
            if not dictlogs:
                return;
            self.logger.debug('DICTLOGS :\n'+str(dictlogs)+'\n');
            dictlogstime = self.cut_dict_time(dictlogs);
            dictlogstime = self.calc_average_values(dictlogstime);
            if not dictlogstime:
                return;
            self.logger.debug('DICTLOGSTIME :\n'+str(dictlogstime)+'\n');
            self.logger.debug('Save Graph Logs\n');
            self.save_graph_logs(dictlogstime, db);
            self.logger.debug('Delete Logs\n');
            self.delete_knx_logs(dictlogs, db);
            self.logger.debug('OK\n\n');
        except Exception as e:
            self.logger.error(e);
Esempio n. 34
0
class MasterDaemon:
    """
    Main class of the master daemon
    It provides communication between master and slave boxes and a part of the database management
    """
    def __init__(self, log_flag):
        self.logger = Logger(log_flag, LOG_FILE);
        self.logger.info('Started Greenleaf Master Daemon');
        self.d3config = {};
        self.aes_slave_keys = {};
        self.aes_master_key = None;
        self.connected_clients = {};
        self.sql = MasterSql();
        self._parser = DaemonConfigParser(MASTER_CONF_FILE);
        self.get_aes_slave_keys();
        self.reload_camera(None, None);
        self.scanner = Scanner(HOSTS_CONF);
        self.scanner.scan(False);
        self.hostlist = self.scanner._HostList;
        self.sql.insert_hostlist_in_db(self.scanner._HostList);
        self.knx_manager = KNXManager(self.aes_slave_keys);
        self.reload_d3config(None, None);
        self.protocol_function = {
            PROTOCOL_KNX        : KNXManager.protocol_knx,
            PROTOCOL_ENOCEAN    : self.protocol_enocean,
            PROTOCOL_IP         : self.protocol_ip
        };
        self.upnp_function = {
            UPNP_PLAY           : self.upnp_set_play,
            UPNP_PAUSE          : self.upnp_set_pause,
            UPNP_NEXT           : self.upnp_set_next,
            UPNP_PREVIOUS       : self.upnp_set_prev,
            UPNP_STOP           : self.upnp_set_stop,
            UPNP_VOLUME_UP      : self.upnp_set_volume_up,
            UPNP_VOLUME_DOWN    : self.upnp_set_volume_down,
            UPNP_SET_VOLUME     : self.upnp_set_volume
        };
        self.enocean_function = {};
        self.data_function = {
            DATA_MONITOR_KNX            	  : self.monitor_knx,
            DATA_MONITOR_IP             	  : self.monitor_ip,
            DATA_MONITOR_ENOCEAN        	  : self.monitor_enocean,
            DATA_MONITOR_BLUETOOTH      	  : self.monitor_bluetooth,
            DATA_KNX_READ               	  : self.knx_read,
            DATA_KNX_WRITE_S            	  : self.knx_write_short,
            DATA_KNX_WRITE_L            	  : self.knx_write_long,
            DATA_SEND_TO_DEVICE         	  : self.send_to_device,
            DATA_CRON_UPNP             		  : self.cron_upnp,
            DATA_SEND_MAIL              	  : self.send_mail,
            DATA_CHECK_SLAVE            	  : self.check_slave,
            DATA_RELOAD_CAMERA          	  : self.reload_camera,
            DATA_RELOAD_D3CONFIG        	  : self.reload_d3config,
            DATA_BACKUP_DB_CREATE_LOCAL       : self.backup_db_create_local,
            DATA_BACKUP_DB_REMOVE_LOCAL       : self.backup_db_remove_local,
            DATA_BACKUP_DB_LIST_LOCAL         : self.backup_db_list_local,
            DATA_BACKUP_DB_RESTORE_LOCAL      : self.backup_db_restore_local,
            DATA_UPDATE                 	  : self.update
        };

    def get_aes_slave_keys(self):
        """
        Get the secretkeys of each slave daemon stored in database
        """
        query = "SELECT serial, secretkey FROM daemon";
        res = self.sql.mysql_handler_personnal_query(query);
        self_hostname = socket.gethostname();
        for r in res:
            if SLAVE_NAME_PREFIX in r[0] or 'MD3' in r[0]:
                self.aes_slave_keys[r[0]] = r[1];
            elif self_hostname == r[0]:
                self.aes_slave_keys[r[0]] = r[1];
                self.aes_master_key = r[1];
        print(self.aes_slave_keys)

    def stop(self):
        """
        Stops the daemon and closes sockets
        """
        flag = False;
        while not flag:
            flag = True;
            for client in self.connected_clients.values():
                flag = False;
                client.close();
                break;
        self.slave_connection.close();
        sys.exit(0);

    def run(self):
        """
        Initialization of the connections and accepting incomming communications
        """
        self.slave_connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.cmd_connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM);
        self.slave_connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        self.cmd_connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1);
        s_port = self._parser.getValueFromSection(MASTER_CONF_LISTEN_SECTION, MASTER_CONF_LISTEN_PORT_SLAVE_ENTRY);
        c_port = self._parser.getValueFromSection(MASTER_CONF_LISTEN_SECTION, MASTER_CONF_LISTEN_PORT_CMD_ENTRY);
        if not s_port:
            frameinfo = getframeinfo(currentframe());
            self.logger.error('in run: No slave listening port defined in ' + MASTER_CONF_FILE);
            sys.exit(1);
        if not c_port:
            frameinfo = getframeinfo(currentframe());
            self.logger.error('in run: No command listening port defined in ' + MASTER_CONF_FILE);
            sys.exit(1);
        self.slave_connection.bind(('', int(s_port)));
        self.slave_connection.listen(MAX_SLAVES);
        self.cmd_connection.bind(('', int(c_port)));
        self.cmd_connection.listen(MAX_CMDS);
        self.loop();

    def loop(self):
        """
        Main loop. Waits for new connections.
        """
        self.run = True;
        while self.run:
            try:
                rlist, wlist, elist = select.select([self.slave_connection], [], [], SELECT_TIMEOUT);
                for connection in rlist:
                    self.accept_new_slave_connection(connection);
                rlist, wlist, elist = select.select([self.cmd_connection], [], [], SELECT_TIMEOUT);
                for connection in rlist:
                    self.accept_new_cmd_connection(connection);
            except KeyboardInterrupt as e:
                frameinfo = getframeinfo(currentframe());
                self.logger.info('in loop: Keyboard interrupt: leaving program');
                print("[ MASTER DAEMON " + frameinfo.filename + ":" + str(frameinfo.lineno) + " ]: Keyboard Interrupt");
                self.stop();
                sys.exit(0);
            except ValueError as e:
                frameinfo = getframeinfo(currentframe());
                self.logger.error('in loop: Value error: ' + str(e));
                print("[ MASTER DAEMON " + frameinfo.filename + ":" + str(frameinfo.lineno) + "]: Value Error");
                print(e);
                pass;

    def accept_new_cmd_connection(self, connection):
        """
        Gets new mastercommand connections and threads the treatment.
        """
        new_connection, addr = connection.accept();
        r = CommandReceiver(new_connection, self);
        r.start();

    def accept_new_slave_connection(self, connection):
        """
        Gets new slave connections and threads the treatment.
        """
        new_connection, addr = connection.accept();
        for host in self.hostlist:
            if addr[0] == host._IpAddr:
                hostname = host._Hostname.split('.')[0];
                r = SlaveReceiver(new_connection, hostname, self);
                r.start();

    def parse_data(self, data, connection):
        """
        Once data are received whether from mastercommand or slave, the function of the packet_type in data is called.
        """
        json_obj = json.JSONDecoder().decode(data);
        if json_obj['packet_type'] in self.data_function.keys():
            self.data_function[json_obj['packet_type']](json_obj, connection);
        else:
            frameinfo = getframeinfo(currentframe());

    def update(self, json_obj, connection):
        call(['apt-get', 'update']);
        call(['apt-get', 'install', 'glmaster', 'glslave', '-y']);
        hostname = socket.gethostname();
        if '.' in hostname:
            hostname = hostname.split('.')[0];
        version_file = open('/etc/greenleaf/.glmaster.version', 'r');
        if not version_file:
            self.logger.error("File not found: /etc/greenleaf/.glmaster.version");
            print("File not found: /etc/greenleaf/.glmaster.version");
            return;
        version = version_file.read();
        if '\n' in version:
            version = version.split('\n')[0];
        query = 'UPDATE daemon SET version="' + version + '" WHERE name="' + hostname + '"';
        self.sql.mysql_handler_personnal_query(query);
        query = 'UPDATE configuration SET configuration_value="' + version + '" WHERE configuration_id=4';
        self.sql.mysql_handler_personnal_query(query);
        json_obj['data'].append(hostname);
        port = self._parser.getValueFromSection('connect', 'port');
        for host in self.hostlist:
            sock = socket.create_connection((host._IpAddr, port));
            if host._Hostname.startswith('MD3') or host._Hostname.startswith('SD3') and host._Hostname not in json_obj['data']:
                json_str = json.JSONEncoder().encode(json_obj);
                sock.send(bytes(json_str, 'utf-8'));
                data = sock.recv(4096);
                decrypt_IV = data[:16].decode();
                decode_obj = AES.new(self.aes_master_key, AES.MODE_CBC, decrypt_IV);
                data2 = decode_obj.decrypt(data[16:]).decode();
                version = data2['new_version'];
                query = 'UPDATE daemon SET version="' + version + '" WHERE name="' + host._Hostname + '"';
                self.sql.mysql_handler_personnal_query(query);

    def backup_db_create_local(self, json_obj, connection):
        filename = '/etc/greenleaf/sql/backup/mastercommand_backup_';
        t = str(time.time());
        if '.' in t:
            t = t.split('.')[0];
        filename += t;
        filename += '.sql';
        os.popen("mysqldump --defaults-file=/etc/mysql/debian.cnf mastercommand > " + filename);

    def backup_db_remove_local(self, json_obj, connection):
        filename = '/etc/greenleaf/sql/backup/';
        filename += json_obj;
        filename += '.sql';
        if json_obj[0] == '.' or json_obj[0] == '/':
            print('The filename is corrupted. Aborting database file removing.')
            return;
        try:
            os.stat(filename);
        except Exception as e:
            print("The database file to remove does not exists.")
            print(e)
            return;
        os.remove(filename);

    def backup_db_list_local(self, json_obj, connection):
        json_obj = [];
        backup_list = os.listdir('/etc/greenleaf/sql/backup/')
        for f in backup_list:
            s = os.stat('/etc/greenleaf/sql/backup/' + f);
            if '.sql' in f:
                f = f.split('.sql')[0];
				json_obj.append({"name": f, "size": s.st_size});
		json_sorted = sorted(json_obj, key=lambda json_obj: json_obj['name']);
		json_str = json.JSONEncoder().encode(json_sorted);
		connection.send(bytes(json_str, 'utf-8'));
Esempio n. 35
0
class KNXManager:
    """
    KNX management class
    """
    def __init__(self, slave_keys):
        self.knx_function = {
            OPTION_ON_OFF       : self.send_knx_write_short_to_slave,
            OPTION_VAR          : self.send_knx_write_long_to_slave,
            OPTION_UP_DOWN      : self.send_knx_write_short_to_slave,
            OPTION_OPEN_CLOSE   : self.send_knx_write_short_to_slave,
            OPTION_STOP_UP_DOWN : self.send_knx_write_short_to_slave,
            OPTION_SPEED_FAN_0  : self.send_knx_write_speed_fan,
            OPTION_SPEED_FAN_1  : self.send_knx_write_speed_fan,
            OPTION_SPEED_FAN_2  : self.send_knx_write_speed_fan,
            OPTION_SPEED_FAN_3  : self.send_knx_write_speed_fan,
            OPTION_SPEED_FAN_4  : self.send_knx_write_speed_fan,
            OPTION_SPEED_FAN_5  : self.send_knx_write_speed_fan,
            OPTION_SPEED_FAN_6  : self.send_knx_write_speed_fan,
            OPTION_TEMPERATURE_W: self.send_knx_write_temp,
            OPTION_COLOR_R      : self.send_knx_write_long_to_slave,
            OPTION_COLOR_G      : self.send_knx_write_long_to_slave,
            OPTION_COLOR_B      : self.send_knx_write_long_to_slave,
            OPTION_COLOR_W      : self.send_knx_write_long_to_slave
        };
        self.logger = Logger(True, LOG_FILE);
        self.sql = MasterSql();
        self._parser = DaemonConfigParser('/etc/domoleaf/master.conf');
        self.aes_slave_keys = slave_keys;

    def update_room_device_option(self, daemon_id, json_obj):
        """
        Update room_device_option table in database to set new values of the device described by 'json_obj'
        """
        if int(json_obj['type']) == KNX_RESPONSE:
            self.sql.update_room_device_option_resp(json_obj, daemon_id);
        elif int(json_obj['type']) == KNX_WRITE_SHORT:
            self.sql.update_room_device_option_write_short(json_obj, daemon_id);
        elif int(json_obj['type']) == KNX_WRITE_LONG:
            self.sql.update_room_device_option_write_long(json_obj, daemon_id);

    def protocol_knx(self, json_obj, dev, hostname):
        """
        KNX protocol data treatment function
        """
        new_obj = {
            "data": {
                "addr": str(dev['addr_dst']),
                "value": str(json_obj['data']['value']),
                "option_id": str(json_obj['data']['option_id']),
                "room_device_id": str(dev['room_device_id']),
            }
        };
        self.knx_function[int(json_obj['data']['option_id'])](hostname, new_obj);

    def send_json_obj_to_slave(self, json_str, sock, hostname, aes_key, close_flag = True):
        """
        Send 'json_obj' to 'hostname' via 'sock'
        """
        hostname_key = '';
        if '.' in hostname:
            hostname_key = hostname.split('.')[0];
        else:
            hostname_key = hostname;
        AES.key_size = 32;
        aes_IV = AESManager.get_IV();
        encode_obj = AES.new(aes_key, AES.MODE_CBC, aes_IV);
        spaces = 16 - len(json_str) % 16;
        data2 = encode_obj.encrypt(json_str + (spaces * ' '));
        sock.send(bytes(aes_IV, 'utf-8') + data2);
        if close_flag == True:
            sock.close();

    def send_knx_write_speed_fan(self, hostname, json_obj):
        """
        Ask to close all the speed fan before open another
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        if json_obj['data']['value'] == '1':
            query =  'SELECT option_id, addr, dpt_id ';
            query += 'FROM room_device_option ';
            query += 'WHERE room_device_id=' + str(json_obj['data']['room_device_id']) + ' AND ';
            query += 'option_id IN(400, 401, 402, 403, 404, 405, 406) AND status=1';
            res = self.sql.mysql_handler_personnal_query(query);
            for line in res:
                if str(line[2]) == "51" and str(line[0]) == str(json_obj['data']['option_id']):
                    sock = socket.create_connection((hostname, port));
                    val = str(line[0]).split('40')[1];
                    json_str = json.JSONEncoder().encode(
                        {
                            "packet_type": "knx_write_long",
                            "addr_to_send": line[1],
                            "value": val
                        }
                    );
                    self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
                    sock.close();
                    return;
                if str(line[2]) == "2" and str(line[0]) != str(json_obj['data']['option_id']):
                    sock = socket.create_connection((hostname, port));
                    json_str = json.JSONEncoder().encode(
                        {
                            "packet_type": "knx_write_short",
                            "addr_to_send": line[1],
                            "value": "0"
                        }
                    );
                    self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
                    sock.close();

        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_short",
                "addr_to_send": json_obj['data']['addr'],
                "value": json_obj['data']['value']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_write_temp(self, hostname, json_obj):
        """
        Converts absolute value of temperature (Celsius) in 2 hexadecimal values for
        sending to KNX device
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        val_str = json_obj['data']['value'];
        if '.' in val_str:
            val_str = val_str.split('.')[0];
        value = utils.convert_temperature_reverse(int(val_str));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_temp",
                "addr_to_send": json_obj['data']['addr'],
                "value": value[0] + ' ' + value[1]
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_write_long_to_slave(self, hostname, json_obj):
        """
        Constructs long write request and sends it to 'hostname'
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_long",
                "addr_to_send": json_obj['data']['addr'],
                "value": hex(int(json_obj['data']['value']))
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_write_short_to_slave(self, hostname, json_obj):
        """
        Constructs short write request and sends it to 'hostname'
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_short",
                "addr_to_send": json_obj['data']['addr'],
                "value": json_obj['data']['value']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_read_request_to_slave(self, hostname, json_obj):
        """
        Constructs short read request and sends it to 'hostname'
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_read_request",
                "addr_to_read": json_obj['data']['addr']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
Esempio n. 36
0
class Schedule:

    def __init__(self, daemon):
        self.logger = Logger(False, LOG_FILE);
        self.sql = MasterSql();
        self.daemon = daemon;
        self.schedules_list = '';
        self.full_schedules_list = '';
        self.update_schedules_list();

    def update_schedules_list(self):
        self.logger.debug('Updating Schedules');
        query = ('SELECT trigger_schedules_list.id_schedule, id_smartcmd, '
                 'months, weekdays, days, hours, mins '
                 'FROM scenarios_list '
                 'JOIN trigger_schedules_list ON scenarios_list.id_schedule = trigger_schedules_list.id_schedule '
                 'WHERE scenarios_list.id_schedule IS NOT NULL && id_trigger IS NULL && activated = 1 '
                 'ORDER BY id_scenario ');
        res = self.sql.mysql_handler_personnal_query(query);
        self.schedules_list = res;
        
        query = ('SELECT trigger_schedules_list.id_schedule, id_smartcmd, '
                 'months, weekdays, days, hours, mins '
                 'FROM scenarios_list '
                 'JOIN trigger_schedules_list ON scenarios_list.id_schedule = trigger_schedules_list.id_schedule '
                 'WHERE scenarios_list.id_schedule IS NOT NULL && activated = 1 '
                 'ORDER BY id_scenario ');
        res = self.sql.mysql_handler_personnal_query(query);
        self.full_schedules_list = res;

    def get_schedule_infos(self, id_schedule):
        schedules_list = self.full_schedules_list;
        for schedule in schedules_list:
            if (schedule[0] == id_schedule):
                return (schedule[2], schedule[3], schedule[4],
                        schedule[5], schedule[6]);
        return 0;

    def check_all_schedules(self, connection):
        schedules_list = self.schedules_list;
        for schedule in schedules_list:
            if self.test_schedule(schedule[0]) == 1:
                self.launch_scenario(schedule[1], connection);

    def test_schedule(self, id_schedule):
        if not self.full_schedules_list:
            return 0;
        months, weekdays, days, hours, mins = self.get_schedule_infos(id_schedule);
        now = datetime.datetime.now();
        curr_month = int(now.month) - 1;
        curr_weekday = int(now.strftime('%w'));
        curr_day = int(now.day) - 1;
        curr_hour = int(now.hour);
        curr_min = int(now.minute);

        months = list("{0:b}".format(int(months)).zfill(12));
        weekdays = list("{0:b}".format(int(weekdays)).zfill(7));
        days = list("{0:b}".format(int(days)).zfill(31));
        hours = list("{0:b}".format(int(hours)).zfill(24));
        mins = list(mins);
        
        if (int(months[curr_month]) == 1 and int(weekdays[curr_weekday]) == 1
            and int(days[curr_day]) == 1 and int(hours[curr_hour]) == 1
            and int(mins[curr_min]) == 1):
            return 1;
        return 0;

    def launch_scenario(self, id_smartcmd, connection):
        jsonString = json.JSONEncoder().encode({
            "data": id_smartcmd
        });
        data = json.JSONDecoder().decode(jsonString);
        self.daemon.smartcmd_launch(data, connection);
Esempio n. 37
0
class KNXManager:
    """
    KNX management class
    """
    def __init__(self, slave_keys):
        self.knx_function = {
            OPTION_ON_OFF       : self.send_knx_write_short_to_slave,
            OPTION_VAR          : self.send_knx_write_long_to_slave,
            OPTION_UP_DOWN      : self.send_knx_write_short_to_slave,
            OPTION_OPEN_CLOSE   : self.send_knx_write_short_to_slave,
            OPTION_STOP_UP_DOWN : self.send_knx_write_short_to_slave,
            OPTION_TEMPERATURE_W: self.send_knx_write_temp
        };
        self.sql = MasterSql();
        self._parser = DaemonConfigParser('/etc/greenleaf/master.conf');
        self.aes_slave_keys = slave_keys;

    def update_room_device_option(self, daemon_id, json_obj):
        """
        Update room_device_option table in database to set new values of the device described by 'json_obj'
        """
        if int(json_obj['type']) == KNX_RESPONSE:
            self.sql.update_room_device_option_resp(json_obj, daemon_id);
        elif int(json_obj['type']) == KNX_WRITE_SHORT:
            self.sql.update_room_device_option_write_short(json_obj, daemon_id);
        elif int(json_obj['type']) == KNX_WRITE_LONG:
            self.sql.update_room_device_option_write_long(json_obj, daemon_id);

    def protocol_knx(self, json_obj, dev, hostname):
        """
        KNX protocol data treatment function
        """
        new_obj = {
            "data": {
                "addr": str(dev['addr_dst']),
                "value": str(json_obj['data']['value'])
            }
        };
        self.knx_function[int(json_obj['data']['option_id'])](hostname, new_obj);

    def send_json_obj_to_slave(self, json_str, sock, hostname, aes_key, close_flag = True):
        """
        Send 'json_obj' to 'hostname' via 'sock'
        """
        hostname_key = '';
        if '.' in hostname:
            hostname_key = hostname.split('.')[0];
        else:
            hostname_key = hostname;
        AES.key_size = 32;
        aes_IV = AESManager.get_IV();
        encode_obj = AES.new(aes_key, AES.MODE_CBC, aes_IV);
        data2 = encode_obj.encrypt(json_str + (176 - len(json_str)) * ' ');
        sock.send(bytes(aes_IV, 'utf-8') + data2);
        if close_flag == True:
            sock.close();

    def send_knx_write_temp(self, hostname, json_obj):
        """
        Converts absolute value of temperature (Celsius) in 2 hexadecimal values for
        sending to KNX device
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        val_str = json_obj['data']['value'];
        if '.' in val_str:
            val_str = val_str.split('.')[0];
        value = utils.convert_temperature_reverse(int(val_str));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_temp",
                "addr_to_send": json_obj['data']['addr'],
                "value": value[0] + ' ' + value[1]
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_write_long_to_slave(self, hostname, json_obj):
        """
        Constructs long write request and sends it to 'hostname'
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_long",
                "addr_to_send": json_obj['data']['addr'],
                "value": hex(int(json_obj['data']['value']))
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_write_short_to_slave(self, hostname, json_obj):
        """
        Constructs short write request and sends it to 'hostname'
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_write_short",
                "addr_to_send": json_obj['data']['addr'],
                "value": json_obj['data']['value']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);

    def send_knx_read_request_to_slave(self, hostname, json_obj):
        """
        Constructs short read request and sends it to 'hostname'
        """
        port = self._parser.getValueFromSection('connect', 'port');
        if not port:
            sys.exit(4);
        sock = socket.create_connection((hostname, port));
        json_str = json.JSONEncoder().encode(
            {
                "packet_type": "knx_read_request",
                "addr_to_read": json_obj['data']['addr']
            }
        );
        self.send_json_obj_to_slave(json_str, sock, hostname, self.aes_slave_keys[hostname]);
Esempio n. 38
0
class CalcLogs:

    def __init__(self, daemon):
        self.logger = Logger(False, LOG_FILE);
        self.logger.debug('Init CalcLogs');
        self.sql = MasterSql();
        self.daemon = daemon;
        self.devices_list = {};
        self.devices_list_update();

    def devices_list_update(self):
        self.logger.debug('Updating Logs');
        query = ('SELECT room_device.daemon_id, room_device_option.addr_plus, room_device_option.addr, '
                 'room_device.room_device_id, room_device_option.option_id, room_device.name '
                 'FROM room_device '
                 'JOIN room_device_option '
                 'ON room_device.room_device_id = room_device_option.room_device_id '
                 'WHERE daemon_id IS NOT NULL '
                 'ORDER BY room_device_id');
        res = self.sql.mysql_handler_personnal_query(query);
        self.devices_list = res;
        self.devices_list = self.get_tab_devices_list(res);

    def get_tab_devices_list(self, res):
        tab = {};
        for r in res:
            daemon_id = r[0];
            addr_plus = r[1];
            addr = r[2];
            if daemon_id not in tab:
                tab[daemon_id] = {};
            if addr_plus:
                if daemon_id in tab and addr_plus not in tab[daemon_id]:
                    tab[daemon_id][addr_plus] = [];
                    r = r[3:];
                    tab[daemon_id][addr_plus].append(r);
            else:
                if daemon_id in tab and addr not in tab[daemon_id]:
                    tab[daemon_id][addr] = [];
                    r = r[3:];
                    tab[daemon_id][addr].append(r);
        return tab;

    def get_only_good_logs(self, res):
        tab = [];
        tab_append = tab.append
        self.logger.debug(self.devices_list);
        for r in res:
            if (r[1] in self.devices_list[r[0]]):
                self.logger.debug(r);
                log = [];
                log_append = log.append;
                log_append(r[2]);
                log_append(r[3]);
                log_append(self.devices_list[r[0]][r[1]][0][0]);
                log_append(self.devices_list[r[0]][r[1]][0][1]);
                log_append(r[4]);
                log_append(r[5]);
                log_append(r[1]);
                log_append(r[0]);
                tab_append(log);
        return tab;

    def get_good_time_range(self, res):
        end_tr = time.time() - TIME_BEFORE_TIME_TO_CALC - 1;
        init_tr = end_tr - TIME_RANGE_TO_CALC + 1;
        #self.logger.debug('NOW = '+ time.strftime("%d %m %Y %H:%M:%S", time.localtime(now)));
        tab = [];
        append = tab.append;
        for r in res:
            if (r[0] <= end_tr):
                append(r);
        return (tab);

    def cut_tab(self, tab):
        cut_tab = {};
        cut_dict = {};

        for log in tab:
            device_id = log[2];
            option_id = log[3];
            if (device_id not in cut_tab):
                cut_tab[device_id] = {};
            if (option_id not in cut_tab[device_id]):
                cut_tab[device_id][option_id] = [];
            cut_tab[device_id][option_id].append(log);
        
        for device in cut_tab:
            cut_dict[device] = {};
            for option in cut_tab[device]:
                cut_dict[device][option] = [];
                for log in cut_tab[device][option]:
                    cut_dict[device][option].append(log);

        return cut_dict;

    def calc_average_values(self, dictlogs):
        dictaverage = {};
        for time_r in dictlogs:
            dictaverage[time_r] = {};
            for device in dictlogs[time_r]:
                dictaverage[time_r][device] = {};
                for option in dictlogs[time_r][device]:
                    dictaverage[time_r][device][option] = [];
                    
                    t0 = -1;
                    t1 = 0;
                    avg = 0;
                    avg_elem = [];
                    append = avg_elem.append;
                    val = 0;
                    for elem in dictlogs[time_r][device][option]:
                        if (t0 == -1):
                            t0 = elem[0];
                            val = elem[1];
                            append(t0);
                        else:
                            t1 = elem[0];
                            avg += (t1 - t0) * val;
                            t0 = t1;
                            val = elem[1];
                    append(int(avg / TIME_INTERVAL));
                    append(device);
                    append(option);
                    dictaverage[time_r][device][option].append(avg_elem);
        return (dictaverage);

    def get_logs(self, db):
        query = ('SELECT daemon_id, addr_dest, t_date, knx_value, type, addr_src '
                 'FROM knx_log '
                 'ORDER BY t_date');
        return self.sql.mysql_handler_personnal_query(query, db);

    def cut_dict_time(self, dictlogs):
        end_tr = time.time() - TIME_BEFORE_TIME_TO_CALC - 1;
        init_tr = end_tr - TIME_RANGE_TO_CALC + 1;
        init = init_tr;
        end = init + TIME_INTERVAL - 1;
        dicttime = {};
        tmpdict = {};
        n = int(TIME_RANGE_TO_CALC / TIME_INTERVAL);
        for time_r in range(n):
            dicttime[time_r] = {};
            tmpdict[time_r] = {};
            for device in dictlogs:
                dicttime[time_r][device] = {};
                tmpdict[time_r][device] = {};
                for option in dictlogs[device]:
                    dicttime[time_r][device][option] = [];
                    tmpdict[time_r][device][option] = [];
                    first = tmpdict[time_r][device][option];
                    if (not first):
                        first = list(dictlogs[device][option][0]);
                        first[0] = init;
                    last = list(first);
                    dicttime[time_r][device][option].append(first);
                    for log in dictlogs[device][option]:
                        date = log[0];
                        if (date >= init and date <= end):
                            dicttime[time_r][device][option].append(log);
                            last = list(log);
                        if (date > end):
                            break;
                    last[0] = end + 1;
                    dicttime[time_r][device][option].append(last);
                    tmpdict[time_r][device][option] = list(last);
            init += TIME_INTERVAL;
            end += TIME_INTERVAL;
        return dicttime;

    def save_graph_logs(self, dictlogs, db):
        query = ('INSERT INTO graphic_log '
                 '(date, value, room_device_id, option_id) '
                 'VALUES ');
        for time_r in dictlogs:
            for device in dictlogs[time_r]:
                for option in dictlogs[time_r][device]:
                    for log in dictlogs[time_r][device][option]:
                        query += '('+str(log[0])+', '+str(log[1])+', '+str(log[2])+', '+str(log[3])+'), ';
        query = query[:-2];
        res = self.sql.mysql_handler_personnal_query(query, db);

    def delete_knx_logs(self, dictlogs, db):
        end_tr = time.time() - TIME_BEFORE_TIME_TO_CALC;
        last_logs = [];
        append = last_logs.append;
        for device in dictlogs:
            for option in dictlogs[device]:
                log = dictlogs[device][option][-1];
                append(log);
        query = ('DELETE FROM knx_log '
                 'WHERE t_date < ' + str(end_tr));
        res = self.sql.mysql_handler_personnal_query(query, db);
        query = ('DELETE FROM enocean_log '
                 'WHERE t_date < ' + str(end_tr));
        res = self.sql.mysql_handler_personnal_query(query, db);
        query = ('INSERT INTO knx_log '
                 '(type, addr_src, addr_dest, knx_value, t_date, daemon_id) '
                 'VALUES ');
        for log in last_logs:
            query += ('( '+str(log[4])+', '+'\''+str(log[5])+'\', '+
                      '\''+str(log[6])+'\', '+str(log[1])+', '+
                      str(log[0])+', '+str(log[7])+'), ');
        query = query[:-2];
        res = self.sql.mysql_handler_personnal_query(query, db);

    def sort_logs(self, connection, db):
        self.logger.debug('\n\nSorting Logs : \n');
        try:
            logs = self.get_logs(db);
            #self.logger.debug('LOGS :\n' + str(logs) + '\n');
            if not logs:
                return;
            tablogs = self.get_only_good_logs(logs);
            self.logger.debug('TABLOGS 1 :\n'+str(tablogs)+'\n');
            tablogs = self.get_good_time_range(tablogs);
            if not tablogs:
                return;
            self.logger.debug('TABLOGS 2 :\n'+str(tablogs)+'\n');
            dictlogs = self.cut_tab(tablogs);
            if not dictlogs:
                return;
            self.logger.debug('DICTLOGS :\n'+str(dictlogs)+'\n');
            dictlogstime = self.cut_dict_time(dictlogs);
            dictlogstime = self.calc_average_values(dictlogstime);
            if not dictlogstime:
                return;
            self.logger.debug('DICTLOGSTIME :\n'+str(dictlogstime)+'\n');
            self.logger.debug('Save Graph Logs\n');
            self.save_graph_logs(dictlogstime, db);
            self.logger.debug('Delete Logs\n');
            self.delete_knx_logs(dictlogs, db);
            self.logger.debug('OK\n\n');
        except Exception as e:
            self.logger.error(e);
Esempio n. 39
0
 def __init__(self):
     ## Logger object for formatting and printing logs
     self.logger = Logger(False, LOG_FILE);
     ## SQL object for managing database
     self.sql = MasterSql();
Esempio n. 40
0
class CalcLogs:

    def __init__(self, daemon):
        self.logger = Logger(False, LOG_FILE);
        self.logger.debug('Init CalcLogs');
        self.sql = MasterSql();
        self.daemon = daemon;
        self.devices_list = {};
        self.devices_list_update();

    def devices_list_update(self):
        self.logger.debug('Updating Logs');
        query = ('SELECT room_device.daemon_id, room_device_option.addr_plus, room_device_option.addr, '
                 'room_device.room_device_id, room_device_option.option_id, room_device.name '
                 'FROM room_device '
                 'JOIN room_device_option '
                 'ON room_device.room_device_id = room_device_option.room_device_id '
                 'WHERE daemon_id IS NOT NULL '
                 'ORDER BY room_device_id');
        res = self.sql.mysql_handler_personnal_query(query);
        self.devices_list = res;
        self.devices_list = self.get_tab_devices_list(res);

    def get_tab_devices_list(self, res):
        tab = {};
        for r in res:
            daemon_id = r[0];
            addr_plus = r[1];
            addr = r[2];
            if (daemon_id not in tab):
                tab[daemon_id] = {};
            if (addr_plus):
                if (daemon_id in tab and addr_plus not in tab[daemon_id]):
                    tab[daemon_id][addr_plus] = [];
                    r = r[3:];
                    tab[daemon_id][addr_plus].append(r);
            else:
                if (daemon_id in tab and addr not in tab[daemon_id]):
                    tab[daemon_id][addr] = [];
                    r = r[3:];
                    tab[daemon_id][addr].append(r);
        return tab;

    def get_only_good_logs(self, res):
        tab = [];
        self.logger.debug(self.devices_list);
        for r in res:
            if (r[1] in self.devices_list[r[0]]):
                self.logger.debug(r);
                log = [];
                log.append(r[2]);
                log.append(r[3]);
                log.append(self.devices_list[r[0]][r[1]][0][0]);
                log.append(self.devices_list[r[0]][r[1]][0][1]);
                log.append(r[4]);
                log.append(r[5]);
                log.append(r[1]);
                log.append(r[0]);
                tab.append(log);
        return tab;

    def get_good_time_range(self, res):
        now = time.time();
        #now = TEST_TIMESTAMP;
        end_tr = now - TIME_BEFORE_TIME_TO_CALC - 1;
        init_tr = end_tr - TIME_RANGE_TO_CALC + 1;

        #self.logger.debug('NOW = '+ time.strftime("%d %m %Y %H:%M:%S", time.localtime(now)));

        tab = [];
        for r in res:
            date = r[0];
            if (date <= end_tr):
                tab.append(r);
        return (tab);

    def cut_tab(self, tab):
        cut_tab = {};
        cut_dict = {};

        for log in tab:
            device_id = log[2];
            option_id = log[3];
            if (device_id not in cut_tab):
                cut_tab[device_id] = {};
            if (option_id not in cut_tab[device_id]):
                cut_tab[device_id][option_id] = [];
            cut_tab[device_id][option_id].append(log);
        
        for device in cut_tab:
            cut_dict[device] = {};
            for option in cut_tab[device]:
                cut_dict[device][option] = [];
                for log in cut_tab[device][option]:
                    cut_dict[device][option].append(log);

        return cut_dict;

    def calc_average_values(self, dictlogs):
        dictaverage = {};

        for time_r in dictlogs:
            dictaverage[time_r] = {};

            for device in dictlogs[time_r]:
                dictaverage[time_r][device] = {};

                for option in dictlogs[time_r][device]:
                    dictaverage[time_r][device][option] = [];
                    
                    t0 = -1;
                    t1 = 0;
                    avg = 0;
                    avg_elem = [];
                    val = 0;

                    for elem in dictlogs[time_r][device][option]:
                        if (t0 == -1):
                            t0 = elem[0];
                            val = elem[1];
                            avg_elem.append(t0);
                        else:
                            t1 = elem[0];
                            avg = avg + (t1 - t0) * val;
                            t0 = t1;
                            val = elem[1];
                    avg_elem.append(int(avg / TIME_INTERVAL));
                    avg_elem.append(device);
                    avg_elem.append(option);
                    dictaverage[time_r][device][option].append(avg_elem);

        return (dictaverage);


    def get_logs(self, test):
        if (test == 0):
            query = ('SELECT daemon_id, addr_dest, t_date, knx_value, type, addr_src '
                     'FROM knx_log '
                     'ORDER BY t_date');
            res = self.sql.mysql_handler_personnal_query(query);

        else:
            res = self.get_test_logs();
            
        return res;

    def cut_dict_time(self, dictlogs):
        now = time.time();
        #now =  TEST_TIMESTAMP;
        end_tr = now - TIME_BEFORE_TIME_TO_CALC - 1;
        init_tr = end_tr - TIME_RANGE_TO_CALC + 1;
        init = init_tr;
        end = init + TIME_INTERVAL - 1;

        dicttime = {};
        tmpdict = {};
        n = int(TIME_RANGE_TO_CALC / TIME_INTERVAL);
        for time_r in range(n):
            dicttime[time_r] = {};
            tmpdict[time_r] = {};
            for device in dictlogs:
                dicttime[time_r][device] = {};
                tmpdict[time_r][device] = {};

                for option in dictlogs[device]:
                    dicttime[time_r][device][option] = [];
                    tmpdict[time_r][device][option] = [];
                                        
                    first = tmpdict[time_r][device][option];
                    if (not first):
                        first = list(dictlogs[device][option][0]);
                        first[0] = init;
                    last = list(first);
                    dicttime[time_r][device][option].append(first);
                    
                    for log in dictlogs[device][option]:
                        date = log[0];
                        if (date >= init and date <= end):
                            dicttime[time_r][device][option].append(log);
                            last = list(log);
                        if (date > end):
                            break;
                    
                    last[0] = end + 1;
                    dicttime[time_r][device][option].append(last);
                    tmpdict[time_r][device][option] = list(last);
                            
            init = init + TIME_INTERVAL;
            end = end + TIME_INTERVAL;

        return dicttime;
        

    def save_graph_logs(self, dictlogs):

        query = ('INSERT INTO graphic_log '
                 '(date, value, room_device_id, option_id) '
                 'VALUES ');

        for time_r in dictlogs:
            for device in dictlogs[time_r]:
                for option in dictlogs[time_r][device]:
                    for log in dictlogs[time_r][device][option]:
                        query += '(' + str(log[0]) + ', ';
                        query += str(log[1]) + ', ';
                        query += str(log[2]) + ', ';
                        query += str(log[3]) + '), ';

        query = query[:-2];
        res = self.sql.mysql_handler_personnal_query(query);

    def delete_knx_logs(self, dictlogs):
        now = time.time();
        #now =  TEST_TIMESTAMP;
        end_tr = now - TIME_BEFORE_TIME_TO_CALC;

        last_logs = [];
        
        for device in dictlogs:
            for option in dictlogs[device]:
                log = dictlogs[device][option][-1];
                last_logs.append(log);

        query = ('DELETE FROM knx_log '
                 'WHERE t_date < ' + str(end_tr));
        res = self.sql.mysql_handler_personnal_query(query);
        query = ('DELETE FROM enocean_log '
                 'WHERE t_date < ' + str(end_tr));
        res = self.sql.mysql_handler_personnal_query(query);
        
        query = ('INSERT INTO knx_log '
                 '(type, addr_src, addr_dest, knx_value, t_date, daemon_id) '
                 'VALUES ');
        for log in last_logs:
            query += '( ' + str(log[4]) + ', ';
            query += '\'' + str(log[5]) + '\', ';
            query += '\'' + str(log[6]) + '\', ';
            query += str(log[1]) + ', ';
            query += str(log[0]) + ', ';
            query += str(log[7]) + '), ';

        query = query[:-2];
        res = self.sql.mysql_handler_personnal_query(query);
        
    def sort_logs(self, connection):
        self.logger.debug('\n\nSorting Logs : \n');

        try:
            logs = self.get_logs(0);
            #self.logger.debug('LOGS :\n' + str(logs) + '\n');

            if not logs:
                return;
            tablogs = self.get_only_good_logs(logs);
            self.logger.debug('TABLOGS 1 :\n' + str(tablogs) + '\n');
            tablogs = self.get_good_time_range(tablogs);
            if not tablogs:
                return;
            self.logger.debug('TABLOGS 2 :\n' + str(tablogs) + '\n');
            
            dictlogs = self.cut_tab(tablogs);
            if not dictlogs:
                return;
            self.logger.debug('DICTLOGS :\n' + str(dictlogs) + '\n');
            
            dictlogstime = self.cut_dict_time(dictlogs);
            dictlogstime = self.calc_average_values(dictlogstime);
            if not dictlogstime:
                return;
            self.logger.debug('DICTLOGSTIME :\n' + str(dictlogstime) + '\n');

            self.logger.debug('Save Graph Logs\n');
            self.save_graph_logs(dictlogstime);
            self.logger.debug('Delete Logs\n');
            self.delete_knx_logs(dictlogs);
            self.logger.debug('OK\n\n');
            
        except Exception as e:
            self.logger.error(e);


    def get_test_logs(self):
        res = [(1, '0/0/12', 1448268700, 1), (1, '0/1/23', 1448268800, 3515), (1, '0/0/14', 1448268850, 255), (1, '0/0/17', 1448268860, 1), (1, '0/1/1', 1448268900, 1786), (1, '0/1/1', 1448270540, 1786), (1, '0/1/1', 1448270661, 1788), (1, '0/1/23', 1448270719, 3548), (1, '0/1/1', 1448270781, 1790), (1, '0/1/1', 1448270901, 1792), (1, '0/1/1', 1448271141, 1796), (1, '0/0/12', 1448271148, 1), (1, '0/0/14', 1448271152, 255), (1, '0/1/23', 1448271155, 3598), (1, '0/0/17', 1448271160, 1), (1, '0/0/19', 1448271163, 255), (1, '0/1/23', 1448271167, 3398), (1, '0/0/12', 1448271173, 0), (1, '0/0/14', 1448271175, 0), (1, '0/0/12', 1448271179, 0), (1, '0/0/17', 1448271181, 0), (1, '0/0/19', 1448271184, 0), (1, '0/0/17', 1448271188, 0), (1, '0/0/12', 1448271229, 1), (1, '0/0/14', 1448271232, 255), (1, '0/0/17', 1448271235, 1), (1, '0/0/19', 1448271238, 251), (1, '0/0/19', 1448271241, 255), (1, '0/0/12', 1448271245, 0), (1, '0/0/14', 1448271247, 0), (1, '0/0/17', 1448271251, 0), (1, '0/0/19', 1448271253, 0), (1, '0/0/12', 1448271257, 1), (1, '0/0/14', 1448271259, 204), (1, '0/1/1', 1448271262, 1802), (1, '0/0/12', 1448271265, 1), (1, '0/0/14', 1448271268, 255), (1, '0/0/14', 1448271273, 59), (1, '0/0/14', 1448271274, 58), (1, '0/0/17', 1448271281, 1), (1, '0/0/19', 1448271284, 255), (1, '0/1/1', 1448271381, 1806), (1, '0/1/1', 1448271501, 1812), (1, '0/1/1', 1448271621, 1816), (1, '0/1/1', 1448271741, 1824), (1, '0/1/1', 1448272011, 1830), (1, '0/1/23', 1448272062, 3398), (1, '0/1/1', 1448272101, 1834), (1, '0/1/1', 1448272222, 1834), (1, '0/1/1', 1448272295, 1824), (1, '0/1/1', 1448272415, 1822), (1, '0/1/1', 1448272535, 1822), (1, '0/1/1', 1448272655, 1824), (1, '0/1/1', 1448272775, 1824), (1, '0/1/1', 1448272911, 1830), (1, '0/1/23', 1448272963, 3398), (1, '0/1/1', 1448273015, 1836), (1, '0/1/1', 1448273135, 1838), (1, '0/1/1', 1448273255, 1842), (1, '0/1/1', 1448273375, 1844), (1, '0/1/1', 1448273495, 1850), (1, '0/1/1', 1448273615, 1852), (1, '0/1/1', 1448273735, 1856), (1, '0/1/1', 1448273856, 1856), (1, '0/1/23', 1448273863, 3398), (1, '0/1/1', 1448273976, 1858), (1, '0/1/1', 1448274096, 1864), (1, '0/1/1', 1448274216, 1866), (1, '0/1/1', 1448274336, 1870), (1, '0/1/1', 1448274456, 1874), (1, '0/1/1', 1448274576, 1876), (1, '0/1/1', 1448274712, 1882), (1, '0/1/23', 1448274764, 3398), (1, '0/1/24', 1448274767, 3423), (1, '0/1/1', 1448274816, 1884), (1, '0/1/1', 1448274936, 1886), (1, '0/1/1', 1448275056, 1888), (1, '0/1/1', 1448275176, 1892), (1, '0/1/1', 1448275296, 1892), (1, '0/1/1', 1448275416, 1896), (1, '0/1/6', 1448275519, 0), (1, '0/1/8', 1448275522, 0)];
        return (res);