RF 433 MHZ PIR motion sensor Raspberry PI configuration

Hi Claudio,

I modified the python script suggest by Graham, instead send the message to binary sensor using http I used paho-mqtt python library to publish the message.

i.e publish.single(“hass/sensor/motion_sensor_1”,“ON”,hostname=“localhost”, auth=auth)

If you want in details, I can share my configuration to you.

Viet Luu

1 Like

for future reference i can give you a third option.
let the script write the values to a small file and let HA read the value from the file.
it has the same advantage as MQTT (the last sensorvalues are Always known at restart) but there is no need to set up a MQTT server for it.

yes please. I am a newb still trying to understan it all. I do have mqtt (mosquitto) installed in the same pi3 where I ran HASS.
On the same pi3 I have a superetherodyne txrx but which I am not able to make it work though.

My goal is to use cheaper 433RF PIR sensor to give motion detection signal to HASS and use it for automation.

Help appreciated

Hi Claudio,

Look like your goal is same as mine. I installed mqtt (mosquitto) in the same pi and got superetherodyne transmitter and receiver.

Anyway below is my code:

  1. Define binary sensor => binary_sensors.yaml
    ##########################################
    • platform: mqtt
      state_topic: “hass/sensor/motion_sensor_1”
      name: “Backyard_Light_Motion”
      qos: 0
      payload_on: “ON”
      payload_off: “OFF”
      sensor_class: motion

##########################################

2.Create automation =>

###########################################

alias: "Motion backyard light during night time"
trigger:
  platform: state
  entity_id: binary_sensor.backyard_light_motion
  from: "off"
  to: "on"
condition:
  - condition: time
    after: '19:00:00'
    before: '5:00:00'
action:
  service: script.motion_backyard_light

###########################################

3.Script trigger turn on => motion_backyard_light.yaml

###########################################
sequence:
- service: script.turn_off
data:
entity_id: script.motion_backyard_light_timer
- service: switch.turn_on
data:
entity_id: switch.courtyard_light
- service: script.turn_on
data:
entity_id: script.motion_backyard_light_timer

###########################################

4.Script timer to turn off => motion_backyard_light_timer.yaml

###########################################
sequence:
- delay:
minutes: 1
- service: switch.turn_off
data:
entity_id: switch.courtyard_light
- service: mqtt.publish
data:
topic: “hass/sensor/motion_sensor_1”
payload: “OFF”
retain: “true”

###########################################

5.Install paho-mqtt

pip3 install paho-mqtt

6.rf signal detection (this script need to run all the time): #You need find update your pir motion rf code also, your topic name

#!/usr/bin/env python3

import argparse
import signal
import sys
import time
import logging
import paho.mqtt.publish as publish

auth = {
   'username':"admin",
   'password':"m@ytao11223344556677"
}

from rpi_rf import RFDevice

rfdevice = None

# pylint: disable=unused-argument
def exithandler(signal, frame):
    rfdevice.cleanup()
    sys.exit(0)

logging.basicConfig(level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S',
                    format='%(asctime)-15s - [%(levelname)s] %(module)s: %(message)s', )

parser = argparse.ArgumentParser(description='Receives a decimal code via a 433/315MHz GPIO device')
parser.add_argument('-g', dest='gpio', type=int, default=27,
                    help="GPIO pin (Default: 27)")
args = parser.parse_args()

signal.signal(signal.SIGINT, exithandler)
rfdevice = RFDevice(args.gpio)
rfdevice.enable_rx()
timestamp = None
logging.info("Listening for codes on GPIO " + str(args.gpio))
i=0
while True:
    if rfdevice.rx_code_timestamp != timestamp:
        timestamp = rfdevice.rx_code_timestamp
        if str(rfdevice.rx_code) == '4654441':
           i = i+1
           logging.info("Detect code " + str(rfdevice.rx_code) + " i=" + str(i))
        if i == 10:
           publish.single("hass/sensor/motion_sensor_1","ON",hostname="localhost", auth=auth)
           i = 0
           time.sleep(60)
    time.sleep(0.01)
