103 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			103 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
| #include "GwButtons.h"
 | |
| #include "GwHardware.h"
 | |
| #include "GwApi.h"
 | |
| #include "GwLeds.h"
 | |
| 
 | |
| class FactoryResetRequest: public GwMessage{
 | |
|     private:
 | |
|         GwApi *api;
 | |
|     public:
 | |
|         FactoryResetRequest(GwApi *api):GwMessage(F("reset button")){
 | |
|             this->api=api;
 | |
|         }
 | |
|         virtual ~FactoryResetRequest(){}
 | |
|     protected:    
 | |
|         virtual void processImpl(){
 | |
|             api->getLogger()->logDebug(GwLog::LOG,"reset request processing");
 | |
|             api->getConfig()->reset();
 | |
|             xTaskCreate([](void *p){
 | |
|             delay(500);
 | |
|             ESP.restart();
 | |
|             vTaskDelete(NULL);
 | |
|             },"reset",1000,NULL,0,NULL);
 | |
|         };
 | |
| };
 | |
| void handleButtons(void *param){
 | |
|     GwApi *api=(GwApi*)param;
 | |
|     GwLog *logger=api->getLogger();
 | |
|     #ifndef GWBUTTON_PIN
 | |
|         LOG_DEBUG(GwLog::LOG,"no button pin defined, do not watch");
 | |
|         vTaskDelete(NULL);
 | |
|         return;
 | |
|     #else
 | |
|     #ifndef GWBUTTON_ACTIVE
 | |
|     int activeState=0; 
 | |
|     #else
 | |
|     int activeState=GWBUTTON_ACTIVE;
 | |
|     #endif
 | |
|     #ifdef GWBUTTON_PULLUPDOWN
 | |
|     bool pullUpDown=true;
 | |
|     #else
 | |
|     bool pullUpDown=false;
 | |
|     #endif
 | |
|     uint8_t mode=INPUT;
 | |
|     if (pullUpDown){
 | |
|         mode=activeState?INPUT_PULLDOWN:INPUT_PULLUP;
 | |
|     }
 | |
|     pinMode(GWBUTTON_PIN,mode);
 | |
|     unsigned long lastPressed=0;
 | |
|     unsigned long firstPressed=0;
 | |
|     unsigned long lastReport=0;
 | |
|     const unsigned long OFF_TIME=20;
 | |
|     const unsigned long REPORT_TIME=1000;
 | |
|     const unsigned long HARD_REST_TIME=10000;
 | |
|     GwLedMode ledMode=LED_OFF;
 | |
|     while(true){
 | |
|         delay(10);
 | |
|         int current=digitalRead(GWBUTTON_PIN);
 | |
|         unsigned long now=millis();
 | |
|         if (current != activeState){
 | |
|             if (lastPressed != 0 && (lastPressed+OFF_TIME) < now){
 | |
|                 lastPressed=0; //finally off
 | |
|                 firstPressed=0;
 | |
|                 if (ledMode != LED_OFF){
 | |
|                     setLedMode(LED_GREEN); //TODO: better "go back"
 | |
|                     ledMode=LED_OFF;
 | |
|                 }
 | |
|                 LOG_DEBUG(GwLog::LOG,"Button press stopped");
 | |
|             }
 | |
|             continue;
 | |
|         }
 | |
|         lastPressed=now;
 | |
|         if (firstPressed == 0) {
 | |
|             firstPressed=now;
 | |
|             LOG_DEBUG(GwLog::LOG,"Button press started");
 | |
|             lastReport=now;
 | |
|         }
 | |
|         if (lastReport != 0 && (lastReport + REPORT_TIME) < now ){
 | |
|             LOG_DEBUG(GwLog::LOG,"Button active for %ld",(now-firstPressed));
 | |
|             lastReport=now;
 | |
|         }
 | |
|         GwLedMode nextMode=ledMode;
 | |
|         if (now > (firstPressed+HARD_REST_TIME/2)){
 | |
|             nextMode=LED_BLUE;
 | |
|         }
 | |
|         if (now > (firstPressed+HARD_REST_TIME*0.9)){
 | |
|             nextMode=LED_RED;
 | |
|         }
 | |
|         if (ledMode != nextMode){
 | |
|             setLedMode(nextMode);
 | |
|             ledMode=nextMode;
 | |
|         }
 | |
|         if (now > (firstPressed+HARD_REST_TIME)){
 | |
|             LOG_DEBUG(GwLog::ERROR,"Factory reset by button");
 | |
|             GwMessage *r=new FactoryResetRequest(api);
 | |
|             api->getQueue()->sendAndForget(r);
 | |
|             r->unref();
 | |
|             firstPressed=0;
 | |
|             lastPressed=0;
 | |
|         }
 | |
|     }
 | |
|     vTaskDelete(NULL);
 | |
|     #endif
 | |
| } |