Using a class to make many handlers for observing, but the handler gets triggered immediately regardless of onAppear results

Asked by Joshua Noble on 2018-08-08

I'm currently in the middle of a script used to observe many regions at once, all pointed at IP camera feeds. The script is to see if any of the screens shown on the feeds go dark at any given moment.

I've used a class to create all of my onAppear and observeInBackground methods since they all follow the same process, and gave the __init__ arguments of 'self', 'name', and 'region'. I was hoping to make another method that would be used as the handler for these onAppears called 'trigger_handler', that would alert us as to which region has been triggered when it happens (see below).

def trigger_handler(self, event):
        ###
        # This is the method that gets called whenever the onAppear observation is triggered. Health check will send with the
        subject
        line noting which screen is down and send both pictures
        ###
        popup(self.name+" appears to be down, can you confirm?")

My idea was to reference this method as the handler in the onAppear method (see below), but when doing so the handler triggers immediately whether the onAppear is true or not.

def start_observe(self, reference):
        ###
        # This is the method assigned to each region being observed that looks for its own reference image and calls its own event
        handler when triggered
        ###
        reference = str(self.region)+"_out"
        self.region.onAppear(reference, self.trigger_handler())
        self.region.observeInBackground(FOREVER)

I'm also pasting the class itself and the __init__ that directly follows just for reference, and also a couple of the class objects below that.

class event_handler():
    ###
    # This is a class that contains all handlers for observation regions. The __init__ helps us define the name of the screen we are
    currently observing,
    # while the trigger_handler method is assigned to all objects of the class and gets called for that specific object when the
    onAppear gets triggered
    ###
    def __init__(self, name, region):
        self.name = name
        self.region = region

rr02_handler = event_handler("Reader Rail 2", rr02) ###(rr02 and rr08 are regions defined earlier on before the class.
rr08_handler = event_handler("Reader Rail 8", rr08)

def start_all_observe():
    rr02_handler.start_observe(rr02_out)

Thank you so much for any help and advice, I am just totally stumped!

Question information

Language:
English Edit question
Status:
Answered
For:
Sikuli Edit question
Assignee:
No assignee Edit question
Last query:
2018-08-08
Last reply:
2018-08-09
RaiMan (raimund-hocke) said : #1

could you just send me the complete code to my mail sikulix--at--outlook--dot--com.

If possible also a screenshot of the watched area and the used sample image (black?).

The case is interesting and I want to help you.

RaiMan (raimund-hocke) said : #2

I just made a test with the latest 1.1.3 nightly (on Mac ;-)

Settings.UserLogs = True
Settings.UserLogTime = True

def handler(evt):
  Debug.user("in handler: black appeared")

Debug.user("starting")

basePath = "/Users/raimundhocke/IdeaProjects/SikuliX114/API/src/main/resources/ImagesAPI"
setBundlePath(basePath)

App.focus("safari"); wait(2.0); reg = App.focusedWindow();

black = "black_128"
match = reg.exists(black, 10)
if (match): Debug.user("black exists")

match = reg.exists("sikulix2", 10)
if (match): Debug.user("image exists")

reg.onAppear(black, handler)
Debug.user("start observing")
reg.observe(10)

The script shows, that the approach principally works.

My workflow:
- to simulate your video-area-gets-black scenario: the browser window shows an animated gif, that shows an image for 5 secs and then the image area as black for 5 secs
- we first wait for the black image
- then we wait for the image, to assure, that the observe starts with seeing the image
- the we start observe

this is the output:
[user (09/08/2018, 13:50:12)] starting
[log] App.focus: [0:safari]
[user (09/08/2018, 13:50:15)] black exists
[user (09/08/2018, 13:50:15)] image exists
[user (09/08/2018, 13:50:15)] start observing
[user (09/08/2018, 13:50:18)] in handler: black appeared

It does not matter, wether observing in foreground or in background.

Problems you might be facing:
- the video image might be too black" and generates false positives - try with Pattern().exact()
- timing problems: you should separate the definitions of the observation (onAppear) and the start of the observations, to have more control

Be sure to use version 1.1.3 nightly - it has some fixes for observation.

Be sure to have read the docs: there are some interesting features, that might be helpful in your situation
https://sikulix-2014.readthedocs.io/en/latest/region.html#observing-visual-events-in-a-region

Can you help with this problem?

Provide an answer of your own, or ask Joshua Noble for more information if necessary.

To post a message you must log in.