示例#1
0
    def _data_collection_step_voltage_input(self):
        """
        This method is a single data collection step
        :return:
        """
        voltage_value = self.gpio_interface.read_value(
            'i2c', self.cfg['gpio']['voltage_sensor'])
        log_event(self.cfg, self.module_name, '', 'INFO',
                  'Data point collected ' + str(voltage_value))
        self._voltage_data.append(voltage_value)

        self.voltage_value = voltage_value

        # Add voltage data point in buffer
        data_point = BufferEntity({
            'measurement':
            self.cfg['influxdb']['voltage_measurement_name'],
            'tags': {
                'Unit': 'V',
                'SclMin': self.cfg['gpio']['voltage_sensor']['scale_min'],
                'SclMax': self.cfg['gpio']['voltage_sensor']['scale_max']
            },
            'fields': {
                'Value': voltage_value
            },
            'timestamp':
            round(time.time() * 1000)
        })
        self.buffer.add_point(data_point)
示例#2
0
 def stop_data_collection(self):
     """
     This methods initiates the data collection thread stop
     :return:
     """
     self._stop_data_collection = True
     log_event(self.cfg, self.module_name, '', 'INFO',
               'Data collection stop initialised')
示例#3
0
 def _control_step(self):
     """
     This method represents a single control step. The last voltage data points is evaluated to define output level
     :return:
     """
     log_event(self.cfg, self.module_name, '', 'INFO', 'Control step')
     self.read_regime()
     decision_level = self._voltage_evaluation()
     if decision_level != self.consumption_level:
         self._set_consumption_level(decision_level)
示例#4
0
 def _run_control(self):
     """
     This methods starts the control as a single thread
     :return:
     """
     self._stop_control = False
     self._stopped_control = False
     self._control_thread = threading.Thread(target=self._control)
     self._control_thread.start()
     log_event(self.cfg, self.module_name, '', 'INFO', 'Controller started')
     self.running = True
示例#5
0
 def switch_to_manual_mode(self):
     log_event(self.cfg, self.module_name, '', 'INFO',
               'Changing mode to manual...')
     self._set_consumption_level(-1)
     self.auto_mode_requested = False
     self.stop_control()
     self.mode_auto = False
     self.mode_manual = True
     log_event(self.cfg, self.module_name, '', 'INFO',
               'Mode changed to manual')
     self._data_collection_mode()
示例#6
0
 def switch_to_auto_mode(self):
     log_event(self.cfg, self.module_name, '', 'INFO',
               'Changing mode to automatic...')
     self._set_consumption_level(-1)
     self.auto_mode_requested = True
     self._run_control()
     self.mode_auto = True
     self.mode_manual = False
     log_event(self.cfg, self.module_name, '', 'INFO',
               'Mode changed to automatic')
     self._write_mode()
示例#7
0
 def stop_control(self):
     """
     This methods initiates the control thread stop
     :return:
     """
     self._stop_control = True
     self._set_consumption_level(-1)
     log_event(self.cfg, self.module_name, '', 'WARN',
               'Control stop initialised')
     while not self._stopped_control:
         pass
     log_event(self.cfg, self.module_name, '', 'WARN', 'Control stopped')
示例#8
0
    def _set_consumption_level(self, level):
        """
        This method sets gpio outputs to get the desired consumption level
        :param level: consumption level
        :return:
        """
        if level == -1:
            changes = [-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13]
            level = 0
        else:
            if level > self.consumption_level:
                changes = self.mapping_table[level - 1]
            else:
                changes = [-x for x in self.mapping_table[level]]

        for change in changes:
            channel = self.cfg['gpio']['relays_outputs']['channels'][
                abs(change) - 1]
            desired_state = change > 0
            self.gpio_interface.write_gpio(channel, desired_state)

        log_event(self.cfg, self.module_name, '', 'INFO',
                  'Consumption level set on ' + str(level))
        self.load = self.cfg['controller']['loads'][level]
        self.consumption_level = level

        data_point = BufferEntity({
            'measurement':
            self.cfg['influxdb']['state_measurement_name'],
            'tags': {
                'Unit': 'V'
            },
            'fields': {
                'Value': level
            },
            'timestamp':
            round(time.time() * 1000)
        })
        self.buffer.add_point(data_point)

        data_point_consumption = BufferEntity({
            'measurement':
            self.cfg['influxdb']['consumption_measurement_name'],
            'fields': {
                'Value': self.cfg['controller']['loads'][level]
            },
            'timestamp':
            round(time.time() * 1000)
        })
        self.buffer.add_point(data_point_consumption)
        log_event(self.cfg, self.module_name, '', 'INFO',
                  'Consumption level ' + str(self.consumption_level))
示例#9
0
    def _run_data_collection(self):
        """
        This methods starts the data collection
        :return:
        """
        self._stop_data_collection = False
        self._stopped_data_collection = False

        self._data_collection_thread = threading.Thread(
            target=self._data_collection)
        self._data_collection_thread.start()
        log_event(self.cfg, self.module_name, '', 'INFO',
                  'Data collection started')
示例#10
0
    def remove_point(self, idx=0):
        """
        This function removes specified element of the buffer. If not specified, removes the very first element.
        :param idx: Index of the element to remove
        :return:
        """

        # Removing operation is only valid if valid index is provided
        if (idx < 0) or (idx > len(self.buffer) - 1):
            log_event(self.cfg, self.module_name, '', 'WARN', str(idx) + ' element does not exist in buffer')
            return
        del self.buffer[idx]
        log_event(self.cfg, self.module_name, '', 'INFO',
                  'Point ' + str(idx) + ' removed from buffer (size=' + str(self.len()) + ')')
