;P75/P175/P275 FM email alert script 1.0.1 :: (C) Pira.cz 2025 ;FM Scope version required: 1.7.2 or later ;Characteristics ; * Watching for no signal, silence, pilot level, audio channel balance ; * Supports several devices and several stations each, in sequence ; * Most of the time, the devices are free and accessible for manual check ; * Sends email alerts, sends daily email report ;************************************************************* ;*** Instructions for use: *** ;************************************************************* ; 1) Check the User configurable parameters below ; 2) Fill/edit the Task List (connections and stations) ; 3) Check the email configuration in Options - SMTP Settings ; 4) Add this script file to Options - Task Scheduler ; 5) Keep the FM Scope running on the PC ;************************************************************* ;*** User configurable parameters: *** ;************************************************************* set (DataPath,c:\alerts) ;existing folder on your harddisk to store the text logs set (DelayMeasuring,60) ;how long to watch each station [sec], min. 20 set (DelayBetweenEmails,28800) ;minimum delay between two emails with same content [sec] set (EmailRecipients,admin@radio.com) ;where to send the emails set (LimitBalance,10) ;max. balance error in dB set (LimitSilence,20) ;min. average deviation in kHz set (LimitPilotMax,8.0) ;max. pilot level in kHz set (LimitPilotMin,5.0) ;min. pilot level in kHz call (Initialize) ;************************************************************* ;*** Task List (connections and stations): *** ;************************************************************* ;device 1 set (ConnectionParameters,192.168.0.101:10001) call (CreateConnection) tune (88.5) ;edit the frequencies as required call (CheckStation) tune (101.9) call (CheckStation) ;... further frequencies here ... disconnect ;device 2 set (ConnectionParameters,4,115200) ;COM4 call (CreateConnection) tune (89.3) call (CheckStation) tune (93.5) call (CheckStation) ;... further frequencies here ... disconnect ;... further devices here ... ; - user editable section ends here - call (SaveLog) ;************************************************************* ;*** Daily email report: *** ;************************************************************* set (CurrentDate,%date) if (%CurrentDate$=%LastReportDate) goto (SkipDailyReport) endif call (SendRegularReport) set (LastReportDate,%CurrentDate) SkipDailyReport: ;************************************************************* ;*** End: *** ;************************************************************* stop ;************************************************************* ;*** Functions: *** ;************************************************************* CreateConnection: set (ConnectionAttempts,0) CreateConnectionLoop: if (%ConnectionAttempts>=5) call (SendNoConnection) disconnect return endif inc (ConnectionAttempts) set (NewText,%crConnecting to %ConnectionParameters) call (AddToLog) disconnect connect (%ConnectionParameters) if (%connected=0) sleep (10) goto (CreateConnectionLoop) endif ;simple communication test tune (87.5) send (?F) set (w1,%freq) tune (108.0) send (?F) if (%w1$=%freq) goto (CreateConnectionLoop) endif return ;************************************************************* CheckStation: if (%connected=0) set (NewText,Frequency skipped - no connection) call (AddToLog) return endif ;initialization of the cycle: set (EndTime,%timestamp) inc (EndTime,%DelayMeasuring) set (EndTimeMeas,%EndTime) inc (EndTimeMeas,-5) set (SignalQualityMax,0) set (DeviationAve,0) set (PltMin,999) set (PltMax,0.0) set (LMax,-60) set (RMax,-60) send (?F) set (NewText,[Checking %frequency]) call (AddToLog) setmode (0) sleep (5) mpx.run textwindow.addtext ( ) CheckStationLoop: getquality getpilot send (?A) send (?C) if (%quality>%SignalQualityMax) set (SignalQualityMax,%quality) endif if (%pilot_>%PltMax) set (PltMax,%pilot_) endif if (%pilot_<%PltMin) set (PltMin,%pilot_) endif if (%devave_>%DeviationAve) set (DeviationAve,%devave_) endif if (%lmaxdb>%LMax) set (LMax,%lmaxdb) endif if (%rmaxdb>%RMax) set (RMax,%rmaxdb) endif if (%timestamp>=%EndTimeMeas) setmode(1) ;for compatibility with P75/P175 endif if (%timestamp>=%EndTime) mpx.stop rds.getdata goto (Evaluation) endif sleep (1) textwindow.addtext (.) ;this is a dot, not an ass goto (CheckStationLoop) ;************************************************************* Evaluation: set (AlertText,) set (w1,%PltMin to %PltMax) if (%PltMin$=%PltMax) set (w1,%PltMin) endif set (Summary,%rdspi %rdsps; Signal %SignalQualityMax; Pilot %w1 kHz; Dev. Ave %DeviationAve kHz; R/L balance %RMax/%LMax dB) set (NewText,%Summary) call (AddToLog) if (%SignalQualityMax<3) set (AlertText,%AlertTextNo signal! ) goto (EvalutionSkipValues) endif if (%rdspi$=0000) if (%rdsps$=" ") set (NewText,Warning: No RDS) call (AddTolog) endif endif if (%PltMax=0) set (NewText,Warning: No pilot) call (AddTolog) goto (EvalutionSkipStereo) endif if (%PltMin>%LimitPilotMax) set (AlertText,%AlertTextPilot level failed! ) endif if (%PltMax<%LimitPilotMin) set (AlertText,%AlertTextPilot level failed! ) endif set (w1,%RMax) inc (w1,%LimitBalance) if (%LMax>%w1) set (AlertText,%AlertTextChannel balance failed! ) endif set (w1,%LMax) inc (w1,%LimitBalance) if (%RMax>%w1) set (AlertText,%AlertTextChannel balance failed! ) endif EvalutionSkipStereo: if (%DeviationAve<%LimitSilence) set (AlertText,%AlertTextAudio level failed! ) endif EvalutionSkipValues: if (%AlertText$=) set (NewText,No problem found) call (AddToLog) return endif set (NewText,%AlertText) call (AddToLog) call (SendAlert) return ;************************************************************* SendRegularReport: set (NewText,Sending regular report to %EmailRecipients%cr) call (AddToLog) email.to (%EmailRecipients) email.subject (FM Scope Daily Report) if (%ProblemCounter=0) email.body (No problem found.) endif if (%ProblemCounter>0) email.body (%ProblemCounter problem(s) found. See the files attached.) endif email.attachfile (%DataPath\recent.txt) email.attachfile (%DataPath\daily.txt) email.send set (ProblemCounter,0) save (ProblemCounter) savetext (%DataPath\daily.txt,) return ;************************************************************* SendAlert: inc (ProblemCounter) if (%LastAlertText%freq$=%AlertText) set (w1,%LastAlertAt%freq) inc (w1,%DelayBetweenEmails) if (%w1>%timestamp) return endif endif set (NewText,Sending alert message to %EmailRecipients) call (AddToLog) email.to (%EmailRecipients) email.subject (Alert for %ConnectionParameters - %frequency) email.body (%date %time:%cr%cr%AlertText%cr%Summary%cr%crSent from FM Scope) email.send set (LastAlertAt%freq,%timestamp) set (LastAlertText%freq,%AlertText) return ;************************************************************* SendNoConnection: set (NewText,Unable to connect!) call (AddToLog) inc (ProblemCounter) set (w1,%LastNoConnectAlert) inc (w1,%DelayBetweenEmails) if (%w1>%timestamp) return endif email.to (%EmailRecipients) email.subject (Alert for %ConnectionParameters) email.body (Unable to connect to the device%cr%crSent from FM Scope) email.send set (LastNoConnectAlert,%timestamp) return ;************************************************************* SaveLog: set (NewText,%crEnd of task list%cr) call (AddToLog) savetext (%DataPath\recent.txt,%RecentLog) appendtext (%DataPath\daily.txt,%RecentLog) set (RecentLog,) save (ProblemCounter) return ;************************************************************* AddToLog: textwindow.addline (%NewText) set (RecentLog,%RecentLog%cr%NewText) return ;************************************************************* Initialize: setproperty (ExecutionSpeed,4) page.show (6) setproperty (OnlineUpdate,1) set (RecentLog,) textwindow.clear set (NewText,Starting at %date %time) call (AddToLog) load (ProblemCounter,0) mpx.stop return