kimzer
Posts: 11
Joined: Thu Sep 28, 2017 5:24 pm

Merging two python scripts into one

Wed May 23, 2018 6:28 pm

Would you be able to assist a noobie here with a small python script?

Now what i am trying to achieve is that i also have a second script. (posted below) That controls a PIR Sensor wich ALSO turns the light on. But i would like to try and merge the two scripts into 1 single script.

It should as default use the PIR sensor to turn the light on when movement is detected. But! If the button is pushed it should override the sensor and leave the light on for 15 minutes.

As i have it set up now the pir does its job. But if there is no movement in front of it and i push the button it turns the light on then quickly off again as the pir is detecting no movement..

Both scripts below. All help i can get is very very much appreciated. :)

Code: Select all

import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(4, GPIO.IN)         #Read output from PIR motion sensor
while True:
   i=GPIO.input(4)
   if i==0:                 #When output from motion sensor is LOW
         print "No movement detected - Turning lights off",i
         exec(open("./LightsOff.py").read(), globals())
         time.sleep(0.1)
   elif i==1:               #When output from motion sensor is HIGH
         print "Movement detected - Turning lights on",i
         exec(open("./LightsOn.py").read(), globals())
         time.sleep(60 * 15)

Code: Select all

import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
 
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
 
while True:
input_state = GPIO.input(18)
if input_state == False:
    print('Button Pressed')
    execfile("LightsOn.py")
    time.sleep(0.2)
    

Idahowalker
Posts: 231
Joined: Wed Jan 03, 2018 5:43 pm

Re: Merging two python scripts into one

Thu May 24, 2018 12:48 am

I'd rather see the 3rd 'script', the one where you tried to merge the 2 scripts and its not working. I'd rather take a look at what you've done, instead of doing all the work for you, and give suggestions on a fix.
Being a programmer: She says go to the store get 1 bottle of milk, if they have eggs bring back 6. She gets mad cause I brought back 6 bottles of milk.

kimzer
Posts: 11
Joined: Thu Sep 28, 2017 5:24 pm

Re: Merging two python scripts into one

Thu May 24, 2018 5:34 am

Code: Select all

import RPi.GPIO as GPIO
import time
 
 
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setmode(GPIO.BCM)
 
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(4, GPIO.IN)         #Read output from PIR motion sensor
 
while True:
     
    input_state = GPIO.input(18)
    if input_state == False:
        print('Button Pressed')
        exec(open("LightsOn.py").read())
        time.sleep(60 * 15)
        exec(open("./LightsOff.py").read())
        input_state = True
    else:
         
        i=GPIO.input(4)
        if i==0:                 #When output from motion sensor is LOW
             print("No movement detected - Turning lights off",i)
             exec(open("./LightsOff.py").read(), globals())
             time.sleep(0.1)
        elif i==1:               #When output from motion sensor is HIGH
             print("Movement detected - Turning lights on",i)
             exec(open("./LightsOn.py").read(), globals())
             time.sleep(60 * 15)

pcmanbob
Posts: 3887
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Merging two python scripts into one

Thu May 24, 2018 9:39 am

The reason your light only turns on for a second is because the pir and the switch are both controlling the light all the time, but as the pir can turn it on and off it will override the switch so if there is no movement it will turn the light off.

if you want the switch to force the light on and it to stay on you need to make it so that if the switch turns the light on it prevents the pir form controlling the light until the switch turns the light off again, at which time you allow the pir to control the light again.

Some thing like this for example

Code: Select all

input_state = GPIO.input(18)
if input_state == False:
    print('Button Pressed')
    #turn on light
    pircontrol = 0
    
if input_state == True:
    print('Button Not Pressed')
    #turn off light
    pircontrol = 1
    
if pircontrol = 1
    print ('PIR Has Control')
    i=GPIO.input(4)  
    #rest of pir control conde follows on here
    
