jeudi 30 janvier 2014

Control your Velux roller shutter with Raspberry Pi and WebIOPi framework

In their basic version, VELUX roller shutters come with a 3 buttons remote controller.
This article proposes a method for controlling your device from a web page or automatizing openings or closures of all your VELUX roller shutters in your home.

Hardware list

Here is the hardware list for this project :

Raspberry Pi board

The Raspberry Pi is a famous credit-card-sized single-board computer than can be purchased for around 30$ (www.raspberrypi.org).
You will also need an Ethernet cable (or WiFi USB dongle) to connect your Raspberry Pi to your LAN.


Velux IO-HomeControl remote controller


This remote controller is required to transmit OPEN / CLOSE commands to IO-HomeControl devices.
You can buy this type of spare remote controller on Ebay market for around 10 $.
Using dedicated procedure, you can easily control several roller-shutters using this single remote controller.


In order to connect this remote controller to your Raspberry Pi and Relay board, you will have to solder some wires:
  • 3 wires (grey) for OPEN / CLOSE / STOP buttons. These wires will be connected to 3 independant relay switches. Each command is triggered by a Low state (Ground) pulse (pulse duration is about 500 ms).
  • 2 Power wires (red and black). These wires will be connected to +3.3v and GND pins of Raspberry Pi GPIO connector.

Relay-Switch board

Relays will be controlled by RaspBerry Pi GPIO and will be connected to the remote controller OPEN/CLOSE/STOP switches. Only three relays are required for this project.


Wiring overview

GPIO mapping :
  • GPIO 17 : OPEN
  • GPIO 18 : CLOSE
  • GPIO 27 : STOP


Software

Raspbian

Your Raspberry needs to run a Linux systems including all drivers for GPIO an network interface (WiFi or Ethernet).
The latest version of Raspbian Linux distribution is definitely a good choice (www.raspbian.org).

WebIOPi framework

