/** * * Copyright (c) 2009-2016 Freedomotic team http://freedomotic.com * * This file is part of Freedomotic * * This Program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2, or (at your option) any later version. * * This Program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * Freedomotic; see the file COPYING. If not, see * <http://www.gnu.org/licenses/>. */ package com.freedomotic.things.impl; import com.freedomotic.events.ObjectReceiveClick; import com.freedomotic.model.ds.Config; import com.freedomotic.model.object.BooleanBehavior; import com.freedomotic.model.object.RangedIntBehavior; import com.freedomotic.behaviors.BooleanBehaviorLogic; import com.freedomotic.things.EnvObjectLogic; import com.freedomotic.behaviors.RangedIntBehaviorLogic; import com.freedomotic.reactions.Command; import com.freedomotic.reactions.Trigger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Enrico Nicoletti */ public class ElectricDevice extends EnvObjectLogic { private static final Logger LOG = LoggerFactory.getLogger(ElectricDevice.class.getName()); protected BooleanBehaviorLogic powered; protected RangedIntBehaviorLogic consumption; protected final static String BEHAVIOR_POWERED = "powered"; protected final static String BEHAVIOR_POWER_CONSUMPTION = "power_consumption"; protected final static String ACTION_TURN_ON = "turn on"; protected final static String ACTION_TURN_OFF = "turn off"; @Override public void init() { powered = new BooleanBehaviorLogic((BooleanBehavior) getPojo().getBehavior(BEHAVIOR_POWERED)); //add a listener to values changes powered.addListener(new BooleanBehaviorLogic.Listener() { @Override public void onTrue(Config params, boolean fireCommand) { if (fireCommand) { executePowerOn(params); //executes a turn on command and then sets the object behavior to on } else { setOn(); //sets the object behavior to on as a result from a notified value } } @Override public void onFalse(Config params, boolean fireCommand) { if (fireCommand) { executePowerOff(params); //executes a turn off command and then sets the object behavior to off } else { setOff(); //sets the object behavior to off as a result from a notified value } } }); //register this behavior to the superclass to make it visible to it registerBehavior(powered); //ADD CONSUMPTION BEHAVIOR final RangedIntBehavior consumptionPojo = (RangedIntBehavior) getPojo().getBehavior(BEHAVIOR_POWER_CONSUMPTION); if (consumptionPojo != null) { consumption = new RangedIntBehaviorLogic(consumptionPojo); consumption.addListener(new RangedIntBehaviorLogic.Listener() { @Override public void onLowerBoundValue(Config params, boolean fireCommand) { setConsumptionValue(consumptionPojo.getMin(), params, fireCommand); } @Override public void onUpperBoundValue(Config params, boolean fireCommand) { setConsumptionValue(consumptionPojo.getMax(), params, fireCommand); } @Override public void onRangeValue(int rangeValue, Config params, boolean fireCommand) { setConsumptionValue(rangeValue, params, fireCommand); } }); //register this behavior to the superclass to make it visible to it registerBehavior(consumption); } //caches hardware level commands and builds user command for the Electric Devices super.init(); } /** * Update the power consumption value. This behavior is supposed to be read * only by design, so no commands are executed even if the fireCommand * property is set to true. * * @param value the new consumption value * @param params general request parameters * @param fireCommand true if a command should executed by the related * plugin, false if this is just a thing status update */ public void setConsumptionValue(int value, Config params, boolean fireCommand) { if (fireCommand) { // Action on the hardware is required LOG.warn("Power consumption behavior of thing \"{}\"" + " is supposed to be a read only value. " + "No command is executed!", this.getPojo().getName()); } // Just a change in the virtual thing status consumption.setValue(value); setChanged(true); } /** * Causes the execution of the related hardware command to turn on this * electric device, updates the object representation and notifies the * changes with an event. * * @param params */ public void executePowerOn(Config params) { boolean executed = executeCommand(ACTION_TURN_ON, params); if (executed) { setOn(); } } /** * Causes the execution of the related hardware command to turn off this * electric device, updates the object representation and notifies the * changes with an event. * * @param params */ public void executePowerOff(Config params) { boolean executed = executeCommand(ACTION_TURN_OFF, params); if (executed) { setOff(); } } private void setOn() { LOG.info("Setting behavior \"powered\" of thing \"{}\" to \"true\"", getPojo().getName()); //if not already on if (powered.getValue() != true) { //setting the object as powered powered.setValue(true); //setting the second view from the XML list (the one with the on light bulb image) getPojo().setCurrentRepresentation(1); setChanged(true); } } private void setOff() { LOG.info("Setting behavior \"powered\" of thing \"{}\" to \"false\"", getPojo().getName()); //if not already off if (powered.getValue() != false) { powered.setValue(false); getPojo().setCurrentRepresentation(0); setChanged(true); } } /** * Creates user level commands for this class of freedomotic objects */ @Override protected void createCommands() { Command setOn = new Command(); setOn.setName("Turn on " + getPojo().getName()); setOn.setDescription(getPojo().getName() + " turns on"); setOn.setReceiver("app.events.sensors.behavior.request.objects"); setOn.setProperty("object", getPojo().getName()); setOn.setProperty("behavior", BEHAVIOR_POWERED); setOn.setProperty("value", BooleanBehavior.VALUE_TRUE); commandRepository.create(setOn); Command setOff = new Command(); setOff.setName("Turn off " + getPojo().getName()); setOff.setDescription(getPojo().getName() + " turns off"); setOff.setReceiver("app.events.sensors.behavior.request.objects"); setOff.setProperty("object", getPojo().getName()); setOff.setProperty("behavior", BEHAVIOR_POWERED); setOff.setProperty("value", BooleanBehavior.VALUE_FALSE); commandRepository.create(setOff); Command switchPower = new Command(); switchPower.setName("Switch " + getPojo().getName() + " power"); switchPower.setDescription("switches the power of " + getPojo().getName()); switchPower.setReceiver("app.events.sensors.behavior.request.objects"); switchPower.setProperty("object", getPojo().getName()); switchPower.setProperty("behavior", BEHAVIOR_POWERED); switchPower.setProperty("value", BooleanBehavior.VALUE_OPPOSITE); commandRepository.create(switchPower); Command setItOn = new Command(); setItOn.setName("Turn it on"); setItOn.setDescription("Object turns on"); setItOn.setReceiver("app.events.sensors.behavior.request.objects"); setItOn.setProperty("object", "@event.object.name"); setItOn.setProperty("behavior", BEHAVIOR_POWERED); setItOn.setProperty("value", "true"); commandRepository.create(setItOn); Command setItOff = new Command(); setItOff.setName("Turn it off"); setItOff.setDescription("Object turns off"); setItOff.setReceiver("app.events.sensors.behavior.request.objects"); setItOff.setProperty("object", "@event.object.name"); setItOff.setProperty("behavior", BEHAVIOR_POWERED); setItOff.setProperty("value", BooleanBehavior.VALUE_FALSE); commandRepository.create(setItOff); Command switchItsPower = new Command(); switchItsPower.setName("Switch its power"); switchItsPower.setDescription("Object switches its power"); switchItsPower.setReceiver("app.events.sensors.behavior.request.objects"); switchItsPower.setProperty("object", "@event.object.name"); switchItsPower.setProperty("behavior", BEHAVIOR_POWERED); switchItsPower.setProperty("value", BooleanBehavior.VALUE_OPPOSITE); commandRepository.create(switchItsPower); } /** * */ @Override protected void createTriggers() { Trigger clicked = new Trigger(); clicked.setName("When " + this.getPojo().getName() + " is clicked"); clicked.setChannel("app.event.sensor.object.behavior.clicked"); clicked.getPayload().addStatement("object.name", this.getPojo().getName()); clicked.getPayload().addStatement("click", ObjectReceiveClick.SINGLE_CLICK); clicked.setPersistence(false); Trigger turnsOn = new Trigger(); turnsOn.setName(this.getPojo().getName() + " turns on"); turnsOn.setChannel("app.event.sensor.object.behavior.change"); turnsOn.getPayload().addStatement("object.name", this.getPojo().getName()); turnsOn.getPayload().addStatement("object.behavior." + BEHAVIOR_POWERED, BooleanBehavior.VALUE_TRUE); Trigger turnsOff = new Trigger(); turnsOff.setName(this.getPojo().getName() + " turns off"); turnsOff.setChannel("app.event.sensor.object.behavior.change"); turnsOff.getPayload().addStatement("object.name", this.getPojo().getName()); turnsOff.getPayload().addStatement("object.behavior." + BEHAVIOR_POWERED, BooleanBehavior.VALUE_FALSE); triggerRepository.create(clicked); triggerRepository.create(turnsOn); triggerRepository.create(turnsOff); } }