the pircontrol variable allows the pir to be active only if the button is not pressed, this of course assumes that the button once pressed stays pressed until it pressed again.
Last edited by pcmanbob on Thu May 24, 2018 9:49 am, edited 1 time in total.
Please only ask questions in the forum I will not answer questions sent to me directly via PM
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

scotty101
Posts: 2856
Joined: Fri Jun 08, 2012 6:03 pm

Re: Merging two python scripts into one

Thu May 24, 2018 9:40 am

Code: Select all

exec(open("./LightsOff.py").read(), globals())
Just no.... Why would you need to do that. You can import functionality from other python programs directly using the "import" or "from <file/module> import <function>".
This is almost as bad as using subprocess to call another python program.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

kimzer
Posts: 11
Joined: Thu Sep 28, 2017 5:24 pm

Re: Merging two python scripts into one

Thu May 24, 2018 5:45 pm

The button doesnt stay "pressed" unfortunately. Its a simple click and then its back to normal state.
Cant the click itself be registered and then sleep 15 minutes before releasing control to the pir?

Please do chime in on calling the LightsOn.py scripts aswell, i know its a shitty way but im still learning.

pcmanbob
Posts: 3887
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Merging two python scripts into one

Thu May 24, 2018 7:09 pm

kimzer wrote:
Thu May 24, 2018 5:45 pm

Cant the click itself be registered and then sleep 15 minutes before releasing control to the pir?
Yes is just a simple delay timer with a hold off function on the pir part of the code as before but this time we just make the pir part of the code the else to the if button_pressed == 1: so that when it =0 the pir is checked.

Some thing like this.

Code: Select all

import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(4, GPIO.IN)         #Read output from PIR motion sensor
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

light_on_delay = 15  # time in min for light to stay on when button pressed
button_pressed = 0

while True:
    # check for button press
    input_state = GPIO.input(18)
    if input_state == False:
        print('Button Pressed')
        end = (light_on_delay * 60) + time.time()
        button_pressed = 1
        execfile("LightsOn.py")   
    
   
    # check if button has been pressed if it has check to see if time is up
    if button_pressed == 1:
        if time.time > end:
            button_pressed = 0
        
        
    else:
    
        i=GPIO.input(4)
        if i==0:                 #When output from motion sensor is LOW
             print "No movement detected - Turning lights off",i
             exec(open("./LightsOff.py").read(), globals())
             time.sleep(0.1)
        else:               #When output from motion sensor is HIGH
             print "Movement detected - Turning lights on",i
             exec(open("./LightsOn.py").read(), globals())
             time.sleep(60 * 15)

    # added delay to prevent program using 100% cpu time.
    time.sleep(0.5)
    
un-tested code so expect errors.

I have set it up so that if you press the button for a second time before the 15 min are up it will start counting the 15 min again.

as for calling your lightsoff or lights on why not add them to this code as functions then you can just call them as you need them.

example...

Code: Select all

def LightsOn:
#put the code here

def LightsOff:
#put the code here

#replace this line
exec(open("./LightsOn.py").read(), globals())

#with this line
LightsOn()
Last edited by pcmanbob on Fri May 25, 2018 9:12 pm, edited 2 times in total.
Please only ask questions in the forum I will not answer questions sent to me directly via PM
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

kimzer
Posts: 11
Joined: Thu Sep 28, 2017 5:24 pm

Re: Merging two python scripts into one

Fri May 25, 2018 5:34 pm

So this is what i have so far. Does it look ok?

Edit; removed some errors. But its stalling on line 50 for some reason. Its saying invalid syntax but im not seeing why.

Code: Select all

import RPi.GPIO as GPIO
import time
import requests

def LightsOn():
	colors = {
	            'dailywhite':'{"on":true,"bri":255,"sat":0,"hue":0}',
	            'latewhite':'{"on":true,"bri":255,"sat":80,"hue":357}',
                'midnight':'{"on":true,"bri":255,"sat":68,"hue":357}',
                'afterparty':'{"on":true,"bri":255,"sat":255,"hue":0,"effect":"colorloop"}'
			}
 