rfdevice.cleanup()
2 Likes

Thanks a lot.

Is it all working fine?
My superetherodyne connected directly to the pi is not working (codes are not registered by two 433RF remotes that I used.
As signal detector code I used 2 different from yours, now I am going to try yours.

On some forum are suggesting to step down Data voltage from 5v (of transceiver) to 3,3v of pi3

QUOTE rf signal detection (this script need to run all the time): #You need find update your pir motion rf code also, your topic name

yes but how to I find/update my pir motion code …

as a side note I also have this error (at the moment the code is a fake one since I did not manage to sniff the codes)

switch 5:
  platform: rpi_rf
  gpio: 17
  switches:
    pir_entrance:
      code_on: 1234567
      code_off: 1234568


17-02-11 11:01:51 ERROR (MainThread) [homeassistant.components.switch] Error while setting up platform rpi_rf
Traceback (most recent call last):
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/homeassistant/helpers/entity_component.py", line 151, in _async_setup_platform
    entity_platform.add_entities, discovery_info
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/hass/hass_venv/lib/python3.4/site-packages/homeassistant/components/switch/rpi_rf.py", line 68, in setup_platform
    rfdevice.enable_tx()
  File "/home/hass/.homeassistant/deps/rpi_rf/rpi_rf.py", line 77, in enable_tx
    GPIO.setup(self.gpio, GPIO.OUT)
RuntimeError: No access to /dev/mem.  Try running as root!

You can run the rf code sniffer python script in the link below:

No code is showing

Hi all,
First i would like to thank you all for the py script.
I’ve done some changes.

#!/usr/bin/env python3

import argparse
import signal
import sys
import time
import logging
import paho.mqtt.client as mqtt
import RPi.GPIO

auth = {
   'username':"mosquittouser",
   'password':"pass"
}

mqtt_server_url = "ip"

from rpi_rf import RFDevice

# declare rf PIR
pir_hol = '13981013'
pir_camera = '7689557'

from datetime import datetime, timedelta

# topic dictionary
dict = {pir_hol: 'pir_hol', pir_camera: 'pir_camera'}

dictTimestamp = {pir_hol: datetime.now(), pir_camera: datetime.now()}
dictFiredEventCount = {pir_hol: 0, pir_camera: 0}
rfdevice = None

# pylint: disable=unused-argument
def exithandler(signal, frame):
    rfdevice.cleanup()
    sys.exit(0)

def on_connect(client, userdata, flags, rc):
    m="Connected flags"+str(flags)+"result code "\
    +str(rc)+"client1_id  "+str(client)
    print(m)

def on_message(client1, userdata, message):
    print("message received  "  ,str(message.payload.decode("utf-8")))


publish = mqtt.Client()
publish.username_pw_set("mosquittouser", "homerulz")
publish.on_connect=on_connect        #attach function to callback
publish.on_message=on_message        #attach function to callback
#publish.loop_forever()
#publish.connect(mqtt_server_url,auth)      #connect to broker
#publish.loop_start() 

logging.basicConfig(level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S',
                    format='%(asctime)-15s - [%(levelname)s] %(module)s: %(message)s', )

parser = argparse.ArgumentParser(description='Receives a decimal code via a 433/315MHz GPIO device')
parser.add_argument('-g', dest='gpio', type=int, default=27,
                    help="GPIO pin (Default: 27)")
args = parser.parse_args()

signal.signal(signal.SIGINT, exithandler)
rfdevice = RFDevice(args.gpio)
rfdevice.enable_rx()
timestamp = None
pirCode = "0"
logging.info("Listening for codes on GPIO " + str(args.gpio))
i=0
while True:
    try:
      if rfdevice.rx_code_timestamp != timestamp:
          timestamp = rfdevice.rx_code_timestamp
          pirCode = str(rfdevice.rx_code)
          if pirCode == pir_hol or pirCode == pir_camera:
             dictFiredEventCount[pirCode] = dictFiredEventCount[pirCode] + 1
             logging.info("Detect code " + str(rfdevice.rx_code) + " i=" + str(dictFiredEventCount[pirCode]))
          if dictFiredEventCount[pirCode] == 3 and dictTimestamp[pirCode] < datetime.now():
             publish.connect(mqtt_server_url,1883)		   
             publish.publish("pir/sensor/" + dict[pirCode],"ON")
             dictFiredEventCount[pirCode] = 0
             dictTimestamp[pirCode]+= timedelta(seconds=60)
             publish.publish("pir/sensor/" + dict[pirCode],"OFF")
             publish.disconnect()
             logging.info("Sleep for code " + str(rfdevice.rx_code) +  str(dictTimestamp[pirCode]))
          elif dictFiredEventCount[pirCode] >= 3 :
             dictFiredEventCount[pirCode] = 0
             logging.info("Count reset to 0")
      time.sleep(0.01)
    except KeyError:
      print("Could not convert data to an integer.")
    except SystemExit:
      print("Stopping py")
      sys.exit()
    except:
      print("Unexpected error:", sys.exc_info()[0])
rfdevice.cleanup()

Hi, I finally received a receiver that works. Evidently my first receiver was defective … damn.

Trying your config now

how to make it run from boot, all time?

I receive this error, shall I do something about it?

pi@raspberrypi:~ $ sudo python3 rf_receive.py
/usr/local/lib/python3.4/dist-packages/rpi_rf/rpi_rf.py:167: RuntimeWarning: Thi                  s channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to                   disable warnings.
  GPIO.setup(self.gpio, GPIO.IN)
2017-04-02 14:07:34 - [INFO] rf_receive: Listening for codes on GPIO 27
2017-04-02 14:09:15 - [INFO] rf_receive: Detect code 971897 i=1
2017-04-02 14:09:15 - [INFO] rf_receive: Detect code 971897 i=2

I want to trigger a light.foyer on when motion sensor is activated. Is working but light does not turn off after one minute??

Other question, what is needed the first script.turn_off for?

# Script motion
  motion_foyer_light:
    sequence:
    - service: script.turn_off
      data:
        entity_id: script.motion_foyer_light_timer
    - service: light.turn_on
      data:
        entity_id: light.foyer
    - service: script.turn_on
      data:
        entity_id: script.motion_foyer_light_timer
  motion_foyer_light_timer:
    sequence:
    - delay:
        minutes: 1
    - service: light.turn_off
      data:
       entity_id: light.foyer
    - service: mqtt.publish
      data:
        topic: "hass/sensor/pir_entrance_one"
        payload: "OFF"
        retain: "true"

I successfully manage to learn codes for a receiver (PIR sensor) and put it in a rf_receive.py file

How to make this file run at boot all time?

You can follow the instructions in this link: http://www.raspberrypi-spy.co.uk/2013/07/running-a-python-script-at-boot-using-cron/

1 Like

Thanks, now I have this, is it ok?

pi@raspberrypi:~ $ ps aux | grep /home/pi/rf_receive.py
root       486 13.5  1.1  24652 11112 ?        Sl   18:53   0:34 python3 /home/p                                                                                                 i/rf_receive.py
pi        2384  0.0  0.2   4280  1912 pts/0    S+   18:57   0:00 grep --color=au                                                                                                 to /home/pi/rf_receive.py
pi@raspberrypi:~ $

Sensor goes from off to on, but not from on to off, can someone explain why?

This is the configuration

binary_sensor pir_entrance1:
  - platform: mqtt
    state_topic: "/home/hass/.homeassistant/sensor/pir_entrance_one"
    name: "Foyer Light Motion"
    qos: 0
    payload_on: "ON"
    payload_off: "OFF"
    sensor_class: motion


# Script motion
  motion_foyer_light:
    sequence:
    #- service: script.turn_off
    #  data:
    #    entity_id: script.motion_foyer_light_timer
    - service: light.turn_on
      data:
        entity_id: light.foyer
    - service: script.turn_on
      data:
        entity_id: script.motion_foyer_light_timer
  motion_foyer_light_timer:
    sequence:
    - delay:
        minutes: 1
    - service: light.turn_off
      data:
        entity_id: light.foyer
    - service: mqtt.publish
      data:
        topic: "/home/hass/.homeassistant/sensor/pir_entrance_one"
        payload: "OFF"
        retain: "true"


# Automation motion sensor entrance
  - alias: "Motion entrance light during night time"
    trigger:
      - platform: state
        entity_id: binary_sensor.foyer_light_motion
        from: 'off'
        to: 'on'
    condition:
      - condition: sun
        after: sunset
    action:
      service: script.motion_foyer_light

this is the rf_receive.py script (last part)

while True:
    if rfdevice.rx_code_timestamp != timestamp:
        timestamp = rfdevice.rx_code_timestamp
        if str(rfdevice.rx_code) == '971897':
           i = i+1
           logging.info("Detect code " + str(rfdevice.rx_code) + " i=" + str(i))
        if i == 10:
           publish.single("/home/hass/.homeassistant/sensor/pir_entrance_one","ON",hostname="localhost", auth=auth)
           i = 0
           time.sleep(60)
    time.sleep(0.01)
rfdevice.cleanup()

Hi you now why the code is correctly going from of to on, but then stays on??

Hi,

I made my RF433 PIR Motion/MQTT automation with appdaemon. A true/smart motion is considered If two (o more) signals arrive to mqtt topic between a X period of time. if a true motion is detected and the alarm state is “armed”, send me a notification (telegram).

The sensor:

- platform: mqtt
  name: "PIR Comedor"
  state_topic: "home/433toMQTT"
  command_topic: "home/commands/MQTTto433/PLSL_307/433_1"
  payload_on: "xxxxxxxx" #put your RF Code here
  payload_off: "OFF_PIR_COMEDOR"
  optimistic: false
  retain: false
  device_class: motion

The config of the script:

pir_motion_1:
  alarm_control_panel: alarm_control_panel.alarma
  class: MotionPir
  command_topic: home/commands/MQTTto433/PLSL_307/433_1
  delay: '8'
  module: motion
  payload_off: OFF_PIR_COMEDOR
  sensor: binary_sensor.pir_comedor

This is the my appdaemon script (the logs are in spanish :wink: ):

import appdaemon.appapi as appapi

class MotionPir(appapi.AppDaemon): 

  def initialize(self):
    self.handle = None
    self.motion_counter = 0
    self.sensor = self.args["sensor"]
    self.command_topic = self.args["command_topic"]
    self.payload_off = self.args["payload_off"]
    self.alarm_control_panel = self.args["alarm_control_panel"]
    self.listen_state(self.motion, self.sensor)
    self.turn_off_motion_sensor()

  def motion(self, entity, attribute, old, new, kwargs):
    if new == "on":
      self.motion_counter = self.motion_counter + 1
      self.log("Movimiento detectado en sensor ({}).".format(self.motion_counter))
      self.turn_off_motion_sensor()

      if self.motion_counter > 1:
        self.send_notification()

      self.cancel_timer(self.handle)
      self.handle = self.run_in(self.reset_motion_counter, self.args["delay"])

  def turn_off_motion_sensor(self):
    self.call_service("mqtt/publish", topic = self.command_topic,
                payload = self.payload_off, qos = "0", retain = "false" )

  def reset_motion_counter(self, kwargs):
    self.log("Reiniciando contador de movimientos para sensor.")
    self.motion_counter = 0

  def send_notification(self):
    if self.get_state(self.alarm_control_panel) == "armed_away":
      self.log("Enviando notificación de movimiento detectado vía Telegram.")
      self.call_service("notify/telegram", title = "Movimiento detectado", message = "[{}]".format(self.get_state(self.sensor, attribute="friendly_name")))
    else:
      self.log("Movimiento detectado, notificaciones desactivadas por alarma no activa.")