raspishake / rsudp

Continuous visual display, sudden motion monitoring, and historical replay of Raspberry Shake data
https://raspishake.github.io/rsudp/
GNU General Public License v3.0
52 stars 30 forks source link

sta/lta timing alarm #41

Open rankinstudio opened 2 years ago

rankinstudio commented 2 years ago

It seems, after messing with this for a while, that setting an alarm only on the threshold value being hit isn't the best approach. When there is a short lived disturbance the threshold can be very briefly hit and drop back down quickly, still sending an alert out. Earthquakes just distant / weak enough to not set the alarm off will still make the sta/lta ratio climb for a longer period of time. It would be neat to be able to configure a trigger with a lower threshold that times how long the alarm is active. If this time value is met (say 10s active) then it sends an alert out. The reset even would stop and reset the timer. I think this would be more likely to skip short events and catch earthquakes.

Cheers

David

iannesbitt commented 1 year ago

Hi David, great point here. The reason I originally built it this way was because I wanted our classroom demonstrations to be able to trigger the alarm just by stomping, but I totally agree with you. The fix I am envisioning would have some sort of "duration" setting which when turned above zero would require a certain number of seconds to elapse over the threshold to trip the alarm.

iannesbitt commented 1 year ago

The things that would have to change are

I may be forgetting a step but this should cover the important changes at least.

rankinstudio commented 5 months ago

I got this working with these updates.

to rsudp.c_alert.Alert import time

I added this to rsudp.c_alert.Alert.init() self.timerRunning = False self.t_value = 37 #Set timeout value here

Then this to rsudp.c_alert.Alert._is_trigger()

def _is_trigger(self):
    '''
    Figures out it there's a trigger active.
    '''
    #INITIAL TRIGGER TIMER
    if self.stalta.max() > self.thresh:
        if not self.exceed: #Not in triggered state already
            if not self.timerRunning:
                self.timerRunning = True
                self.t_start = time.time() #time the timer thread for printing out
                print("\n Timer started")

            if self.timerRunning:
                self.t_end = time.time()
                if self.t_end - self.t_start > self.t_value: 
                    self.timerRunning = False
                    print("\n Timer threshold reached. Triggering.")
                    print(' Timer ran for: ', round(self.t_end - self.t_start, 2), 's')
    if self.stalta.max() < self.thresh:
        if self.timerRunning:
            self.timerRunning = False
            self.t_end = time.time()
            print("\n Timer canceled")
            print(' Timer ran for: ', round(self.t_end - self.t_start, 2), 's')

    #TRIGGER PAST TIMER
    if self.stalta.max() > self.thresh and not self.timerRunning:
        if not self.exceed:
            print(" Triggering") #etc.

I don't know how to implement this fully the way you wanted to, but I've tested it extensively and it works well. After further testing I've realized that it works best if you set a longer LTA and a shorter STA to have the timer timeout on short signal bursts. Here are my trigger settings:

"alert": {
    "enabled": true,
    "channel": "HZ",
    "sta": 15,
    "lta": 130,
    "threshold": 2.1,
    "reset": 1.6,
    "highpass": 0.01,
    "lowpass": 2,
    "deconvolve": true,
    "units": "VEL"},

The threading timer above (30s) should be about 2x the value of the STA setting.

Cheers David

rankinstudio commented 5 months ago

Just want to say that after running the above code for a while, it has decreased the false alarms to almost non-existent, and is extremely good at capturing quakes, even muted ones.