Having fun with Semantic Model in JRuby

I love working with Semantic Model in JRuby. Just today, we came up with an idea to tell Google / Alexa to “Turn off Other Lights”. This will quickly turn off lights in all the other rooms where no movements have been detected in the past 10 minutes.

Normally some rooms have much longer timeouts, e.g. 60 minutes. This “manual” command lets us turn them off immediately.

So here’s the rule, utilising the Semantic Model to find all Locations with motion sensors (Tagged as Presence) and getting their last_update. Some locations can have multiple motion sensors, so we take the “max” (i.e. the one with the most recent last_update) to represent the last motion in that location.

Other_Lights.on # Turn it on by default / on startup

rule "Turn off lights where there are no recent movements" do
  received_command Other_Lights, command: OFF
  run do
    Other_Lights.on

    locations_with_no_motion = items.locations.select do |location|
      # Select Locations without Presence sensors
      # If it has Presence sensors, select the ones where the latest motion detected before 10 minutes ago
      latest_motion = persistence(:influxdb) do
        location.equipments.members.points(Semantics::Presence).map(&:last_update).compact.max
      end
      next true unless latest_motion

      latest_motion < 10.minutes.ago
    end

    power = locations_with_no_motion.members
                                    .equipments(Semantics::Lightbulb)
                                    .members
                                    .points(Semantics::Power)
                                    .select(&:on?)

    next if power.empty?

    locations = power.map(&:location).uniq

    logger.info "Turn off lights in #{locations.map(&:label).to_sentence}"
    power.off
  end
end
1 Like