The software part of this project is based on WebIOPi framework (https://code.google.com/p/webiopi/).
This framework is written in Python and also includes javascript/HTML library for designing web User Interfaces.
Please refer to WebIOPi website for installation and Python/javascript script / source customization instructions.

Web UI Snapshots

Once WebIOPi service is correctly started on your Raspbery 
This Web UI is accessible on the following :


Velux UP time : Set opening hours
Velux DOWN time : Set closure hour
Automatic UP/DOWN mode : Indicates AUTO mode state
Set Hours : Latch Opening/Closure hours defined in upper fields.
Set mode : Toggles AUTO mode (0=OFF / 1=ON)

Up : Asynchronous OPEN command
Stop : Asynchronous STOP command
Down : Asynchronous DOWN command

Customized source code

Python server script :

download

import webiopi
import datetime

GPIO = webiopi.GPIO

VELUX_UP = 17 # GPIO pin using BCM numbering
VELUX_DOWN = 18 # GPIO pin using BCM numbering
VELUX_STOP = 27 # GPIO pin using BCM numbering

VELUX_STATE = 0 # DOWN
AUTO_MODE = 1

HOUR_UP  = 9   # Turn Velux UP at
HOUR_DOWN = 19 # Turn Velux Down at

# setup function is automatically called at WebIOPi startup
def setup():
  global VELUX_STATE, AUTO_MODE

  # set the GPIO used for VELUX command to output
  GPIO.setFunction(VELUX_UP, GPIO.OUT)
  GPIO.setFunction(VELUX_DOWN, GPIO.OUT)

  # STOP function not used at this time
  GPIO.setFunction(VELUX_STOP, GPIO.OUT)
  GPIO.digitalWrite(VELUX_STOP, GPIO.LOW)


  # retrieve current datetime
  now = datetime.datetime.now()

  if (AUTO_MODE==1):
    # test time
    if ((now.hour >= HOUR_UP) and (now.hour < HOUR_DOWN)):
      GPIO.digitalWrite(VELUX_UP, GPIO.HIGH)
      webiopi.sleep(0.2)
      GPIO.digitalWrite(VELUX_UP, GPIO.LOW)
      VELUX_STATE = 1
    else: 
      GPIO.digitalWrite(VELUX_DOWN, GPIO.HIGH)
      webiopi.sleep(0.2)
      GPIO.digitalWrite(VELUX_DOWN, GPIO.LOW)
      VELUX_STATE = 0

# loop function is repeatedly called by WebIOPi 
def loop():
  global VELUX_STATE, AUTO_MODE

  # retrieve current datetime
  now = datetime.datetime.now()

  if (AUTO_MODE==1):
    # toggle VELUX UP all days at the correct time
    if ((now.hour == HOUR_UP) and (now.minute == 0) and (VELUX_STATE == 0)):
      GPIO.digitalWrite(VELUX_UP, GPIO.HIGH)
      webiopi.sleep(0.2)
      GPIO.digitalWrite(VELUX_UP, GPIO.LOW)
      VELUX_STATE = 1 #UP
        
    # toggle VELUX DOWN all days at the correct time
    if ((now.hour == HOUR_DOWN) and (now.minute == 0) and (VELUX_STATE == 1)):
      GPIO.digitalWrite(VELUX_DOWN, GPIO.HIGH)
      webiopi.sleep(0.2)
      GPIO.digitalWrite(VELUX_DOWN, GPIO.LOW)
      VELUX_STATE = 0 #DOWN
        
  # gives CPU some time before looping again
  webiopi.sleep(1)

# destroy function is called at WebIOPi shutdown
def destroy():
  GPIO.digitalWrite(VELUX_UP, GPIO.LOW)
  GPIO.digitalWrite(VELUX_DOWN, GPIO.LOW)
  GPIO.digitalWrite(VELUX_STOP, GPIO.LOW)


@webiopi.macro
def getHours():
    return "%d;%d" % (HOUR_UP, HOUR_DOWN)

@webiopi.macro
def setHours(on, off):
    global HOUR_UP, HOUR_DOWN
    HOUR_UP = int(on)
    HOUR_DOWN = int(off)
    return getHours()


@webiopi.macro
def getAutoMode():
    return "%d" % (AUTO_MODE)

@webiopi.macro
def setAutoMode():
    global AUTO_MODE
    
    if AUTO_MODE:
      AUTO_MODE=0
    else:
      AUTO_MODE=1
    return getAutoMode()

HTML code for Web UI :

download

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>VELUX Control</title>
        <script type="text/javascript" src="/webiopi.js"></script>
        <script type="text/javascript">
                webiopi().ready(function() {

                // Following function will process data received from set/getHours macro.
                var updateHours = function(macro, args, response) {
                    var hours = response.split(";");
                    // Following lines use jQuery functions
                    $("#inputOn").val(hours[0]);
                    $("#inputOff").val(hours[1]);
                }

                // Following function will process data received from getAutoMode macro.
                var updateAutoMode = function(macro, args, response) {
                    var tmp = response.split(";");
                    // Following lines use jQuery functions
                    $("#AutoMode").val(tmp[0]);
                }


                // Immediately call getHours macro to update the UI with current values
                webiopi().callMacro("getHours", [], updateHours);

                // Immediately call getAutoMode macro to update the UI with current values
                webiopi().callMacro("getAutoMode", [], updateAutoMode);



                // Create a button to call setLightHours macro
                var sendButton = webiopi().createButton("sendButton", "Set Hours", function() {
                   // Arguments sent to the macro
                    var hours = [$("#inputOn").val(), $("#inputOff").val()];
                    // Call the macro

                    webiopi().callMacro("setHours", hours, updateHours);



                // Append the button to the controls box using a jQuery function
                $("#controls").append(sendButton);


                // Create a button to call setAutoMode macro
                var automodeButton = webiopi().createButton("automodeButton", "Set Mode", function() {
                    // Call the macro
                    webiopi().callMacro("setAutoMode",[], updateAutoMode);
                });

                // Append the button to the controls box using a jQuery function
                $("#controls").append(automodeButton);

                // create a "UP" button that output a single pulse on GPIO 17
                //var button_up = webiopi().createPulseButton("up", "Up", 17);
                var button_up = webiopi().createSequenceButton("up","Up",17,100,"011110");
                $("#controls").append(button_up); // append button to content div

                // create a "STOP" button that output a single pulse on GPIO 27
                var button_stop = webiopi().createSequenceButton("stop","Stop",27,200,"011110");
                $("#controls").append(button_stop); // append button to content div

                // create a "DOWN" button that output a single pulse on GPIO 18
                //var button_down = webiopi().createPulseButton("down", "Down", 18);
                var button_down = webiopi().createSequenceButton("down","Down",18,100,"011110");
                $("#controls").append(button_down); // append button to content div

                // Refresh GPIO buttons
                // pass true to refresh repeatedly of false to refresh once
                webiopi().refreshGPIO(true);

        });

        </script>
        <style type="text/css">
                button {
                        display: block;
                        margin: 5px 5px 5px 5px;
                        width: 160px;
                        height: 45px;
                        font-size: 24pt;
                        font-weight: bold;
                        color: white;
                }
        </style>
</head>

<body>
<div align="center">
Velux UP time (hour):<input type="text" id="inputOn" /><br/>
Velux DOWN time (hour): <input type="text" id="inputOff" /><br/>
Automatic UP/DOWN mode: <input type="text" id="AutoMode" /><br/>
<HR>

<div id="controls"></div>
</div>
</body>

</html>


36 commentaires:

  1. Very nice! I was just wondering about the "Using dedicated procedure, you can easily control several roller-shutters using this single remote controller"

    Do you have such procedure on how to set one remote to control 2 or more windows at the same time?

    Thanks

    RépondreSupprimer
    Réponses
    1. Hello,
      Yes, the procedure is described in Velux KUX100 user-guide.
      Here is the usefull part :

      The example shows three VELUX control systems, A, B and C, each with its own roller shutter, where the remote control from system C is to be set to operate roller shutters in systems A and B as well.
      The next two steps must be completed within 10 minutes.
      1. Press RESET button (for at least 10 seconds) on the back of remote controls A and B with a pointed object.
      2. Press RESET button (1 second) on the back of remote control C. The products in the three systems can now be operated via remote control C. The products in control systems A and B can still be operated with the remote controls from their respective systems.

      Supprimer
  2. Hello, the post is very interesting. Would it be possible to get a more accurate diagram of the wiring? Thanks in advanced.

    RépondreSupprimer
  3. Hello,

    Can you post the separted files here ( link ). I got a lot of errors. And I don't know why. ( python error )

    Thanks!!!

    RépondreSupprimer
  4. Hello,
    Yes !
    Files are now accessible through "download" links

    RépondreSupprimer
    Réponses
    1. Thanks! Everything works now!!

      Now tuning your code.Where to change the delay? My velux must be 30 seconds UP then shutdown ( relais )

      Thanks !

      Supprimer
  5. Ce commentaire a été supprimé par l'auteur.

    RépondreSupprimer
  6. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  7. Hi, thanks so much for the great info and guide, I'm looking to control my 2 velux window blinds but I'm not sure about the remote, when I search on ebay.co.uk the remotes are all £100+

    Could you point me in the direction of a suitable remote please :)
    Are there cheap Chinese 'rip offs' I can use?

    RépondreSupprimer
  8. Hi,
    The remote I used are the following :
    Velux KUX 100 Remote Control.
    As a last possibility, you can try to order one as a spare (replacement) part.
    I'm not aware about any Chinese clones...but interested if it exists.

    RépondreSupprimer
  9. Thanks for getting back to me. I may well have to buy a kux 100 or 110, I was hoping to avoid the extra cost and use the pi as a control box rather than a switch. This guide will be a bible for that though so thanks :) My next dilemma is finding out if the kux can control 2 blinds of different lengths. I've been reading that upon first setup it learns the length of one blind but can't find out if it has the intelligence to know there are 2 blinds. Could you tell me please, is there more than one set of terminals? Some places say it can control up to 5 blinds but I don't know if that's just wiring them all in parallel? I guess it should be more sophisticated than that though to allow for varying motor speeds / fatigue.
    Are you able to shed some light? Many thanks :)

    RépondreSupprimer
  10. Thanks for getting back to me. I may well have to buy a kux 100 or 110, I was hoping to avoid the extra cost and use the pi as a control box rather than a switch. This guide will be a bible for that though so thanks :) My next dilemma is finding out if the kux can control 2 blinds of different lengths. I've been reading that upon first setup it learns the length of one blind but can't find out if it has the intelligence to know there are 2 blinds. Could you tell me please, is there more than one set of terminals? Some places say it can control up to 5 blinds but I don't know if that's just wiring them all in parallel? I guess it should be more sophisticated than that though to allow for varying motor speeds / fatigue.
    Are you able to shed some light? Many thanks :)

    RépondreSupprimer
  11. Wow, this is a really clever use of the Raspberry Pi! I actually had roller shutters installed about six months ago, and I've been looking for a way to automate them. I may have to look into this, and see if I could get it to work with my shutters. Thanks so much for writing, this is ingenious!

    http://www.qldblinds.com/security

    RépondreSupprimer
  12. Ce commentaire a été supprimé par l'auteur.

    RépondreSupprimer
  13. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  14. Thanks for this! We had some Velux shutters installed during some major renovations and I'd just assumed they'd be on the same bus system as the other blinds (which we still haven't installed!). I ebayed all but one of the KLR200 control pads and used the money to buy the Pi, swicthes and basic remotes.

    I've added some features and uploaded to git

    https://github.com/richdyer2000/shutterberry

    1) "nicer" HTML interface which uses standard HTML rather than the WebIOPi library. Far from perfect, but it's my first attempt and allows e.g. check box to be used for the schedule.
    2) Separate times (to the minute) for weekdays, Saturday and Sunday
    3) Retrieval of public holidays from iCal and possibility to use Sunday times for public holidays
    4) Storage of the schedule in an ASCII file to cope with reboot of the Pi
    5) And Coming soon, a daylight mask to delay opening until sunrise and bring forward closing to sunset

    Cheers

    Rich

    RépondreSupprimer
    Réponses
    1. Hi Rich,
      Thank you very much !
      Cheers,
      Eric

      Supprimer
    2. Rich, I have VCS (solar controlled) Skylights. Can you confirm if you have the same? I have 5 VCS skylights with KLR200 pads and am hoping your post implies this will work for me.

      Supprimer
  15. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  16. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  17. Ce commentaire a été supprimé par l'auteur.

    RépondreSupprimer
  18. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  19. Ce commentaire a été supprimé par l'auteur.

    RépondreSupprimer
  20. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  21. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  22. Hi, i don't know where to buy the Velux Controller IO-HomeControl.
    Can you send me some links on ebay?
    Thank you.

    RépondreSupprimer
  23. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  24. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  25. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  26. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  27. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  28. Can you stop spamming this great post with pitiful 'cheap shot' adverts for your company. Why would anyone want to do business with vultures like you.

    RépondreSupprimer
  29. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  30. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  31. Ce commentaire a été supprimé par un administrateur du blog.

    RépondreSupprimer
  32. ADV shopfronts is one of the best company for Roller Shutters repair services. Contact us in case of emergency, we are available 24/7. We provide aluminium roller shutters, glass doors,etc. Visit our official website for more information.

    RépondreSupprimer