No announcement yet.

Using email for several different alerts

  • Filter
  • Time
  • Show
Clear All
new posts

  • Using email for several different alerts

    I have a program written & it requres several different email outputs for different shifts that are based on days & times. I have written the day & time code in a subroutine & i just keep reusing the subroutine to activate the different email alerts. my issue is, I have around 30 different alerts that are triggered by certain events. One set of alerts is that we have 21 different tanks. I have each tank high level setup to send an email alert when each tank is full. Before you say OMG you are killing your people.... these tanks hardley ever reach full. I just want them to know when they do. Is there a way that I can put these email alerts in a program or a task? i have tried to put them in a program but it didn't work. Can someone help me out with an example?

  • #2
    You probably need to utilize FIFOs since I'm guessing these events can occur at any time and you don't want to miss any.

    Have your subroutines do FIFOLOADs. Not sure what data is in your alerts. An Alert# would be best. Are the recipient list identical for all alerts or is this different based on the event also? A User Data Type named AlertStruct containing the Alert# RecipientSet# and DWORD 1970 Epoch value for date/time stamp (see DST22) would be good. So your FIFO would be a block of 10 of these AlertStruct UDTs (this is the MAX POSSIBLE SIMULTANEOUS ALERTs). Make it 20 if 10 is too small. EMails should go out quick, but you never know. Alerts should be rare, but you never know. It doesn't hurt to double the size of whatever you think the worst case scenario is because memory is cheap (or if there's a possibility of an error sending EMails - see code below).

    Have a stage program called MonitorAlerts that RUNs always (never EXITs), that looks to see if the FIFO is empty or not (AlertQueue.Depth > 0). When one shows up, it does a FIFOUNLOAD to get the "newest" AlertStruct event, JMPs to the next stage that does an EMAIL of THAT event. When it's successful, it JMPs back to the first stage, looking to see if the FIFO is empty or not (back to the AlertQueue.Depth > 0 test).

    I added a stage to "crack" the unloaded AlertStruct into 2 text strings, the alert text and the recipient list (SG S1).

    PROGRAM MonitorAlerts

    SG S0
    AlertQueue.Depth > 0 JMP S1 // stays here until you have an alert

    SG S1
    FIFOUNLOAD AlertFIFO CurrentEMailAlert // AlertFIFO is the block of AlertStruct UDTs, CurrentEMailAlert is a heap-item of a single AlertStruct UDT that just got unloaded from the AlertFIFO
    Crack CurrentEMailAlert to generate the text into an SL0 string, and recipients into a different SL1 string using a couple STRPRINT with some Lookup() functions based on the Alert# and RecipientSet#, also need to generate text for the 1970 Epoch value by converting it to a User Date/Time structure, then FmtDate FmtTime with that User Date/Time structure; I can definitely help with all of this
    JMP S2 // unconditionally

    SG S2
    EMAIL SL0 Recipients with SL1 text, OnSuccess JMP S0, OnError JMP S99

    // that's okay, add CurrentEMailAlert BACK TO THE FIFO and try again!
    FIFLOAD AlertFIFO CurrentEMailAlert // go ahead and add it back
    SET Y0 (turn on some audible alarm cuz email ain't working!)
    JMP S0

    What's good about this is that it handles a bunch of alerts at the same time (up to 10 or 20 or whatever), but it also doesn't LOSE any alerts if your email server goes down or your Ethernet connection gets cut. That's why I said make the FIFO pretty big.
    There are 10 kinds of people in this world, those who know binary, and those who do not.


    • #3
      I needed to bang on 2.7.2 coming out soon (to fix a bug in Comment Editor), so I implemented this functionality in the PID1.dmd example project. It already had "alarms", so I just made each alarm an "event" and try to email it. I made a faux email server on or whatever, so it will fail the TCP connection. I email maintenence at, qa at, and/or engineering at with simple alarm text with a date/time stamp in the email.

      The emails ALWAYS fail, so I end up in Stage 99. I changed this code to wait for Y10 (Email failure audible annunciator) to be acknowledge before continuing (since NO emails will probably go out).

      I can't post the code yet until 2.7.2 ships, but here is a screen shot of the MonitorAlerts stage program. Note in the Project Browser I expanded the program to show the 4 Stages. It's currently sitting at S99 EMailFailure, waiting for Y10 to turn OFF (it was SET by this stage). An HMI could Reset it to "acknowledge the email failure (or other logic, whatever).

      The FIFOUNLOAD status in Stage S1 shows the "requeued" failed email alert. Alert# is 3 (LO-LO ALARM), Recipient set is 1 (Maintenance? 0 is RCP_EVERYONE, then Maintenance, QA, and Engineering - I may have the order wrong).

      The FIFOLOADs occur in the existing MonitorAlarms task. I can easily queue up 3 to 5 alerts since emails always fail, but they all will "try" to send every time I acknowledge the Y10 alarm, it tries the next one, fails, re-queues failed alert, acknowledge, try next one, fails that one, re-queues THAT failed alert, acknowledge, and on and on

      Click image for larger version  Name:	PID1_FIFOEMAIL1a.png Views:	0 Size:	141.4 KB ID:	130085
      Last edited by franji1; 04-06-2020, 11:57 AM. Reason: replace faux email addresses so they aren't actual looking email addresses
      There are 10 kinds of people in this world, those who know binary, and those who do not.


      • #4
        Great application of User Data Types, FIFOs, symbolic constants, STRPRINT, EMail, PID, et. al.
        There are 10 kinds of people in this world, those who know binary, and those who do not.