Help with code for newbee

Hallo! Having trouble with motion sensor code.

A motion sensor detects movement and lights a LED, when movement stops the LED goes off.
Thats OK and works.
Problem:
When movement is detected I wan´t to play a wav-file and print a statement.
When movement stops I wan´t to play a another wav-file and print a statement.

I tried to do while True- loops, and tried IF -loops but it does not work.
Any ideas to put me in the right direction?
Code below:

‘’’’’
from gpiozero import MotionSensor, LED
from signal import pause
from playsound import playsound

pir = MotionSensor(17)
led = LED(16)

pir.when_motion = led.on

playsound(’/home/pi/FTP/knoddeftp/Mon.wav’)
print(‘movement’)

pir.when_no_motion = led.off

playsound(’/home/pi/FTP/knoddeftp/Moff.wav’)

print(‘no movement’)

pause()

‘’’’

1 Like

Hey Goesta! My name is Cloovy, and I am gonna try to help you out a bit.

So, could you maybe run the code and reply to this to send the error message? I will respond as soon as I can.

Hi @goesta . In general, in order to make it easier for us to give you accurate help without having to guess, please be specific and detailed when describing “it doesn’t work”—provide the full error message and traceback if you’re getting an error, or describe the actual behavior in detail and how it differs from what you expect. Also, three backticks are used for code formatting, like this (you can copy and paste it):

```python
YOUR CODE HERE
```

With that said, on to your question. The reason the LED works is that you’re passing a callback function (led.on) that gets called by gpiozero whenever your motion sensor object pir detects motion (.when_motion) and another that gets called whenever it stops detection motion. By contrast, you are merely playing the sound and printing movement once, at the time you initially set up your motion sensor object.

To explain a bit more, a callback function is a function that gets called at a later time by another function or object when something specific happens. For example, let’s say you were setting up for a surprise party for Friend A, and you need to make sure that you’re ready when your friend is about to come in the door. Friend B (who’s in on the surprise) is with them, making sure they head over on schedule. You’d tell your other friend to “call you back” when Friend A is coming in the door, in which case you’d be ready to spring the surprise. What you’ve done above is just run those functions while you’re still setting things up, rather than tell the motion sensor (i.e. Friend B) to run them when it detects motion (i.e. call them back).

So, to fix this, you’d want to define a function that turns on the LED, plays the sound and prints the message, and then pass that function object to pir.when_motion(), and the same thing for when_no_motion. For example:

def say_hello():
    print("Hello world!")
    led.on()
    # Play sound, etc.

def say_goodbye():
    print("Goodbye world!")
    led.off()
    # Play sound, etc.

pir.when_motion = say_hello
pir.when_no_motion = say_goodbye

Make sense?