hour = time.localtime().tm_hour

time_colors = {(0,2):'midnight', (2,7):'afterparty', (7, 20):'dailywhite', (20,24):'latewhite'}
color_schema  = {hour:color for hours, color in time_colors.items() for hour in range(hours[0], hours[1])}
color = colors[color_schema[hour]]

headers = {
    'Accept': 'application/json',
}
 
requests.put('http://192.168.1.47/api/xxxxxxxxxxxxxxxxxxxxxx/lights/2/state', headers=headers, data=color)

def LightsOff():
    time.sleep(0.1)

headers = {
    'Accept': 'application/json',
}

data = '{"on":false}'

requests.put('http://192.168.1.47/api/xxxxxxxxxxxxxxxxxxxxxxxxx/lights/2/state', headers=headers, data=data)


GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(4, GPIO.IN)         #Read output from PIR motion sensor
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

light_on_delay = 15  # time in min for light to stay on when button pressed
button_pressed = 0

while True:
    # check for button press
    input_state = GPIO.input(18)
    if input_state == False:
        print('Button Pressed')
        end time = time.time + (light_on_delay * 60)
        button_pressed = 1
        LightsOn()
    
   
    # check if button has been pressed if it has check to see if time is up
    if button_pressed == 1:
        if time.time > end:
            button_pressed = 0
        
    else:
    
        i=GPIO.input(4)
        if i==0:                 #When output from motion sensor is LOW
             print "No movement detected - Turning lights off",i
             LightsOn()
             time.sleep(0.1)
        else:               #When output from motion sensor is HIGH
             print "Movement detected - Turning lights on",i
             LightsOff()
             time.sleep(60 * 15)

    # added delay to prevent program using 100% cpu time.
    time.sleep(0.5)

Idahowalker
Posts: 231
Joined: Wed Jan 03, 2018 5:43 pm

Re: Merging two python scripts into one

Fri May 25, 2018 8:00 pm

kimzer wrote:
Fri May 25, 2018 5:34 pm
So this is what i have so far. Does it look ok?

Edit; removed some errors. But its stalling on line 50 for some reason. Its saying invalid syntax but im not seeing why.
Why not post the error message, that way it might be easier to find line 50.
Being a programmer: She says go to the store get 1 bottle of milk, if they have eggs bring back 6. She gets mad cause I brought back 6 bottles of milk.

kimzer
Posts: 11
Joined: Thu Sep 28, 2017 5:24 pm

Re: Merging two python scripts into one

Fri May 25, 2018 8:26 pm

Sorry abut that, should have obviously posted that.

This is how it looks after ive been tinkering.
The error is here on line 17:

Code: Select all

        end time = time.time + (light_on_delay * 60)
And this is the error message:

Code: Select all

  File "button.py", line 17
    end time = time.time + (light_on_delay * 60)
           ^
SyntaxError: invalid syntax

Code: Select all

import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.IN) #Read output from PIR motion sensor
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)

light_on_delay = 15  # time in min for light to stay on when button pressed
button_pressed = 0

while True:
    # check for button press
    input_state = GPIO.input(18)
    if input_state == False:
        print('Button Pressed')
        end time = time.time + (light_on_delay * 60)
        button_pressed = 1
        #exec(open("./LightsOn.py").read(), globals())
        print('button push')
    
   
    # check if button has been pressed if it has check to see if time is up
    if button_pressed == 1:
        if time.time > end:
            button_pressed = 0
        
    else:
    
        i=GPIO.input(4)
        if i==0:            #When output from motion sensor is LOW
            print ('No movement detected - Turning lights off')
            #exec(open("./LightsOn.py").read(), globals()) 
            print ('off')
            time.sleep(0.1)
        else:               #When output from motion sensor is HIGH
            print ('Movement detected - Turning lights on')
            #exec(open("./LightsOff.py").read(), globals())
            print ('on')
            time.sleep(60 * 15)

    # added delay to prevent program using 100% cpu time.
    time.sleep(0.5)
