/* * coffee.cpp * * Created on: Sep 25, 2017 * Author: sebastian */ #include #include #include #include #include #include #include #include #include #include #include #include "coffee.h" #include "hal.h" #include "logger.h" #include "timer.h" int state; int sigValue; int brewTime; //Brew time in ms timer brewTimer(&brewTimeHandler); void *coffeeThread(void *threadid) { logger(V_BREW, "Initializing coffee thread...\n"); //installing new Signal handler for coffeethread struct sigaction action; sigemptyset(&action.sa_mask); action.sa_flags = SA_SIGINFO; action.sa_sigaction = coffeeHandler; sigaction(SIGUSR2, &action, NULL); brewTimer.setDivider(4); brewTimer.stop(); brewTime = 0; state = STATE_OFF; logger(V_BREW, "Determining inital state\n"); //determine inital state if (halGetRelaisState(RELAIS_POWER) && halGetRelaisState(RELAIS_HEAT) && !halGetRelaisState(RELAIS_PUMP)) { //wait for heat relais to switch sleep(1); if (halIsHeating()) { //Heating is on logger(V_BREW, "Change state: INITALHEATING\n"); state = STATE_INITALHEATING; } else { logger(V_BREW, "Change state: IDLE\n"); state = STATE_IDLE; } } else if (halGetRelaisState(RELAIS_PUMP)) { logger_error("Whoops, why is the pump running...\n"); state = STATE_ERROR; } logger(V_BREW, "Start Coffee FSM\n"); //begin FSM while(1){ switch(state){ case STATE_OFF: pause(); if (getSigValue() == SigInt0Rls) { if (halProxSensorCovered()) { //Check Waterlevel //turn machine on logger(V_BREW, "Turn machine on\n"); halRelaisOn(RELAIS_HEAT); halRelaisOff(RELAIS_PUMP); halRelaisOn(RELAIS_POWER); sleep(1); if (halIsHeating()) { //check if System starts to heat when turned on logger(V_BREW, "Change state: INITALHEATING\n"); state = STATE_INITALHEATING; } else { logger(V_BREW, "Change state: IDLE\n"); state = STATE_IDLE; } } else { logger(V_BREW, "Change state: ERROR\n"); state = STATE_ERROR; } break; } break; case STATE_INITALHEATING: pause(); switch (getSigValue()) { case SigInt1Rls: //Turn machine off again halRelaisOff(RELAIS_HEAT); halRelaisOff(RELAIS_PUMP); halRelaisOff(RELAIS_POWER); logger(V_BREW, "Change state: OFF\n"); state = STATE_OFF; break; case SigPressOpn: //Inital heating finished logger(V_BREW, "Change state: IDLE\n"); state = STATE_IDLE; break; } break; case STATE_HEATING: pause(); switch(getSigValue()){ case SigInt1Rls: //Turn machine off again halRelaisOff(RELAIS_HEAT); halRelaisOff(RELAIS_PUMP); halRelaisOff(RELAIS_POWER); logger(V_BREW, "Change state: OFF\n"); state = STATE_OFF; break; case SigPressOpn: logger(V_BREW, "Change state: IDLE\n"); state = STATE_IDLE; break; case SigInt0Psh: //start to brew a delicious coffee logger(V_BREW, "Change state: BREW\n"); state = STATE_BREW; break; case SigBrewOn: //someone brews manually logger(V_BREW, "Change state: BREWMANUAL\n"); state = STATE_BREWMANUAL; break; } break; case STATE_IDLE: pause(); switch(getSigValue()){ case SigInt1Rls: //Turn machine off again halRelaisOff(RELAIS_HEAT); halRelaisOff(RELAIS_PUMP); halRelaisOff(RELAIS_POWER); logger(V_BREW, "Change state: OFF\n"); state = STATE_OFF; break; case SigPressCls: logger(V_BREW, "Change state: HEATING\n"); state = STATE_HEATING; break; case SigInt0Psh: //start to brew a delicious coffee logger(V_BREW, "Change state: BREW\n"); state = STATE_BREW; break; case SigBrewOn: //someone brews manually logger(V_BREW, "Change state: BREWMANUAL\n"); state = STATE_BREWMANUAL; break; } break; case STATE_BREW: //Preinfusion logger(V_BREW, "Starting preinfusion...\n"); halRelaisOn(RELAIS_PUMP); brewTime = 0; brewTimer.start(); while(brewTime < TIME_PREINFUSION){ usleep(100000); } brewTimer.stop(); brewTime = 0; halRelaisOff(RELAIS_PUMP); sleep(TIME_SOAK/1000); logger(V_BREW, "Starting infusion...\n"); halResetFlow(); halRelaisOn(RELAIS_PUMP); brewTimer.start(); while(brewTime < TIME_INFUSION && halGetFlow() < TIME_DBLESPRESSO){ usleep(100000); } halRelaisOff(RELAIS_PUMP); brewTimer.stop(); brewTime = 0; logger(V_BREW, "Finish brewing\n"); logger(V_BREW, "Change state: IDLE\n"); state = STATE_IDLE; break; case STATE_BREWMANUAL: pause(); break; case STATE_CLEANING: pause(); break; case STATE_ERROR: pause(); break; } } pthread_exit(EXIT_SUCCESS); } /* * Saves value delivered by the signal */ void coffeeHandler(int signum, siginfo_t *siginfo, void *context) { sigval_t sigVal = (siginfo->si_value); sigValue = sigVal.sival_int; logger(V_BREW, "CoffeeHandler called with %d\n", sigValue); } /* * returns the Signal value from the last received Signal and clears the variable */ int getSigValue(void){ int tmp = sigValue; sigValue = 0; return tmp; } /* * Counter for the brew time * refresh every 200ms */ void brewTimeHandler (void){ brewTime += 200; }