Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python - execute function on button press

First thing first, this is the first time ever i work and use python, so please be patient :)

I'm trying to hack a dash button from amazon to toggle my philips hue light, and i manage to find all the required elements and code and edit it to suit my needs.

The problem i've got now, is that if i run the script, the function in python that i'd like to run execute instantly and doesn't wait to the button to be pressed...

here's some code:

from pydhcplib.dhcp_network
import *
import requests, json

bridgeIP = "{{mybridgeIP}}"
user = "{{philipsUserID}}"
dashMac = "{{dashMacAddress}}"
lightID = "4"

def do_something():
    print("button has been pressed")

def toggleLight(lightID):
    url = "http://" + bridgeIP + "/api/" + user + "/lights/" + lightID
    r = requests.get(url)
    data = json.loads(r.text)
    if data["state"]["on"] == False:
      r = requests.put(url + "/state", json.dumps({
        'on': True
      }))
    elif data["state"]["on"] == True:
      r = requests.put(url + "/state", json.dumps({
        'on': False
        }))


netopt = {'client_listen_port':"68", 'server_listen_port':"67", 'listen_address':"0.0.0.0"}

class Server(DhcpServer):
    def __init__(self, options, dashbuttons):
        DhcpServer.__init__(self, options["listen_address"],
                                options["client_listen_port"],
                                options["server_listen_port"])
        self.dashbuttons = dashbuttons

    def HandleDhcpRequest(self, packet):
        mac = self.hwaddr_to_str(packet.GetHardwareAddress())
        self.dashbuttons.press(mac)


    def hwaddr_to_str(self, hwaddr):
        result = []
        hexsym = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
        for iterator in range(6) :
            result += [str(hexsym[hwaddr[iterator]/16]+hexsym[hwaddr[iterator]%16])]
        return ':'.join(result)

class DashButtons():
    def __init__(self):
        self.buttons = {}

    def register(self, mac, function):
        self.buttons[mac] = function

    def press(self, mac):
        if mac in self.buttons:
            self.buttons[mac]()
            return True
        return False


dashbuttons = DashButtons()
dashbuttons.register(dashMac, do_something)
dashbuttons.register(dashMac, toggleLight(lightID))
server = Server(netopt, dashbuttons)

while True :
    server.GetNextDhcpPacket()

My problem is that do_something() is called properly (when i press the button) but toggleLight(lightID) is called as soon as i run the script..

i don't understand why, they look identical to me..

can you help me understand? thanks

like image 934
Nick Avatar asked Apr 23 '26 16:04

Nick


1 Answers

With this line

dashbuttons.register(dashMac, toggleLight(lightID))

you execute toggleLight(lightID) and bind the result of that call to the function parameter. Since the function takes a parameter, you can not just pass toggleLight, either. Instead, use a lambda function:

dashbuttons.register(dashMac, lambda: toggleLight(lightID))

This creates a new anonymous function that takes no parameters and that will call toggleLight(lightID) when invoked by the button.

like image 59
tobias_k Avatar answered Apr 25 '26 21:04

tobias_k



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!