4 Replies Latest reply on May 28, 2015 10:52 AM by LightBulb

    Light Switch replacement project

    LightBulb

      Update: now with presence and light sensor. Looking for Blueproximity package to let it react to a mobile phone in a vicinity.

      Update: 25th May 2015 now v2 in a smaller box. Blueproximity is just a python script, so it should be easy to fit it to the project.

      IMG-20150525-00051.jpg

       

      Original Post

      Today I have finished a first hardware/software prototype for a light switch replacement based on the Edison. The idea is to have a kit that will allow for a drop-in zero-soldering replacement for common wall light switch. The advantage is that your Edison will be connected to the power and have a default place in any room. You can immediately start interacting with it in a real environment. Obviously nothing to stop you from extending both software and hardware.

       

       

      My goal is to kickstart the development of this type of a Edison kit. Later on it would be great to have a custom breakout board. If you interested please let me know. I plan to add all needed documentation to build it from parts.

       

      Currently it uses an Edison +Arduino+Seeed Grove board, Grove Relay, Grove touch sensor and some standard 220/110V electrical hardware.  Everything is accommodated in oversize plastic boxes. The final version should ideally be not much bigger then the common wall light switch. The light brown plastic case on the back of the box (where the light bulb is connected) is the common plastic case for the switch. So this should roughly be the size of the kit when assembled.

       

      IMG-20150517-00008.jpgIMG-20150517-00006.jpgIMG-20150517-00009.jpg

       

       

      #There are three files in the project

      /etc/init.d/startLightSwitch.sh

      /home/root/lightSwitchDaemon.py

      /home/root/daemon.py

       

      ######################################### startLightSwitch.sh #########################################################

      #! /bin/sh

      /home/root/lightSwitchDaemon.py start

      ######################################### END startLightSwitch.sh #####################################################

       

      cp startLightSwitch.sh /etc/init.d/

      update-rc.d startLightSwitch.sh defaults 19

       

      ######################################## lightSwitchDaemon.py ##########################################################

      #!/usr/bin/env python

       

      import sys, time

      sys.path.append(".")

      from daemon import Daemon

      import mraa

      class Toggle:

        state = 0

       

      class MyDaemon(Daemon):

          def run(self):

              t=Toggle()

              mraa.Gpio(8).dir(mraa.DIR_OUT) # connect Relay to the D8

              def pressed(args):

                  if t.state==0:

                      mraa.Gpio(8).write(1)

                      t.state = 1

                  else:

                      mraa.Gpio(8).write(0)

                      t.state = 0

              x = mraa.Gpio(4) # connect button to the D4

              x.dir(mraa.DIR_IN)

              x.isr(mraa.EDGE_RISING, pressed, pressed)

              print ("started")

              while True:

                  time.sleep(15)

       

       

      if __name__ == "__main__":

          daemon = MyDaemon('/tmp/lightSwitchDaemon.pid')

          if len(sys.argv) == 2:

              if 'start' == sys.argv[1]:

                  daemon.start()

              elif 'stop' == sys.argv[1]:

                  daemon.stop()

              elif 'restart' == sys.argv[1]:

                  daemon.restart()

              else:

                  print "Unknown command"

                  sys.exit(2)

              sys.exit(0)

          else:

              print "usage: %s start|stop|restart" % sys.argv[0]

              sys.exit(2)

      ######################################## END lightSwitchDaemon.py ##########################################################

       

       

      ############################################# daemon.py ########################################################

      #!/usr/bin/env python

       

      import sys, os, time, atexit

      from signal import SIGTERM

       

      class Daemon:

          """

          A generic daemon class.

       

          Usage: subclass the Daemon class and override the run() method

          """

          def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):

              self.stdin = stdin

              self.stdout = stdout

              self.stderr = stderr

              self.pidfile = pidfile

       

          def daemonize(self):

              """

              do the UNIX double-fork magic, see Stevens' "Advanced

              Programming in the UNIX Environment" for details (ISBN 0201563177)

              http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16

              """

              try:

                  pid = os.fork()

                  if pid > 0:

                      # exit first parent

                      sys.exit(0)

              except OSError, e:

                  sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))

                  sys.exit(1)

       

              # decouple from parent environment

              os.chdir("/")

              os.setsid()

              os.umask(0)

       

              # do second fork

              try:

                  pid = os.fork()

                  if pid > 0:

                      # exit from second parent

                      sys.exit(0)

              except OSError, e:

                  sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))

                  sys.exit(1)

       

              # redirect standard file descriptors

              sys.stdout.flush()

              sys.stderr.flush()

              si = file(self.stdin, 'r')

              so = file(self.stdout, 'a+')

              se = file(self.stderr, 'a+', 0)

              os.dup2(si.fileno(), sys.stdin.fileno())

              os.dup2(so.fileno(), sys.stdout.fileno())

              os.dup2(se.fileno(), sys.stderr.fileno())

       

              # write pidfile

              atexit.register(self.delpid)

              pid = str(os.getpid())

              file(self.pidfile,'w+').write("%s\n" % pid)

       

          def delpid(self):

              os.remove(self.pidfile)

       

          def start(self):

              """

              Start the daemon

              """

              # Check for a pidfile to see if the daemon already runs

              try:

                  pf = file(self.pidfile,'r')

                  pid = int(pf.read().strip())

                  pf.close()

              except IOError:

                  pid = None

       

              if pid:

                  message = "pidfile %s already exist. Daemon already running?\n"

                  sys.stderr.write(message % self.pidfile)

                  sys.exit(1)

       

              # Start the daemon

              self.daemonize()

              self.run()

       

          def stop(self):

              """

              Stop the daemon

              """

              # Get the pid from the pidfile

              try:

                  pf = file(self.pidfile,'r')

                  pid = int(pf.read().strip())

                  pf.close()

              except IOError:

                  pid = None

       

              if not pid:

                  message = "pidfile %s does not exist. Daemon not running?\n"

                  sys.stderr.write(message % self.pidfile)

                  return # not an error in a restart

       

              # Try killing the daemon process

              try:

                  while 1:

                      os.kill(pid, SIGTERM)

                      time.sleep(0.1)

              except OSError, err:

                  err = str(err)

                  if err.find("No such process") > 0:

                      if os.path.exists(self.pidfile):

                          os.remove(self.pidfile)

                  else:

                      print str(err)

                      sys.exit(1)

       

          def restart(self):

              """

              Restart the daemon

              """

              self.stop()

              self.start()

       

          def run(self):

              """

              You should override this method when you subclass Daemon. It will be called after the process has been

              daemonized by start() or restart().

              """

      ############################################# END daemon.py ########################################################

       

      status update

        • 1. Re: Light Switch replacement project
          LightBulb

          Yesterday I have added a light sensor and a presence sensor

          ######################################## lightSwitchDaemon.py ##########################################################

          #!/usr/bin/env python

           

          import sys, time

          sys.path.append(".")

          from daemon import Daemon

          import mraa

           

          class Toggle:

            state = 0

            lock = 0

           

          print ("command accepted")

           

          class MyDaemon(Daemon):

              def run(self):

                  t=Toggle()

                  dw_relay = mraa.Gpio(8) # connect Relay to the D8

                  dw_relay.dir(mraa.DIR_OUT)

                  dr_touch = mraa.Gpio(4) # connect touch sensor to the D4

                  dr_touch.dir(mraa.DIR_IN)

                  dr_presence = mraa.Gpio(3) # connect presence sensor to the D3

                  dr_presence.dir(mraa.DIR_IN)

                  ar_light = mraa.Aio(0) # connect the analog light sensor to the A0

           

                  def pressed(args):

                      if t.state+t.lock==0:

                          dw_relay.write(1)

                          t.state = 1

                      else:

                          dw_relay.write(0)

                          t.state = 0 

                          t.lock = 1

                          time.sleep(20) # block the presence sensor and going on/off which is damaging for most lamps

                          t.lock = 0

                  def presence_detected(args):

                      if ar_light.read()<160: # it's dark

                          if t.lock==0:

                              dw_relay.write(1)

                              t.state = 1

           

                  dr_touch.isr(mraa.EDGE_RISING, pressed, pressed)

                  dr_presence.isr(mraa.EDGE_RISING, presence_detected, presence_detected)

                  while True:

                      time.sleep(15)

           

           

          if __name__ == "__main__":

              daemon = MyDaemon('/tmp/lightSwitchDaemon.pid')

              if len(sys.argv) == 2:

                  if 'start' == sys.argv[1]:

                      daemon.start()

                  elif 'stop' == sys.argv[1]:

                      daemon.stop()

                  elif 'restart' == sys.argv[1]:

                      daemon.restart()

                  else:

                      print "Unknown command"

                      sys.exit(2)

                  sys.exit(0)

              else:

                  print "usage: %s start|stop|restart" % sys.argv[0]

                  sys.exit(2)

          ######################################## END lightSwitchDaemon.py ##########################################################

          • 2. Re: Light Switch replacement project
            LightBulb

            Did the second version of the enclosure. Now it is just one box (so just half the size) and I have decided to drop the switch for the Edison itself. The black tail on the top is the 12v power plug and it can be pulled out to turn the Edison off.

            I guess this is good enough for now and can go to the wall like this.

             

            IMG-20150525-00051.jpg

             

            case: wero-plast Hit-Box 1004 grau bar-code 520896/4016138048025 €7,39

            Holhraumschalterdose 68mm, 35mm tief 612132/4004282452539 €1,89

            Cable Einzelader ölflex heat 180 sid 1x1603148/2050000539039 €0,89

            Sechskant-Mutter verzinkt M2 (100) 886682/4016138502268 €1,99

            Kunststoff-sechkant-mutter m3 (100) 886678/4016138502220 €7,39

            Zylinderkopfschrauben Din84 M2x10 Polyamid 886740/4016138502817 €9,79

            OBI 4008224561815 Kreuzschalter MLT a €9,79

            • 3. Re: Light Switch replacement project
              LightBulb

              Application ideas:

              1 Touch light switch

              2 Automatic "lights on" based on

                   a time pattern

                   b light sensor

                   c pseudo-random pattern as deterrent for the thieves

              3 Presence detector "lights on"

              4 Bluetooth proximity detection sensor (your smartphone is home) and master driver for lights, computer (wake on lan) etc.

              5 Babyphone (add sound sensor)

              6 Infrared remote lights on/off

              7 Speech lights on/off

              8 Speech recognition master for other devices in the room

              9 Bluetooth Music sink and router e.g. from your smatphone or laptop to the speakers in another (all other rooms) also via WiFi

              10 Intel Realsense base station for gesture recognition and a master for for other devices in the room