/*
Copyright (c) Matteo Mazzoni 2013
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 3 of the License, 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.freedomotic.plugins.devices.roomevents;
import com.freedomotic.api.EventTemplate;
import com.freedomotic.api.Protocol;
import com.freedomotic.environment.EnvironmentLogic;
import com.freedomotic.environment.Room;
import com.freedomotic.events.ProtocolRead;
import com.freedomotic.exceptions.UnableToExecuteException;
import com.freedomotic.model.environment.Zone;
import com.freedomotic.model.object.EnvObject;
import com.freedomotic.things.EnvObjectLogic;
import com.freedomotic.reactions.Command;
import com.freedomotic.reactions.CommandRepository;
import com.freedomotic.reactions.Trigger;
import com.freedomotic.reactions.TriggerRepository;
import com.freedomotic.rules.Payload;
import java.io.IOException;
import java.util.HashSet;
import java.util.logging.Logger;
public class RoomEvents extends Protocol {
final int POLLING_WAIT;
CommandRepository cp;
public RoomEvents() {
//every plugin needs a name and a manifest XML file
super("RoomEvents", "/room-events/room-events-manifest.xml");
POLLING_WAIT = configuration.getIntProperty("time-between-reads", -1);
//default value if the property does not exist in the manifest
setPollingWait(POLLING_WAIT); //millisecs interval between hardware device status reads
this.setName("RoomEvents");
}
@Override
protected void onRun() {
}
@Override
protected void onStart() {
LOG.info("RoomEvents plugin is started");
this.setDescription("Starting...");
this.cp = getApi().commands();
addEventListener("app.event.sensor.object.behavior.change");
addEnvCommands();
addRoomCommands();
this.setDescription("Started");
}
@Override
protected void onStop() {
this.setDescription("Stopped");
LOG.info("RoomEvents plugin is stopped ");
}
@Override
protected void onCommand(Command c) throws IOException, UnableToExecuteException {
}
@Override
protected boolean canExecute(Command c) {
//don't mind this method for now
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
protected void onEvent(EventTemplate event) {
LOG.info("ROOMEVENT: received event " + event.toString());
// just to see what properties you are receiving
// do here what you have now in onCommand and send your room status event
// search related room
EnvObjectLogic object = getApi().things().findOne(event.getProperty("object.uuid"));
boolean found = false;
for (Room z : object.getEnvironment().getRooms()) {
for (EnvObject obj : z.getPojo().getObjects()) {
if (obj.getUUID().equalsIgnoreCase(object.getPojo().getUUID())) {
found = true;
break;
}
}
if (found) {
notifyRoomStatus(z);
break;
}
}
}
private void notifyRoomStatus(Room z) {
ProtocolRead event = new ProtocolRead(this, "roomevent", z.getPojo().getName());
// Freedomotic.logger.info(event.toString());
int numLightsOn = 0;
int totLights = 0;
String roomName = z.getPojo().getName();
for (EnvObject obj : z.getPojo().getObjects()) {
if (obj.getType().equalsIgnoreCase("EnvObject.ElectricDevice.Light")) {
totLights++;
if (obj.getCurrentRepresentationIndex() == 1) {
numLightsOn++;
}
}
}
if (totLights != 0) {
String amount = "";
if (numLightsOn == 0) {
amount = "no";
} else if (numLightsOn == totLights) {
amount = "all";
} else {
amount = "some";
}
event.addProperty("hasLightsOn", amount);
event.addProperty("roomName", roomName);
notifyEvent(event);
// add and register this
String triggerName = "Room " + roomName + " has " + amount + " lights On";
Trigger t;
if (getApi().triggers().findByName(triggerName).isEmpty()) {
t = new Trigger();
t.setName(triggerName);
t.setChannel(event);
Payload p = new Payload();
p.addStatement("hasLightsOn", amount);
p.addStatement("roomName", roomName);
t.setPayload(p);
getApi().triggers().create(t);
}
}
}
private void addRoomCommands() {
String cmdName;
for (EnvironmentLogic env : getApi().environments().findAll()) {
for (Zone z : env.getPojo().getZones()) {
if (z.isRoom()) {
cmdName = "Turn off devices inside room " + z.getName();
for (Command c : cp.findByName(cmdName)) {
cp.delete(c);
}
Command c = new Command();
c.setReceiver("app.events.sensors.behavior.request.objects");
c.setName(cmdName);
c.setDescription(cmdName);
c.setProperty(Command.PROPERTY_OBJECT_ZONE, z.getName());
c.setProperty(Command.PROPERTY_BEHAVIOR, "powered");
c.setProperty("value", "false");
HashSet<String> tags = new HashSet<>();
tags.add("turn");
tags.add("off");
tags.add("room");
tags.add("devices");
tags.add(z.getName());
c.setTags(tags);
cp.create(c);
}
}
}
}
private void addEnvCommands() {
String cmdName;
for (EnvironmentLogic env : getApi().environments().findAll()) {
cmdName = "Turn off devices inside area " + env.getPojo().getName();
for (Command c : cp.findByName(cmdName)) {
if (c != null) {
cp.delete(c);
}
}
Command c = new Command();
c.setReceiver("app.events.sensors.behavior.request.objects");
c.setName(cmdName);
c.setDescription(cmdName);
c.setProperty(Command.PROPERTY_OBJECT_ENVIRONMENT, env.getPojo().getName());
c.setProperty(Command.PROPERTY_BEHAVIOR, "powered");
c.setProperty("value", "false");
HashSet<String> tags = new HashSet<>();
tags.add("turn");
tags.add("off");
tags.add("area");
tags.add("devices");
tags.add(env.getPojo().getName());
c.setTags(tags);
cp.create(c);
}
}
private static final Logger LOG = Logger.getLogger(RoomEvents.class.getName());
}