Send an email that lists the time an item state has changed every 2 hours

My rulesdsl is rusty, and coding in it is just a pain compared to JRuby which is my preference for rule scripting.

Here’s how I would do it in JRuby:

@state_changes = []

REPORT_PERIOD = "8am".."4pm"

SMTP = "mail:smtp:samplesmtp"
EMAIL = "my_email@gmail.com"

rule "Keep track of door states" do
  changed GF_Entry_Door, from: CLOSED, to: OPEN
  changed GF_Entry_Door, from: OPEN, to: CLOSED
  between REPORT_PERIOD
  run do |event|
    if event.open?
      @state_changes << { opened: ZonedDateTime.now }
      things[SMTP].send_html_mail(EMAIL, "OH Alert - Main door event", "Entry door was opened")
      logger.info "eMail of main door status change was sent"
    else
      @state_changes.last[:closed] = ZonedDateTime.now
    end
  end
end

rule "Report door state changes" do
  every 2.hours
  between REPORT_PERIOD
  run do
    changes = @state_changes.slice!(0..) # move the array into `changes` and empty it

    changes = changes.map do |change|
      opened, closed = change.values_at(:opened, :closed)
      if closed
        duration = closed - opened
        closed = closed.to_time.strftime("%H:%M:%S")
      else
        duration = ZonedDateTime.now - opened
        closed = "still open"
      end
      opened = opened.to_time.strftime("%H:%M:%S")
      "<li>#{opened} - #{closed} (#{duration.to_minutes} minutes)</li>"
    end

    msg = <<~HTML
      <h1>Main door log</h1>

      <ul>
        #{changes.join}
        #{changes.empty? ? "<li>No changes. Current door state: #{GF_Entry_Door.state}</li>" : ""}
      </ul>
    HTML

    things[SMTP].send_html_mail(EMAIL, "OH Alert - Main door log", msg)
  end
end

Untested, so there may be bugs, but I hope you get the general idea of how to implement it.

The variable @state_changes will reset (empty) when you save/reload the script, so once it’s working, don’t touch it :slight_smile:

Another way of doing it is using persistence.

1 Like