Commit e9d02a40 authored by Ibrahim Ahmed's avatar Ibrahim Ahmed
Browse files

src: Feedback controller clipping and diagnostics;

baseline_control: SimpleFeedbackController returns last action's feedback in predict() -> action, feedback,
controller: actions are clipped on top to TemoCondOut i.e. setpoint cannot be warmer than output temperature of warmed water
parent af6d9f1a
Loading
Loading
Loading
Loading
+2 −2
Changes for src/baseline_control.py: 2 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -190,7 +190,7 @@ class SimpleFeedbackController(BaseEstimator):
        self._errors = deque(maxlen=100)


    def predict(self, X: pd.DataFrame) -> Tuple[np.ndarray]:
    def predict(self, X: pd.DataFrame) -> Tuple[np.ndarray, float]:
        feedback = self.feedback(X)
        self._feedbacks.append(feedback)

@@ -225,7 +225,7 @@ class SimpleFeedbackController(BaseEstimator):
            action = self.clip_action(action, X)
            
            self._actions.append(action)
        return action,
        return action, feedback


    def feedback(self, X: pd.DataFrame) -> float:
+4 −3
Changes for src/controller.py: 4 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ def get_controller(**settings) -> BaseEstimator:

        def clip_action(self, u, X):
            u = super().clip_action(u, X)
            return np.clip(u, a_min=X['TempWetBulb'], a_max=None)
            return np.clip(u, a_min=X['TempWetBulb'], a_max=X['TempCondOut'])

    stepsize, window = settings['stepsize'], settings['window']
    setpoint_bounds = settings['bounds']
@@ -229,8 +229,9 @@ if __name__ == '__main__':
                    state = get_current_state(prev_end, start, **settings)
                if state is not None:
                    logger.debug('State\n{}'.format(state))
                    action, = ctrl.predict(state)
                    logger.info('Setpoint: {}'.format(action))
                    action, *diag = ctrl.predict(state)
                    feedback = diag[0] if len(diag) > 0 else -1
                    logger.info('Last feedback: {:.2f} \tSetpoint: {:.2f}'.format(feedback, action[0]))
                    put_control_action(action, **settings)
                if settings['dry_run']:
                    logger.info('Dry run finished. Halting.')
+2 −1
Changes for src/monitor.py: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ def log():
    logger = get_logger()
    rdict = request.form
    ip = request.environ.get('HTTP_X_REAL_IP', request.remote_addr)
    logger.log(int(rdict.get('levelno', logging.ERROR)), 'From: %s. %s' % (ip, rdict.get('message', 'NO_MESSAGE')))
    logger.log(int(rdict.get('levelno', logging.ERROR)), 'From: %s. %s' % (ip, rdict.get('message',
                                                                               rdict.get('msg', 'NO_MESSAGE'))))
    return 'OK'


+3 −3
Changes for src/settings.ini: 3 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ logs_file_verbosity = INFO
logs_server_verbosity = DEBUG
# for messages emailed
logs_email_verbosity = DEBUG
# Logging via POST requests to a server.
# Logging via POST requests to a server. Format: scheme://domain[:port][/path/to/POST]
logs_server = http://vumacs.isis.vanderbilt.edu:5000/log
# Email logging settings. Will skip if username/password is absent.
logs_email_to = ibrahim.ahmed@vanderbilt.edu
@@ -60,5 +60,5 @@ logs = ./server-logs.txt
# global level. No less severe messages will be processed. Can only be higher
# than default verbosity.
verbosity = DEBUG
logs_stream_verbosity = INFO
logs_file_verbosity = INFO
logs_stream_verbosity = DEBUG
logs_file_verbosity = DEBUG