The principle of the Light Follow Me application is to switch on/off the lights in the different rooms if there is somebody or anybody. The following screenshot is an example of the application in action:
You need to create and generate the skeleton of the unique class of your application.
Create a new iPOJO Project.
Configure the iPOJO Preferences. Go to Windows -> Preferences -> iPOJO Preferences.
Create a new component BinaryFollowMe. Open the metadata.xml
file with the iPOJO Metadata Editor.
Click Add and change the component name to BinaryFollowMe.
Add to service dependencies (i.e. required services) with Multiple and Optional characteristics:
BinaryLight
with a field binaryLights
and bind/unbind methods named respectively bindBinaryLight
and unbindBinaryLight
;PresenceSensor
with a field presenceSensors
and bind/unbind methods named respectively bindPresenceSensor
and unbindPresenceSensor
.Add new methods start
and stop
for the Component Lifecycle Callbacks.
Generate the class with right click on your component.
Complete the package field.
If you have done that successfully, you will have a skeleton like this:
package com.example.binary.follow.me;
import fr.liglab.adele.icasa.device.light.BinaryLight;
import fr.liglab.adele.icasa.device.presence.PresenceSensor;
import java.util.Map;
public class BinaryLightFollowMeImpl {
/** Field for binaryLights dependency */
private BinaryLight[] binaryLights;
/** Field for presenceSensors dependency */
private PresenceSensor[] presenceSensors;
/** Bind Method for null dependency */
public void bindBinaryLight(BinaryLight binaryLight, Map properties) {
// TODO: Add your implementation code here
}
/** Unbind Method for null dependency */
public void unbindBinaryLight(BinaryLight binaryLight, Map properties) {
// TODO: Add your implementation code here
}
/** Bind Method for null dependency */
public void bindPresenceSensor(PresenceSensor presenceSensor, Map properties) {
// TODO: Add your implementation code here
}
/** Unbind Method for null dependency */
public void unbindPresenceSensor(PresenceSensor presenceSensor,
Map properties) {
// TODO: Add your implementation code here
}
/** Component Lifecycle Method */
public void stop() {
// TODO: Add your implementation code here
}
/** Component Lifecycle Method */
public void start() {
// TODO: Add your implementation code here
}
}
In order to be notified when something is modified in the environment, the BinaryLightFollowMeImpl
class must implement DeviceListener
interface.
public class BinaryLightFollowMeImpl implements DeviceListener
Add two attributes in this BinaryLightFollowMeImpl
class:
listBinaryLight
is a list containing all the lights available in the environment;mapPresenceSensor
is a map containing all the presence sensors available in the environment.
/** List containing all the lights in the house */
private List listBinaryLights;
/** Map containing all the presenceSensors in the house */
private Map mapPresenceSensors;
Complete the code of bind
and unbind
methods by adding and removing devices from their respective sets.
/** Bind Method for null dependency */
public void bindBinaryLight(BinaryLight binaryLight, Map properties) {
listBinaryLights.add(binaryLight);
}
/** Unbind Method for null dependency */
public void unbindBinaryLight(BinaryLight binaryLight, Map properties) {
listBinaryLights.remove(binaryLight);
}
/** Bind Method for null dependency */
public void bindPresenceSensor(PresenceSensor presenceSensor, Map properties) {
mapPresenceSensors.put(presenceSensor.getSerialNumber(), presenceSensor);
}
/** Unbind Method for null dependency */
public void unbindPresenceSensor(PresenceSensor presenceSensor,
Map properties) {
mapPresenceSensors.remove(presenceSensor.getSerialNumber());
}
Attach the listener to the interesting devices (in our case all the presence sensors) in the bind
method. Also unregister the listener when the sensor is leaving in the unbind
method.
/** Bind Method for null dependency */
public void bindPresenceSensor(PresenceSensor presenceSensor, Map properties) {
presenceSensor.addListener(this);
mapPresenceSensors.put(presenceSensor.getSerialNumber(), presenceSensor);
}
/** Unbind Method for null dependency */
public void unbindPresenceSensor(PresenceSensor presenceSensor,
Map properties) {
presenceSensor.removeListener(this);
mapPresenceSensors.remove(presenceSensor.getSerialNumber());
}
Complete the start
and stop
lifecycle methods with a message. Initialize the required fields at validate and clear those fields at invalidate.
/** Component Lifecycle Method */
public void stop() {
System.out.println("Component is stopping...");
listBinaryLights = null;
mapPresenceSensors = null;
}
/** Component Lifecycle Method */
public void start() {
System.out.println("Component is starting...");
listBinaryLights = new ArrayList();
mapPresenceSensors = new HashMap();
}
Create a method named getBinaryLightFromLocation
. This method will create a list of all binary lights from a location.
/**
- Method which catches all BinaryLights from a location
- @param location
@return List of BinaryLights
*/
private List<BinaryLight> getBinaryLightFromLocation(String location) {
List<BinaryLight> binaryLightsLocation = new ArrayList<BinaryLight>();
for(BinaryLight binaryLight : listBinaryLights) {
if(binaryLight.getPropertyValue(LOCATIONPROPERTYNAME).equals(location)) {
binaryLightsLocation.add(binaryLight);
}
}
return binaryLightsLocation;
}
LOCATION_PROPERTY_NAME
is a constant defined and intialized previously in this class:
public static String LOCATIONPROPERTYNAME = "Location";
Manage the light(s) if a presence is sensed in a location. In the method devicePropertyModified
, there is the core of the application: if the device is an instance of PresenceSensor
, the device is identified by its serial number. According to its location, all the lights in the same location are turn on or off.
@Override
public void devicePropertyModified(GenericDevice device, String propertyName, Object oldValue, Object newValue) {
if(device instanceof PresenceSensor) {
PresenceSensor activSensor = mapPresenceSensors.get(device.getSerialNumber());
if(activSensor != null && propertyName.equals(PresenceSensor.PRESENCE_SENSOR_SENSED_PRESENCE)) {
String detectorLocation = (String) activSensor.getPropertyValue(LOCATION_PROPERTY_NAME);
if(!detectorLocation.equals(LOCATION_UNKNOW)) {
List sameLocationLights = getBinaryLightFromLocation(detectorLocation);
for(BinaryLight binaryLight : sameLocationLights) {
binaryLight.setPowerStatus(!(Boolean) oldValue);
}
}
}
}
}
LOCATION_UNKNOWN
is a constant defined and intialized previously in this class:
public static String LOCATION_UNKNOWN = "unknown";
Create a component instance from the metadata.xml file with the iPOJO Metadata Editor. Open the second tab Component Configuration. Right click on BinaryLightFollowMe bundle -> New Instance Declaration.
Right click on your project: iCasa -> iCasa Bundle Deployment
Test your application with iCasa Simulator.