0

i'm pretty new to python, so my knowledge is quiet basic. (i'm a system engineer) i have a raspberry pi, an led strip and a python script to simulate a fire on the led strip :D

now i want to start the script by pressing my flic button. i found the fliclib sdk on github and installed it. my problem is now, how to handle the event correctly. i successfully can start the script, but i'd like to stop it by doublepress the flic button. but it seems like i'm stuck in the fire.py script as soon as i press the button once. can anybody help me how to set this up correctly please? :-)

Edit after suggestion: i just edited my scripts as the following. i can see when the button is pressed once or twice with this output:

Starting Fire
Stopping Fire

but the led wont turn on, seems like, fire.py isn't opened or something like that.. when i set button=1 in fire.py itself, the fire turns on.

main.py

#!/usr/bin/env /usr/bin/python3
# -*- coding: utf-8 -*-

import flicbutton
import fire

button = 0

flicbutton.py

#!/usr/bin/env /usr/bin/python3
# -*- coding: utf-8 -*-

import fliclib
client = fliclib.FlicClient("localhost")
MyButton1 = '80:e4:da:71:83:42' #turquoise flic button

def got_button(bd_addr):
    cc = fliclib.ButtonConnectionChannel(bd_addr)
    cc.on_button_single_or_double_click_or_hold = some_handler
    cc.on_connection_status_changed = \
        lambda channel, connection_status, disconnect_reason: \
                        print(channel.bd_addr + " " + str(connection_status) + (" " + str(disconnect_reason) if connection_status == fliclib.ConnectionStatus.Disconnected else ""))
    client.add_connection_channel(cc)

def got_info(items):
    print(items)
    for bd_addr in items["bd_addr_of_verified_buttons"]:
        got_button(bd_addr)

def some_handler(channel, click_type, was_queued, time_diff):
    if channel.bd_addr == MyButton1:
            try:
                    if click_type == fliclib.ClickType.ButtonSingleClick:
                        print("Starting Fire")
                        button=1

                    if click_type == fliclib.ClickType.ButtonDoubleClick:
                        print("Stopping Fire")
                        button=2
                            

                    if click_type == fliclib.ClickType.ButtonHold:
                        print("ButtonHold has not been assigned an action")

            except Exception:
                    import datetime
                    print('An error occured: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()))


client.get_info(got_info)

client.on_new_verified_button = got_button

client.handle_events()

fire.py

import RPi.GPIO as GPIO
import threading
import time
import random
import math

R = 17
G = 22

pwms = []
intensity = 1.0

def initialize_gpio():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup([17,22], GPIO.OUT)


def red_light():
    p = GPIO.PWM(R, 300)
    p.start(100)
    pwms.append(p)
    while True:
        p.ChangeDutyCycle(min(random.randint(50, 100) * math.pow(intensity + 0.1, 0.75), 100) if intensity > 0 else 0)
        rand_flicker_sleep()


def green_light():
    global green_dc
    p = GPIO.PWM(G, 300)
    p.start(0)
    pwms.append(p)
    while True:
        p.ChangeDutyCycle(random.randint(5, 10) * math.pow(intensity, 2) if intensity > 0 else 0)
        rand_flicker_sleep()


def rand_flicker_sleep():
    time.sleep(random.randint(3,10) / 100.0)



def fan_the_flame(_):
    global intensity
    intensity = min(intensity + 0.25, 1.0)


def light_candle():
    threads = [
        threading.Thread(target=red_light),
        threading.Thread(target=green_light),
##        threading.Thread(target=burning_down)
    ]
    for t in threads:
        t.daemon = True
        t.start()
    for t in threads:
        t.join()


def startfire():
    try:
        initialize_gpio()
        print("\nPress ^C (control-C) to exit the program.\n")
        light_candle()
    except KeyboardInterrupt:
        pass
    finally:
        for p in pwms:
            p.stop()

def stopfire():
    GPIO.cleanup()


#if __name__ == '__main__':
 #   main()



if button == 1:
    startfire()
if button == 2:
    stopfire()
  • One way this can be done is instead of calling a script that automatically does (task1), have a variable that the script can read, and it does (task1) or (task2) depending on that variable. The main script can then change this global variable, changing the task being performed without recalling the function – Adi Dec 08 '20 at 18:27
  • thank you for your answer! i'm not sure if i understand this correctly. so i would have for example `runscript = fire.main() stopscript = fire.stopfire()` but what would i do if the button is pressed single/ double? – Vanessa Rüegg Dec 10 '20 at 13:27

1 Answers1

0

Have a common (global variable) that both codes can read, you can put this in a standalone file that both codes can access. So script 1 updates this variable like

 if(single press): variable=1 
 elif(double press): variable=2

then in fire.py you can poll the variable.

if(varaible==1): start/stop fire
elif(variable==2): stop/start fire
else: #throw error

I'm sure there are more efficient ways to do this, but this method should be the easiest to understand.

Adi
  • 84
  • 5
  • thanks for the clarification, i added an answer, because i had a character limit to comment your answer. i'm really confused with stackoverflow and this whole coding... :D – Vanessa Rüegg Dec 13 '20 at 10:49
  • Instead of having the global in main.py and calling both files in main.py, you can have the global in main.py and call main.py in both files, that should work. Check: https://stackoverflow.com/questions/13034496/using-global-variables-between-files – Adi Dec 13 '20 at 20:32
  • thanks i'm feeling really stupid, but if i import main.py in both other files, which file do i start? main.py only has `button = 0`so nothing happens. and if i should start flicbutton.py, why would i need main.py, if i could set variable button in this file? – Vanessa Rüegg Dec 14 '20 at 10:33
  • Okay lets call main.py 'variable.py' to avoid this confusion, you start flicbutton.py, and you still need the variable.py called on both files because it contains the global variable you need shared between the 2 files, when you update the global variable in flicbutton.py, it updates in fire.py, through variable.py/main.py – Adi Dec 14 '20 at 14:38