Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Example project: PIR sensor and Domoticz API

    Scheduled Pinned Locked Moved Projects
    example
    7 Posts 4 Posters 6.4k Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • R Offline
      Ralph
      last edited by Ralph

      I've done a small project on my WiPy 1.0 with a PIR sensor to turn on a lamp in my home using my existing Domoticz setup. I'm using this sensor. This project can be found on this repo. Below a small report of the project and the code.

      The setup
      For every motion trigger, a message is sent to the domoticz api to update a 'user variable'. The domoticz installation, which is running on a RasPi, has a lua script that triggers when this variable changes and turns one lamp on for 2 minutes. (It uses the rfxcom 433 tranceiver and cheap pieces of hardware in my lamps, but that's not relevant now) My kitchen seemed like a good place to implement this, since the lights there only need to be on when there is motion.

      To make it run from the 3.3v out of the WiPy, I soldered a wire to bypass the 5v to 3.3v stepdown on the back of the PIR board. When the sensor triggers, it pulls the pin up for about 5 or 6 seconds, after which it drops back, ready for more triggers. This means I don't have to build in any mechanism to prevent sending http requests too often, which is nice.

      Main.py
      I kept everything very simple, so it's easy for others to grab and adept for their own purposes. Besides the sensor, I also listen to a button press on the expansion board to break the main loop, which I found useful for testing. To make it work with your domoticz, just replace <ip> and <basic hash> with your values.

      import time
      from network import WLAN
      from machine import Pin
      from domoticz import Domoticz
      
      wl = WLAN(WLAN.STA)
      d = Domoticz("<ip>", 8080 ,"<basic hash>")
      
      #flags
      running = True
      button_pressed = False
      pir_triggered = False
      
      #callbacks
      def pirTriggered(pin):
          global pir_triggered
          pir_triggered = True
      
      def buttonPressed(pin):
          global button_pressed
          button_pressed = True
      
      
      pir = Pin('GP4',mode=Pin.IN,pull=Pin.PULL_UP)
      pir.irq(trigger=Pin.IRQ_RISING, handler=pirTriggered)
          
      pir = Pin('GP17',mode=Pin.IN,pull=Pin.PULL_UP)
      pir.irq(trigger=Pin.IRQ_FALLING, handler=buttonPressed)
      
      # main loop
      print("Starting main loop")
      while running:
          time.sleep_ms(500)
          if pir_triggered:
              pir_triggered = False
              result = d.setVariable('Presence:LivingRoom','1')
              print("HTTP Status: "+str(result))
          elif button_pressed:
              button_pressed = False
              running = False
      
      print("Exited main loop")
      

      Domoticz class
      This implements a simple http get request and 2 domoticz api endpoints. Implementation consists of setting values of devices and user-variables.

      I tried implementing the micropython-http-client class from balloob (I simply copied the class into my project), but I found that after 4 successful http requests it stopped working for some reason. So for now, I'm just using the bare sockets in the simplest way possible.

      import socket
      class Domoticz:
          
          def __init__(self, ip, port,  basic):
              self.basic = basic
              self.ip = ip
              self.port = port
          
          def setDevice(self, idx, command):
              print("Setting device "+idx+" to "+command)
              return self.sendRequest("type=command&param=switchlight&idx="+idx+"&switchcmd="+command)
      
          def setVariable(self, name, value):
              print("Setting variable "+name+" to "+value)
              return self.sendRequest("type=command&param=updateuservariable&vtype=0&vname="+name+"&vvalue="+value)
      
          def sendRequest(self, path):
              
              try:
                  s = socket.socket()
                  s.connect((self.ip,self.port))
                  s.send(b"GET /json.htm?"+path+" HTTP/1.1\r\nHost: pycom.io\r\nAuthorization: Basic "+self.basic+"\r\n\r\n")
                  status = str(s.readline(), 'utf8')
                  code = status.split(" ")[1]
                  s.close()
                  return code
                  
              except Exception:
                  print("HTTP request failed")
                  return 0
      

      Boot.py
      I slightly adapted the wifi code to support fixed IP on different wifi networks

      import os
      import machine
      
      uart = machine.UART(0, 115200)
      os.dupterm(uart)
      
      known_nets = {
          '<net>': {'pwd': '<password>'}, 
          '<net>': {'pwd': '<password>', 'wlan_config':  ('10.0.0.114', '255.255.0.0', '10.0.0.1', '10.0.0.1')}, # (ip, subnet_mask, gateway, DNS_server)
      }
      
      if machine.reset_cause() != machine.SOFT_RESET:
          from network import WLAN
          wl = WLAN()
          wl.mode(WLAN.STA)
          original_ssid = wl.ssid()
          original_auth = wl.auth()
      
          print("Scanning for known wifi nets")
          available_nets = wl.scan()
          nets = frozenset([e.ssid for e in available_nets])
      
          known_nets_names = frozenset([key for key in known_nets])
          net_to_use = list(nets & known_nets_names)
          try:
              net_to_use = net_to_use[0]
              net_properties = known_nets[net_to_use]
              pwd = net_properties['pwd']
              sec = [e.sec for e in available_nets if e.ssid == net_to_use][0]
              if 'wlan_config' in net_properties:
                  wl.ifconfig(config=net_properties['wlan_config']) 
              wl.connect(net_to_use, (sec, pwd), timeout=10000)
              while not wl.isconnected():
                  machine.idle() # save power while waiting
              print("Connected to "+net_to_use+" with IP address:" + wl.ifconfig()[0])
              
          except Exception as e:
              print("Failed to connect to any known network")
              wl.init(mode=WLAN.AP, ssid=original_ssid, auth=original_auth, channel=6, antenna=WLAN.INT_ANT)
      

      Plans:

      • Making the http library from Balloob wor properly, or implementing a new http wrapper class
      • Add more sensors like temperature and lux to this same project and send these values to domoticz
      • Expand domoticz class to support the full api

      EDIT
      The API on the esp32 devices for Pin has changed. The pir.irq method has been replaced by pin.callback. The correct implementation for these devices would be:

      pir = Pin('G4',mode=Pin.IN,pull=Pin.PULL_UP)
      pir.callback(trigger=Pin.IRQ_RISING, handler=pirTriggered)
      
      pir = Pin('G17',mode=Pin.IN,pull=Pin.PULL_UP)
      pir.callback(trigger=Pin.IRQ_FALLING, handler=buttonPressed)
      
      1 Reply Last reply Reply Quote 3
      • X Offline
        Xykon administrators
        last edited by

        Thanks a lot for sharing the project

        I soldered a wire to bypass the 5v to 3.3v stepdown on the back of the PIR board

        I'm curious why you did that instead of powering the PIR sensor from 5V through VIN? The only reason I could think of is that you are using a 3.7V LIPO to power the Wipy2. But if it's installed in an area where you have power anyway I'm wondering why you would rely on a battery powered solution.

        Christian Ehlers

        1 Reply Last reply Reply Quote 0
        • R Offline
          Ralph
          last edited by

          @Xykon You are right, I might as well have left it on the 5V.
          I'm running it without the expansion board and only soldered one connector to the 5v out of an old usb cable that I stripped. I could have added another connector on hindsight, but at that point it seemed easier to use the free 3.3v out pin on the wipy and bypass the stepdown.

          1 Reply Last reply Reply Quote 0
          • R Offline
            robmarkcole
            last edited by

            @Ralph Does this need to be updated since callbacks are not handled with pin.irq (deprecated?) but pin.callback? https://docs.pycom.io/pycom_esp32/library/machine.Pin.html#machine.Pin

            R 1 Reply Last reply Reply Quote 0
            • R Offline
              Ralph @robmarkcole
              last edited by

              @robmarkcole Correct, thanks for pointing this out. I added a note to this post now with the correct code.

              R 1 Reply Last reply Reply Quote 1
              • R Offline
                robmarkcole @Ralph
                last edited by robmarkcole

                @Ralph OK great. Not sure if you took this project any further (?) but I am working on something almost identical. https://forum.pycom.io/topic/1308/wipy-motion-and-ambient-conditions-sensor-node
                Cheers

                1 Reply Last reply Reply Quote 0
                • M Offline
                  Morningstar
                  last edited by

                  Can someone help me out on how to setup a domoticz for this project? And also the changes that are required to be made to the code.

                  1 Reply Last reply Reply Quote 0

                  Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                  Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                  With your input, this post could be even better 💗

                  Register Login
                  • 1 / 1
                  • First post
                    Last post

                  Pycom on Twitter

                  Pycom