示例#11
0
    def remove_points(self, idx):
        """
        This function removes a set of elements.
        :param idx: list of indices
        :return:
        """
        # Removing duplicates
        idx = list(dict.fromkeys(idx))

        # Loop within sorted and reversed list
        for i in sorted(idx, reverse=True):
            self.remove_point(i)
        log_event(self.cfg, self.module_name, '', 'INFO',
                  str(len(idx)) + ' points removed from buffer (size=' + str(self.len()) + ')')
示例#12
0
    def add_point(self, buffer_entity):
        """
        This function puts additional entity into buffer
        :param buffer_entity: buffer entity consisted of node instance and opcua variant
        :return:
        """

        # If after adding a point, the buffer will be overfilled, we will remove the first entity in the buffer
        if len(self.buffer) + 1 > self.max_buffer_size:
            self.remove_point(0)
            log_event(self.cfg, self.module_name, '', 'WARN', 'Buffer is full (' + str(len(self.buffer)) + ')')

        # Append entity
        self.buffer.append(buffer_entity)
        log_event(self.cfg, self.module_name, '', 'INFO', 'Point copied into buffer (size=' + str(self.len()) + ')')
示例#13
0
 def _data_collection(self):
     """
     This method executes repeatedly the data collection step unless stopped
     :return:
     """
     while not self._stop_data_collection:
         start_time = time.time()
         self._data_collection_step_regime()
         self._data_collection_step_voltage_input()
         self._data_collection_step_output_states()
         time_till_next_step = 1 - (time.time() - start_time)
         if time_till_next_step > 0:
             time.sleep(time_till_next_step)
     else:
         self._stopped_data_collection = True
         log_event(self.cfg, self.module_name, '', 'INFO',
                   'Data collection stopped')
示例#14
0
 def read_regime(self):
     regime_names = ['not defined', 'bulk', 'absorb', 'float']
     input_absorb = self.gpio_interface.read_value(
         'GPIO', self.cfg['gpio']['regime_inputs']['absorb'])
     input_float = self.gpio_interface.read_value(
         'GPIO', self.cfg['gpio']['regime_inputs']['float'])
     if input_absorb and not input_float:
         regime = 2
     elif not input_absorb and input_float:
         regime = 3
     elif not input_absorb and input_float:
         regime = 1
     else:
         regime = 0
     regime = 2
     self.regime = regime
     self.regime_str = regime_names[regime]
     log_event(self.cfg, self.module_name, '', 'INFO',
               'Phase: ' + regime_names[self.regime])
示例#15
0
 def set_gpio_state(self, output_no, state):
     channel = self.cfg['gpio']['relays_outputs']['channels'][output_no]
     self.gpio_interface.write_gpio('gpio', channel, state)
     log_event(self.cfg, self.module_name, '', 'INFO',
               'Channel ' + str(channel) + ' set to ' + str(state))
示例#16
0
    def _voltage_evaluation(self):
        """
        This method calculates average voltage value and check whether it changes or does not
        :return:
        """

        new_level = self.consumption_level

        voltage_values = self._voltage_data

        if not len(voltage_values):
            log_event(self.cfg, self.module_name, '', 'WARN',
                      'Not enough voltage data points for evaluation')
            return new_level

        avg_voltage = sum(voltage_values) / len(voltage_values)
        log_event(self.cfg, self.module_name, '', 'INFO',
                  'Calculated average value:' + str(avg_voltage))

        if avg_voltage <= self.cfg['controller']['voltage_critical_level']:
            log_event(self.cfg, self.module_name, '', 'INFO',
                      'The voltage level is too low')
            return -1

        if self.regime == 0:
            return -1

        if self.regime == 1:
            if avg_voltage >= self.cfg['controller'][
                    'voltage_absorb_limit_max']:
                new_level = min(new_level + 1, 23)
                log_event(
                    self.cfg, self.module_name, '', 'INFO',
                    'The consumption level is to increase: ' +
                    str(avg_voltage) + '>=' + str(self.voltage_average))
            if avg_voltage <= self.cfg['controller'][
                    'voltage_absorb_limit_min']:
                new_level = max(new_level - 1, 0)
                log_event(
                    self.cfg, self.module_name, '', 'INFO',
                    'The consumption level is to decrease: ' +
                    str(avg_voltage) + '<=' + str(self.voltage_average))

        if self.regime == 2:
            if avg_voltage >= self.cfg['controller']['voltage_float_limit_max']:
                new_level = min(new_level + 1, 23)
                log_event(
                    self.cfg, self.module_name, '', 'INFO',
                    'The consumption level is to increase: ' +
                    str(avg_voltage) + '>=' + str(self.voltage_average))
            if avg_voltage <= self.cfg['controller']['voltage_float_limit_min']:
                new_level = max(new_level - 1, 0)
                log_event(
                    self.cfg, self.module_name, '', 'INFO',
                    'The consumption level is to decrease: ' +
                    str(avg_voltage) + '<=' + str(self.voltage_average))

        self.voltage_average = avg_voltage

        del self._voltage_data[0:len(voltage_values)]
        return new_level