/** * * 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.behaviors.BooleanBehaviorLogic; import com.freedomotic.behaviors.ListBehaviorLogic; import com.freedomotic.model.ds.Config; import com.freedomotic.model.object.Behavior; import com.freedomotic.model.object.RangedIntBehavior; import com.freedomotic.behaviors.RangedIntBehaviorLogic; import com.freedomotic.model.object.BooleanBehavior; import com.freedomotic.model.object.ListBehavior; import com.freedomotic.reactions.Command; /** * A 'Washing Machine' thing abstraction. Type is * EnvObject.ElectricDevice.WashingMachine * <p> * Behavior: * <ul> * <li>Any change to washing machine settings make the machine to power on * first</li> * <li>Powering off makes the washing machine to pause washing first</li> * <li>When selecting custom temperature or spinning rpm the washing program is * considered 'Custom'</li> * <li>All settings became read only after the washing machine startup</li> * </ul> * </p> * <p> * Notes for template configurators: * <ul> * <li>Do not remove or alter the 'Custom' washing program</li> * <li>Do not remove or alter the 'Finished' washing cycle</li> * </ul> * * @author Mauro Cicolella */ public class WashingMachine extends ElectricDevice { private BooleanBehaviorLogic washing; private RangedIntBehaviorLogic washingTemperature; private RangedIntBehaviorLogic spinningRpm; private ListBehaviorLogic washingProgram; private ListBehaviorLogic washingCycle; // The two main parameters of a basic washing machine protected final static String BEHAVIOR_WASHING = "washing"; protected final static String BEHAVIOR_WASHING_TEMPERATURE = "washing-temperature"; protected final static String BEHAVIOR_SPINNING_RPM = "spinning-rpm"; // The current phase which the machine is executing protected final static String BEHAVIOR_WASHING_CYCLE = "washing-cycle"; // Contains presets for temperature and spinning defined in the XML protected final static String BEHAVIOR_WASHING_PROGRAM = "washing-program"; @Override public void init() { washing = new BooleanBehaviorLogic((BooleanBehavior) getPojo().getBehavior(BEHAVIOR_WASHING)); //add a listener to values changes washing.addListener(new BooleanBehaviorLogic.Listener() { @Override public void onTrue(Config params, boolean fireCommand) { startWashing(params, fireCommand); } @Override public void onFalse(Config params, boolean fireCommand) { pauseWashing(params, fireCommand); } }); // Set the temparature at which the washing machine should work washingTemperature = new RangedIntBehaviorLogic((RangedIntBehavior) getPojo().getBehavior(BEHAVIOR_WASHING_TEMPERATURE)); washingTemperature.addListener(new RangedIntBehaviorLogic.Listener() { @Override public void onLowerBoundValue(Config params, boolean fireCommand) { setWashingTemperature(washingTemperature.getMin(), params, fireCommand); } @Override public void onUpperBoundValue(Config params, boolean fireCommand) { setWashingTemperature(washingTemperature.getMax(), params, fireCommand); } @Override public void onRangeValue(int rangeValue, Config params, boolean fireCommand) { setWashingTemperature(rangeValue, params, fireCommand); } }); // Set the RPM at which the washing machine should spinn spinningRpm = new RangedIntBehaviorLogic((RangedIntBehavior) getPojo().getBehavior(BEHAVIOR_SPINNING_RPM)); spinningRpm.addListener(new RangedIntBehaviorLogic.Listener() { @Override public void onLowerBoundValue(Config params, boolean fireCommand) { setSpinningRpm(spinningRpm.getMin(), params, fireCommand); } @Override public void onUpperBoundValue(Config params, boolean fireCommand) { setSpinningRpm(spinningRpm.getMax(), params, fireCommand); } @Override public void onRangeValue(int rangeValue, Config params, boolean fireCommand) { setSpinningRpm(rangeValue, params, fireCommand); } }); // Sets the washing program (whites, wool, ...) // TODO: This behavior should contain temperature, spinning rpm, duration, cycles list data for each program (as washing machine presets) washingProgram = new ListBehaviorLogic((ListBehavior) getPojo().getBehavior(BEHAVIOR_WASHING_PROGRAM)); washingProgram.addListener(new ListBehaviorLogic.Listener() { @Override public void selectedChanged(Config params, boolean fireCommand) { setWashingProgram(params.getProperty("value"), params, fireCommand); } }); // Controls the current cycle whitin a washing program (ready, washing, rinsing, spinning, finished) washingCycle = new ListBehaviorLogic((ListBehavior) getPojo().getBehavior(BEHAVIOR_WASHING_CYCLE)); washingCycle.addListener(new ListBehaviorLogic.Listener() { @Override public void selectedChanged(Config params, boolean fireCommand) { setWashingCycle(params.getProperty("value"), params, fireCommand); } }); //register new behaviors to the superclass to make it visible to it registerBehavior(washing); registerBehavior(washingTemperature); registerBehavior(spinningRpm); registerBehavior(washingProgram); registerBehavior(washingCycle); super.init(); } @Override public void executePowerOff(Config params) { // Pause washing before turning off pauseWashing(params, true); // Resume normal poweroff procedure from superclass super.executePowerOff(params); } public void startWashing(Config params, boolean fireCommand) { // Cannot change settings after startup washingTemperature.setReadOnly(true); washingCycle.setReadOnly(true); washingProgram.setReadOnly(true); spinningRpm.setReadOnly(true); //Turn it on first (executed only if not already powered) executePowerOn(params); if (fireCommand) { // Action on the hardware is required if (executeCommand("start washing", params)) { //Executed succesfully, update the value washing.setValue(true); getPojo().setCurrentRepresentation(2); setChanged(true); } } else { // Just a change in the virtual thing status washing.setValue(true); setChanged(true); } } public void pauseWashing(Config params, boolean fireCommand) { // Allow to change settings again washingTemperature.setReadOnly(false); washingCycle.setReadOnly(false); washingProgram.setReadOnly(false); spinningRpm.setReadOnly(false); if (fireCommand) { // Action on the hardware is required if (executeCommand("pause washing", params)) { //Executed succesfully, update the value washing.setValue(false); getPojo().setCurrentRepresentation(1); setChanged(true); } } else { // Just a change in the virtual thing status washing.setValue(false); setChanged(true); } } /** * Updates the internal state of the washing machine related to the washing * temperature behavior. * * @param value the new washing temperature * @param params set of behavior related additional parameters * @param fireCommand decide if it is just an update or if should also * execute something on the hardware */ public void setWashingTemperature(int value, Config params, boolean fireCommand) { // Makes the program a custom one washingProgram.setSelected("Custom"); //Turn it on first (executed only if not already powered) executePowerOn(params); if (fireCommand) { // Action on the hardware is required if (executeCommand("set washing temperature", params)) { //Executed succesfully, update the value washingTemperature.setValue(value); setChanged(true); } } else { // Just a change in the virtual thing status washingTemperature.setValue(value); setChanged(true); } } /** * Updates the internal state of the washing machine related to the spinning * rotation per minutes of the washing machine. * * @param value the new washing spinning rotation * @param params set of behavior related additional parameters * @param fireCommand decide if it is just an update or if should also * execute something on the hardware */ public void setSpinningRpm(int value, Config params, boolean fireCommand) { // Makes to program a custom one washingProgram.setSelected("Custom"); //Turn it on first (executed only if not already powered) executePowerOn(params); if (fireCommand) { // Action on the hardware is required if (executeCommand("set spinning rpm", params)) { //Executed succesfully, update the value spinningRpm.setValue(value); setChanged(true); } } else { // Just a change in the virtual thing status spinningRpm.setValue(value); setChanged(true); } } /** * Updates the internal state of the washing machine related to the * currently active washing cycle. * * The washing cycle can be also used to notify it has FINISHED (last * cycle). Do not change or remove the 'Finishes' washing cycle from the * template definition * * @param selectedCycle the cycle that the machine is currently doing or the * one to use as washing machine startup * @param params set of behavior related additional parameters * @param fireCommand decide if it is just an update or if should also * execute something on the hardware */ public void setWashingCycle(String selectedCycle, Config params, boolean fireCommand) { //Turn it on first (executed only if not already powered) executePowerOn(params); if (fireCommand) { // Action on the hardware is required if (executeCommand("set washing cycle", params)) { //Executed succesfully, update the value washingCycle.setSelected(selectedCycle); setChanged(true); //Has completely finished its job if (washingCycle.getSelected().equalsIgnoreCase("Finished")) { pauseWashing(params, fireCommand); } } } else { // Just a change in the virtual thing status washingCycle.setSelected(selectedCycle); setChanged(true); //Has completely finished its job if (washingCycle.getSelected().equalsIgnoreCase("Finished")) { pauseWashing(params, fireCommand); } } } /** * Updates the internal state of the washing machine related to the washing * program. A washing program is a preset of washing time, washing * temperature and cycles to execute hardcoded in the washing machine * firmware. * * @param selectedProgram the cycle that the machine is currently doing * @param params set of behavior related additional parameters * @param fireCommand decide if it is just an update or if should also * execute something on the hardware */ public void setWashingProgram(String selectedProgram, Config params, boolean fireCommand) { //Turn it on first (executed only if not already powered) executePowerOn(params); if (fireCommand) { // Action on the hardware is required if (executeCommand("set washing program", params)) { //Executed succesfully, update the value washingProgram.setSelected(selectedProgram); setChanged(true); } } else { // Just a change in the virtual thing status washingProgram.setSelected(selectedProgram); setChanged(true); } } @Override protected void createCommands() { super.createCommands(); Command increareWashTemp = new Command(); increareWashTemp.setName("Increase " + getPojo().getName() + " washing temperature"); increareWashTemp.setDescription("increases " + getPojo().getName() + " washing temperature of one step"); increareWashTemp.setReceiver("app.events.sensors.behavior.request.objects"); increareWashTemp.setProperty("object", getPojo().getName()); increareWashTemp.setProperty("behavior", BEHAVIOR_WASHING_TEMPERATURE); increareWashTemp.setProperty("value", Behavior.VALUE_NEXT); Command decreaseWashTemp = new Command(); decreaseWashTemp.setName("Decrease " + getPojo().getName() + " washing temperature"); decreaseWashTemp.setDescription("decreases " + getPojo().getName() + " washing temperature of one step"); decreaseWashTemp.setReceiver("app.events.sensors.behavior.request.objects"); decreaseWashTemp.setProperty("object", getPojo().getName()); decreaseWashTemp.setProperty("behavior", BEHAVIOR_WASHING_TEMPERATURE); decreaseWashTemp.setProperty("value", Behavior.VALUE_PREVIOUS); Command nextWashCycle = new Command(); nextWashCycle.setName(getPojo().getName() + " next washing cycle"); nextWashCycle.setDescription("select the " + getPojo().getName() + " next washing cycle"); nextWashCycle.setReceiver("app.events.sensors.behavior.request.objects"); nextWashCycle.setProperty("object", getPojo().getName()); nextWashCycle.setProperty("behavior", BEHAVIOR_WASHING_PROGRAM); nextWashCycle.setProperty("value", Behavior.VALUE_NEXT); Command prevWashCycle = new Command(); prevWashCycle.setName(getPojo().getName() + " previous washing cycle"); prevWashCycle.setDescription("select the " + getPojo().getName() + " previous washing cycle"); prevWashCycle.setReceiver("app.events.sensors.behavior.request.objects"); prevWashCycle.setProperty("object", getPojo().getName()); prevWashCycle.setProperty("behavior", BEHAVIOR_WASHING_PROGRAM); prevWashCycle.setProperty("value", Behavior.VALUE_PREVIOUS); //TODO: add missing commands! commandRepository.create(increareWashTemp); commandRepository.create(decreaseWashTemp); commandRepository.create(prevWashCycle); commandRepository.create(nextWashCycle); } @Override protected void createTriggers() { super.createTriggers(); } }