A task that speaks a source's value when it drops below a threshold. It repeats at a set interval while the value stays low, and re-arms only once the value has clearly recovered.
-- Low value alert: a background task that calls out a source when it drops-- below a threshold, with repeat interval and hysteresis.-- https://frskyrc.github.io/ethos-lua-doc/cookbook/alert-task/-- task state is file-level: a task has one instance per modellocalcfg={source=nil,threshold=105,interval=15}-- threshold in tenths (10.5)localHYSTERESIS=2-- tenths above the threshold before re-arminglocalCHECK_EVERY=0.25-- seconds; 4 Hz is plenty for an alertlocalnextCheck,nextCall,armed=0,0,truelocalfunctionwakeup()localnow=os.clock()ifnow<nextCheckthenreturnend-- cheap early exit on most ticksnextCheck=now+CHECK_EVERYlocalsrc=cfg.sourcelocalv=srcandsrc:value()ifnotvthenreturnendlocaltenths=v*10iftenths<cfg.thresholdthenifarmedornow>=nextCallthensystem.playNumber(v,src:unit(),src:decimals())system.playHaptic(300)armed=falsenextCall=now+cfg.intervalendelseiftenths>cfg.threshold+HYSTERESISthenarmed=true-- clearly recovered: next drop alerts immediatelyendendlocalfunctionconfigure()localline=form.addLine("Source")form.addSourceField(line,nil,function()returncfg.sourceend,function(v)cfg.source=vend)line=form.addLine("Alert below")localf=form.addNumberField(line,nil,0,10000,function()returncfg.thresholdend,function(v)cfg.threshold=vend)f:decimals(1)line=form.addLine("Repeat every")f=form.addNumberField(line,nil,5,120,function()returncfg.intervalend,function(v)cfg.interval=vend)f:suffix("s")endlocalfunctionread()cfg.source=storage.read("source")cfg.threshold=storage.read("threshold")orcfg.thresholdcfg.interval=storage.read("interval")orcfg.intervalendlocalfunctionwrite()storage.write("source",cfg.source)storage.write("threshold",cfg.threshold)storage.write("interval",cfg.interval)endlocalfunctioninit()system.registerTask({key="lowalrt",name="Low value alert",wakeup=wakeup,configure=configure,read=read,write=write})endreturn{init=init}