Last edited by kimzer on Fri May 25, 2018 8:46 pm, edited 1 time in total.

B.Goode
Posts: 5837
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: Merging two python scripts into one

Fri May 25, 2018 8:32 pm

Code: Select all

    if input_state == False:
        print('Button Pressed')
        end time = time.time + (light_on_delay * 60)
        button_pressed = 1
        LightsOn()

end time = time.time + (light_on_delay * 60)

You cannot have a space in a variable name.

pcmanbob
Posts: 3887
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Merging two python scripts into one

Fri May 25, 2018 8:34 pm

The error is because you are using "end time" as your variable name.

time is reserved for use with the time function which you import at the start of your program.

you should just be using end as the variable name as it is in the line

Code: Select all

if time.time > end:

it was a typo in my example which has now been corrected. ( I did say expect errors code untested.)
Please only ask questions in the forum I will not answer questions sent to me directly via PM
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

kimzer
Posts: 11
Joined: Thu Sep 28, 2017 5:24 pm

Re: Merging two python scripts into one

Fri May 25, 2018 8:49 pm

Roger that. Thanks for clearing that up.
Giving me this now tho

Code: Select all

    end = time.time + (light_on_delay * 60)
TypeError: unsupported operand type(s) for +: 'builtin_function_or_method' and 'int'

B.Goode
Posts: 5837
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: Merging two python scripts into one

Fri May 25, 2018 9:01 pm

In English, something like "Sorry, but time.time is my special way of storing the time and it doesn't make sense to try to add another number to it."

User avatar
DougieLawson
Posts: 32715
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Merging two python scripts into one

Fri May 25, 2018 9:10 pm

kimzer wrote:
Fri May 25, 2018 8:49 pm
Roger that. Thanks for clearing that up.
Giving me this now tho

Code: Select all

    end = time.time + (light_on_delay * 60)
TypeError: unsupported operand type(s) for +: 'builtin_function_or_method' and 'int'
The maths you're doing gives you a time object (when you fix your syntax problems).

Code: Select all

#!/usr/bin/python3

import time
print (time.ctime())
end = time.time() + 600
print (time.ctime(end))
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

pcmanbob
Posts: 3887
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Merging two python scripts into one

Fri May 25, 2018 9:11 pm

Part of writing code is to learn how to debug it, if you had looked up the usage of time.time in python you would have seen I had missed the () at the end.

this line produces the correct result

Code: Select all

end = (light_on_delay * 60) + time.time()
Please only ask questions in the forum I will not answer questions sent to me directly via PM
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

kimzer
Posts: 11
Joined: Thu Sep 28, 2017 5:24 pm

Re: Merging two python scripts into one

Fri May 25, 2018 9:49 pm

Sorry guys, i really am trying. Thanks alot for helping me out.
Getting this now.

Code: Select all

    if time.time > end:
TypeError: unorderable types: builtin_function_or_method() > float()

pcmanbob
Posts: 3887
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Merging two python scripts into one

Fri May 25, 2018 9:52 pm

kimzer wrote:
Fri May 25, 2018 9:49 pm
Sorry guys, i really am trying. Thanks alot for helping me out.
Getting this now.

Code: Select all

    if time.time > end:
TypeError: unorderable types: builtin_function_or_method() > float()

You are really not looking are you Image

clue " ( ) "

Code: Select all

if time.time > end:

if time.time() > end:
Please only ask questions in the forum I will not answer questions sent to me directly via PM
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

kimzer
Posts: 11
Joined: Thu Sep 28, 2017 5:24 pm

Re: Merging two python scripts into one

Fri May 25, 2018 10:05 pm

Beautifull. It appears to be working. Now onto trying to get the other two scripts into this one.
Thanks so much for all your help!

Return to “Python”

Who is online

Users browsing this forum: No registered users and 14 guests