Roller shutter(s_cover) on Domoticz



  • hello. I'm building and remake of Simple cover actuator from @dpressle (here), i call it a remake because my shutter have 2 relays ,one for UP and 1 for Down(not power and direction like original one)

    and i'm having problems to make it work like "blind percentage" switch type on Domoticz.
    i read that they were not supported 4 years ago but i think it was already corrected.Right?
    picture above its what i got on domoticz, up,down and stop works,but percentage its buggy ,not respond, and status its always closed,even when windows it' full open(full up).

    0_1564994876501_domoticz.jpg

    my edited code

    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_RFM69
    
    //#define MY_RF24_PA_LEVEL RF24_PA_LOW
    
    //#define MY_REPEATER_FEATURE
    
    
    
    #include <Bounce2.h>
    #include <MySensors.h>
    #include <SPI.h>
    
    // uncomment if we want to manually assign an ID
    //#define MY_NODE_ID 1 /
    
    #define BUTTON_UP_PIN 5  // Arduino Digital I/O pin number for up button
    #define BUTTON_DOWN_PIN 6  // Arduino Digital I/O pin number for down button
    //#define BUTTON_STOP_PIN 7  // Arduino Digital I/O pin number for stop button
    #define RELAY_UP_PIN 3  // Arduino Digital I/O pin number for direction relay
    #define RELAY_DOWN_PIN 4  // Arduino Digital I/O pin number for power relay
    #define RELAY_ON 0
    #define RELAY_OFF 1
    //#define RELAY_DOWN 1
    //#define RELAY_UP 0
    #define DIRECTION_DOWN 1
    #define DIRECTION_UP 0
    #define SKETCH_NAME "Cover"
    #define SKETCH_VER "2.0"
    #define CHILD_ID_COVER 0   // sensor Id of the sensor child
    #define STATE_UP 100 // 100 is open - up
    #define STATE_DOWN 0 // 0 is closed - down
    //#define CHILD_ID_CALIBRATE 1   // sensor Id of the sensor child to calibrate
    #define CHILD_ID_SET 1   // sensor Id of the sensor child to init the roll time
    #define PRESENT_MESSAGE "shuttle for Livingroom"
    const int LEVELS = 100; //the number of levels
    float rollTime = 28.0; //the overall rolling time of the shutter
    const bool IS_ACK = false; //is to acknowlage
    static bool initial_state_sent = false;//for hass we need at list one state send at begining
    
    // debouncing parameters
    int value = 0;
    int oldValueUp = 0;
    int oldValueDown = 0;
    //int value1=0;int value2=0;
    int oldValueStop=0;
    int oldValueStop1=0;
    //static unsigned long last_interrupt_time_up = 0;
    //static unsigned long last_interrupt_time_down = 0;
    //static unsigned long debounce_time = 200;
    
    Bounce debouncerUp = Bounce();
    Bounce debouncerDown = Bounce();
    //Bounce debouncerStop = Bounce();
    
    // shutter position parameters
    float timeOneLevel = rollTime / LEVELS;
    int requestedShutterLevel = 0;
    int currentShutterLevel = 0;
    unsigned long lastLevelTime = 0;
    bool isMoving = false;
    int directionUpDown;
    
    enum CoverState {
      STOP,
     UP, // Window covering. Up.
      DOWN, // Window covering. Down.
    };
    
    static int coverState = STOP;
    
    MyMessage msgUP(CHILD_ID_COVER, V_UP);
    MyMessage msgDown(CHILD_ID_COVER, V_DOWN);
    MyMessage msgStop(CHILD_ID_COVER, V_STOP);
    MyMessage msgPercentage(CHILD_ID_COVER, V_PERCENTAGE);
    //MyMessage msgCode(CHILD_ID_SET, V_IR_SEND);
    
    void sendState() {
      // Send current state and status to gateway.
      send(msgUP.set(coverState == UP));
      send(msgDown.set(coverState == DOWN));
      send(msgStop.set(coverState == STOP));
      send(msgPercentage.set(currentShutterLevel));
    }
    
    void shuttersUp(void) {
    #ifdef MY_DEBUG
      Serial.println("Shutters going up");
    #endif
      if (digitalRead(RELAY_DOWN_PIN) == RELAY_ON) {
          digitalWrite(RELAY_DOWN_PIN, RELAY_OFF);
          delay(20);
      }
      digitalWrite(RELAY_UP_PIN, RELAY_ON);
     
    
      directionUpDown = DIRECTION_UP;
      isMoving = true;
      coverState = UP;
      sendState();
    }
    
    void shuttersDown(void) {
    #ifdef MY_DEBUG
      Serial.println("Shutters going down");
    #endif
      if (digitalRead(RELAY_UP_PIN) ==  RELAY_ON) {
         digitalWrite(RELAY_UP_PIN, RELAY_OFF);
         delay(20);
      }
      digitalWrite(RELAY_DOWN_PIN, RELAY_ON);
      
    
      directionUpDown = DIRECTION_DOWN;
      isMoving = true;
      coverState = DOWN;
      sendState();
    }
    
    void shuttersHalt(void) {
    #ifdef MY_DEBUG
      Serial.println("Shutters halted X");
    #endif
     // Serial.println("2 BOTOES OFF");
       // if (digitalRead((RELAY_UP_PIN) || (RELAY_DOWN_PIN) )==  RELAY_ON) {
        digitalWrite(RELAY_UP_PIN, RELAY_OFF);
        digitalWrite(RELAY_DOWN_PIN, RELAY_OFF);
        delay(20);
       //}
    
      isMoving = false;
      requestedShutterLevel = currentShutterLevel;
    #ifdef MY_DEBUG
      Serial.println("saving state to: ");
      Serial.println(String(currentShutterLevel));
    #endif
      saveState(CHILD_ID_COVER, currentShutterLevel);
      coverState = STOP;
      //sendState();
    }
    
    void changeShuttersLevel(int level) {
      int dir = (level > currentShutterLevel) ? DIRECTION_UP : DIRECTION_DOWN;
      if (isMoving && dir != directionUpDown) {
        shuttersHalt();
      }
      requestedShutterLevel = level;
    }
    
    void initShutters() {
    #ifdef MY_DEBUG
      Serial.println("Init Cover");
    #endif
      shuttersUp();
      delay((rollTime + timeOneLevel * LEVELS) * 1000);
      currentShutterLevel = STATE_UP;
      requestedShutterLevel = currentShutterLevel;
    }
    
    void receive(const MyMessage &message) {
    #ifdef MY_DEBUG
      Serial.println("recieved incomming message");
      Serial.println("Recieved message for sensor: ");
      Serial.println(String(message.sensor));
      Serial.println("Recieved message with type: ");
      Serial.println(String(message.type));
    #endif
      if (message.sensor == CHILD_ID_COVER) {
        switch (message.type) {
          case V_UP:
            //Serial.println(", New status: V_UP");
            changeShuttersLevel(STATE_UP);
            //state = UP;
            //sendState();
            break;
    
          case V_DOWN:
            //Serial.println(", New status: V_DOWN");
            changeShuttersLevel(STATE_DOWN);
            //state = DOWN;
            //sendState();
            break;
    
          case V_STOP:
            //Serial.println(", New status: V_STOP");
            shuttersHalt();
            //state = IDLE;
            //sendState();
            break;
    
          case V_PERCENTAGE:
            //Serial.println(", New status: V_PERCENTAGE");
            //          if (!initial_state_sent) {
            //            #ifdef MY_DEBUG
            //            Serial.println("Receiving initial value from controller");
            //            #endif
            //            initial_state_sent = true;
            //          }
            int per = message.getInt();
            if (per > STATE_UP) {
              per = STATE_UP;
            }
            changeShuttersLevel(per);
            //InitShutters(message.getInt());//send value < 0 or > 100 to calibrate
            //sendState();
            break;
        }
      } 
    else if (message.sensor ==  CHILD_ID_SET) {
    
        if (message.type == V_VAR1) {
          Serial.println(", New status: V_VAR1, with payload: ");
          String strRollTime = message.getString();
          rollTime = strRollTime.toFloat();
          Serial.println("rolltime value: ");
          Serial.println(String(rollTime));
          saveState(CHILD_ID_SET, rollTime);
        }
      }
    #ifdef MY_DEBUG
      Serial.println("exiting incoming message");
    #endif
      return;
    }
    
    void before() {
    
      // Setup the button
      pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
      // Activate internal pull-up
      digitalWrite(BUTTON_UP_PIN, HIGH);
      //attachInterrupt(digitalPinToInterrupt(BUTTON_UP_PIN), upButtonPress, RISING);
      
      pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);
      // Activate internal pull-up
      digitalWrite(BUTTON_DOWN_PIN, HIGH);
     // attachInterrupt(digitalPinToInterrupt(BUTTON_DOWN_PIN), downButtonPress, RISING);
    
      //pinMode(BUTTON_STOP_PIN, INPUT_PULLUP);
      // Activate internal pull-up
      //digitalWrite(BUTTON_STOP_PIN, HIGH);
    
      // After setting up the button, setup debouncer
      debouncerUp.attach(BUTTON_UP_PIN);
      debouncerUp.interval(5);
      // After setting up the button, setup debouncer
      debouncerDown.attach(BUTTON_DOWN_PIN);
      debouncerDown.interval(5);
      // After setting up the button, setup debouncer
     // debouncerStop.attach(BUTTON_UP_PIN&&BUTTON_UP_PIN);
     // debouncerStop.interval(5);
    
      // Make sure relays are off when starting up
      digitalWrite(RELAY_UP_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_UP_PIN, OUTPUT);
    
      // Make sure relays are off when starting up
      digitalWrite(RELAY_DOWN_PIN, RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(RELAY_DOWN_PIN, OUTPUT);
    }
    
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo(SKETCH_NAME, SKETCH_VER);
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_COVER, S_COVER, PRESENT_MESSAGE, IS_ACK);
      //present(CHILD_ID_SET, S_CUSTOM);
    }
    
    void setup(void) {
      //set up roll time if the saved value is not 255
      Serial.println("getting rolltime from eeprom: ");
      float tmpRollTime = loadState(CHILD_ID_SET);
      if (tmpRollTime != 0xff) {
        rollTime = tmpRollTime;
      }
      Serial.println(String(rollTime));
    
      int state = loadState(CHILD_ID_COVER);
    #ifdef MY_DEBUG
      Serial.println("getting state from eeprom: ");
      Serial.println(String(state));
    #endif
      if (state == 0xff) {
        initShutters();
      } else {
        changeShuttersLevel(state);
      }
    }
    
    void loop(void) {
      if (!initial_state_sent) {
    #ifdef MY_DEBUG
        Serial.println("Sending initial value");
    #endif
        sendState();
        
       // send(msgCode.set('20.0'));
        //    #ifdef MY_DEBUG
        //    Serial.println("Requesting initial value from controller");
        //    #endif
        //    request(CHILD_ID_COVER, V_PERCENTAGE);
        //    wait(2000, C_SET, V_PERCENTAGE);
        initial_state_sent = true;
      }
    
      debouncerUp.update();
      value = debouncerUp.read();
      if (value == 0 && value != oldValueUp) {
        changeShuttersLevel(STATE_UP);
        //state = UP;
        //sendState();
      }
      oldValueUp = value;
    
      debouncerDown.update();
      value = debouncerDown.read();
      if (value == 0 && value != oldValueDown) {
        changeShuttersLevel(STATE_DOWN);
        //state = DOWN;
        //sendState();
      }
      oldValueDown = value;
    
     // debouncerStop.update();
      //value = debouncerStop.read();
      //if (value == 0 && value !=( oldValueUp||oldValueDown)) {
    
    // debouncerDown.update();  
    // debouncerUp.update();
      value = debouncerUp.rose();
       if (value == 0 && value != oldValueStop){
       shuttersHalt();
       }
       oldValueStop = value;
       
      value = debouncerDown.rose();
        if (value == 0 && value != oldValueStop1){
        
        shuttersHalt();
       }
        oldValueStop1 = value;
    
    
      if (isMoving) {
        unsigned long _now = millis();
        if (_now - lastLevelTime >= timeOneLevel * 1000) {
          if (directionUpDown == DIRECTION_UP) {
            currentShutterLevel += 1;
          } else {
            currentShutterLevel -= 1;
          }
    #ifdef MY_DEBUG
          //Serial.println(String(requestedShutterLevel));
          Serial.println(String(currentShutterLevel));
    #endif
          lastLevelTime = millis();
          //send(msgPercentage.set(currentShutterLevel));
        }
    
        
        if (currentShutterLevel == requestedShutterLevel){
        //if ((currentShutterLevel == requestedShutterLevel) || (digitalRead(((RELAY_UP_PIN) ==1) &&(RELAY_DOWN_PIN) ==1))) {
          shuttersHalt();
        }
      } 
      else if (requestedShutterLevel != currentShutterLevel) {
        if (requestedShutterLevel > currentShutterLevel) {
          shuttersUp();
        }
        else {
          shuttersDown();
        }
        lastLevelTime = millis();
      }
    }
    
    

    what am i missing? thank you .


  • Mod

    @tmaster what does the debug log from the node say?



  • thank you for reply @mfalkvidd
    Payload like 100 shoud be 100% on domoticz, right? how does domoticz "know" that a blindcover /or shutter is open or close? because it's not respondig to that...

     
     __  __       ____
    |  \/  |_   _/ ___|  ___ _ __  ___  ___  _ __ ___
    | |\/| | | | \___ \ / _ \ `_ \/ __|/ _ \| `__/ __|
    | |  | | |_| |___| |  __/ | | \__ \  _  | |  \__ \
    |_|  |_|\__, |____/ \___|_| |_|___/\___/|_|  |___/
            |___/                      2.3.1
    
    16 MCO:BGN:INIT NODE,CP=RRNNA---,REL=255,VER=2.3.1
    26 MCO:BGN:BFR
    28 TSM:INIT
    30 TSF:WUR:MS=0
    34 TSM:INIT:TSP OK
    34 TSF:SID:OK,ID=4
    36 TSM:FPAR
    1257 TSF:MSG:SEND,4-4-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
    1423 TSF:MSG:READ,0-0-4,s=255,c=3,t=8,pt=1,l=1,sg=0:0
    1429 TSF:MSG:FPAR OK,ID=0,D=1
    3264 TSM:FPAR:OK
    3264 TSM:ID
    3266 TSM:ID:OK
    3268 TSM:UPL
    3276 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
    3315 TSF:MSG:READ,0-0-4,s=255,c=3,t=25,pt=1,l=1,sg=0:1
    3321 TSF:MSG:PONG RECV,HP=1
    3325 TSM:UPL:OK
    3328 TSM:READY:ID=4,PAR=0,DIS=1
    3540 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
    3567 TSF:MSG:READ,0-0-4,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
    3786 TSF:MSG:SEND,4-4-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.3.1
    4005 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0
    4046 TSF:MSG:READ,0-0-4,s=255,c=3,t=6,pt=0,l=1,sg=0:M
    4263 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=11,pt=0,l=5,sg=0,ft=0,st=OK:Cover
    4483 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=12,pt=0,l=3,sg=0,ft=0,st=OK:2.0
    4708 TSF:MSG:SEND,4-4-0-0,s=0,c=0,t=5,pt=0,l=22,sg=0,ft=0,st=OK:shuttle for Livingroom
    4716 MCO:REG:REQ
    4929 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
    4956 TSF:MSG:READ,0-0-4,s=255,c=3,t=27,pt=1,l=1,sg=0:1
    4962 MCO:PIM:NODE REG=1
    4964 MCO:BGN:STP
    getting rolltime from eeprom: 
    28.00
    getting state from eeprom: 
    0
    4968 MCO:BGN:INIT OK,TSP=1
    Sending initial value
    5185 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=29,pt=1,l=1,sg=0,ft=0,st=OK:0
    5402 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=30,pt=1,l=1,sg=0,ft=0,st=OK:0
    5619 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=31,pt=1,l=1,sg=0,ft=0,st=OK:1
    5838 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=3,pt=2,l=2,sg=0,ft=0,st=OK:0
    

    .
    .
    .
    .
    after I give an order of CLOSE (DOWN) shutter (v_percentage=0)

    ------------     *(HERE WAS AT 100% AND I ORDER TO GO 0%(CLOSED)* -------------------
    
    exiting incoming message
    Shutters going down
    612509 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=29,pt=1,l=1,sg=0,ft=0,st=OK:0
    612728 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=30,pt=1,l=1,sg=0,ft=0,st=OK:1
    612947 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=31,pt=1,l=1,sg=0,ft=0,st=OK:0
    613167 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=3,pt=2,l=2,sg=0,ft=0,st=OK:100
    99
    98
    
    
    
    (...)
    
    7
    6
    5
    4
    3
    2
    1
    0
    Shutters halted X
    saving state to: 
    0
    645519 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=29,pt=1,l=1,sg=0,ft=0,st=OK:0
    645738 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=30,pt=1,l=1,sg=0,ft=0,st=OK:0
    645957 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=31,pt=1,l=1,sg=0,ft=0,st=OK:1
    646176 TSF:MSG:SEND,4-4-0-0,s=0,c=1,t=3,pt=2,l=2,sg=0,ft=0,st=OK:0
    
    ------------    *(HERE REACH 0%)* -------------------
    


  • so, i assume that my question it's not obvious and because that domoticz still have this bug...
    i will leave it without percentage bar(just as blind) because its just to opena and close that shutter at night/morning

    nobody have an sensor with S_COVER presented on Domoticz working good?



  • I have similar problem. Some time ago I even wrote a nice piece of code to update roller shutter position if changed from buttons. But domoticz just does not seem to understand values the sensor sends. So I confirm, blinds percentage is buggy.


 

269
Online

8.7k
Users

9.5k
Topics

99.6k
Posts