How to trigger an event when a property value is changed?

I have a simple web thing written in python with an ‘on’ property -

def make_thing():
thing = Thing('My Lamp', ['OnOffSwitch', 'Light'], 'A web connected lamp')

thing.add_property(
    Property(thing,
             'on',
             Value(True),
             metadata={
                 '@type': 'OnOffProperty',
                 'title': 'On/Off',
                 'type': 'boolean',
                 'description': 'Whether the lamp is turned on',
}))

Is it possible to attach an event to this on property so another piece of code can be run when the user changes the sate of My Lamp?

The web thing API packages are designed to be primarily used for writing out, since you should know more about when exactly these state transitions happen. So you’d do it there.

If you’re talking about doing something that involves multiple devices, you should check out rules in the gateway, where you can define a condition and actions.

You can pass a function to the Value() constructor which will be called when the value is set. From there, you could probably trigger an event.

Thanks for replying. I’ve got this so far, all I want is to see the debug output ‘get’ / ‘set’ to be displayed but this isn’t happening. I’m new to this sorry, where am I going wrong?

Many thanks.

class LightThing(Thing):

def __init__(self):
    Thing.__init__(self,
        'Light Thing',
        ['OnOffSwitch', 'Light'],
        'A web connected light thing')

    self.state = False
	
    self.add_property(
        Property(self,
                 'on',
                 Value(self.get_state(), self.set_state()),
                 metadata={
                     '@type': 'OnOffProperty',
                     'title': 'On/Off',
                     'type': 'boolean',
                     'description': 'Whether the lamp is turned on'
                 }))

def get_state(self):
    logging.debug("get")
    return True
	
def set_state(self):
    logging.debug("set")

You probably only want Value(self.get_state(), self.set_state) so you pass the function and not the return value of the function.

Thanks Martin, that did it!
I see how the brackets work now.

Thanks, the code above was really useful. I’m getting the following when running it and changing the state:

TypeError: set_state() takes 1 positional argument but 2 were given

Any thoughts what I might have done wrong?

Do you try to pass some additional values in get_state(**some_value**) ?
Some ware you have a value in bracket’s too much. I think.

I tested that today by chance. Or better I stumbled over it.
You have to add a parameter like this:set_state(self, value)
value will be the state of your property.
An OnOffProperty has 'type':'boolean' so value will be True or False depending on the state of the gateway UI button.

you can add this to the Multiplething Example in line 101:

def geting(self):
        logging.debug('get')

    def seting(self,value):
        logging.debug(f'set {value}')

and change the Line 43 to this:
Value(self.geting(),self.seting),

Then start and click the myLamp thing on gateway. It will print:

2020-05-12 20:28:53,414 multiple-things.py:106 DEBUG set True
2020-05-12 20:28:55,260 multiple-things.py:106 DEBUG set False