Open rankinstudio opened 2 years 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.
The things that would have to change are
"duration"
setting to the alert
dictionary in the .json
file. (should be a float with a default of 0.0 so classrooms don't have to reconfigure)"duration"
to client.py
intake section"duration"
to client.py
thread initialization sectionduration
as a parameter to rsudp.c_alert.Alert.init()duration
as a definition to rsudp.c_alert.Alert.init()n
samples within duration
range (n = rsudp.raspberryshake.getSR() * duration
) and ALL would have to exceed threshold
c_alert.Alert
settings.rst
I may be forgetting a step but this should cover the important changes at least.
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
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.
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