fr.immotronic.ubikit.pems.enocean.impl.item.IntesisBoxDKRCENO1i1iCDevice.java Source code

Java tutorial

Introduction

Here is the source code for fr.immotronic.ubikit.pems.enocean.impl.item.IntesisBoxDKRCENO1i1iCDevice.java

Source

/*
 * Copyright (c) Immotronic, 2012
 *
 * Contributors:
 *
 *     Lionel Balme (lbalme@immotronic.fr)
 *     Kevin Planchet (kplanchet@immotronic.fr)
 *
 * This file is part of ubikit-core, a component of the UBIKIT project.
 *
 * This software is a computer program whose purpose is to host third-
 * parties applications that make use of sensor and actuator networks.
 *
 * This software is governed by the CeCILL-C license under French law and
 * abiding by the rules of distribution of free software.  You can  use,
 * modify and/ or redistribute the software under the terms of the CeCILL-C
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * As a counterpart to the access to the source code and  rights to copy,
 * "http://www.cecill.info".
 *
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability.
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and,  more generally, to use and operate it in the
 * same conditions as regards security.
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL-C license and that you accept its terms.
 *
 * CeCILL-C licence is fully compliant with the GNU Lesser GPL v2 and v3.
 *
 */

package fr.immotronic.ubikit.pems.enocean.impl.item;

import org.json.JSONObject;
import org.ubikit.event.EventGate;

import fr.immotronic.ubikit.pems.enocean.ControllerProfile;
import fr.immotronic.ubikit.pems.enocean.EnoceanEquipmentProfileV20;
import fr.immotronic.ubikit.pems.enocean.SensorActuatorProfile;
import fr.immotronic.ubikit.pems.enocean.actuator.HVACDevice;
import fr.immotronic.ubikit.pems.enocean.data.EEP07201011Data;
import fr.immotronic.ubikit.pems.enocean.data.EEP07201011Data.Disablement;
import fr.immotronic.ubikit.pems.enocean.data.EEP07201011Data.FanSpeed;
import fr.immotronic.ubikit.pems.enocean.data.EEP07201011Data.Mode;
import fr.immotronic.ubikit.pems.enocean.data.EEP07201011Data.OnOffStatus;
import fr.immotronic.ubikit.pems.enocean.data.EEP07201011Data.RoomOccupancy;
import fr.immotronic.ubikit.pems.enocean.data.EEP07201011Data.VanePosition;
import fr.immotronic.ubikit.pems.enocean.data.EEP07201011Data.WindowsStatus;
import fr.immotronic.ubikit.pems.enocean.event.in.GenericHVACInterfaceControlEvent;
import fr.immotronic.ubikit.pems.enocean.event.in.GenericHVACInterfaceDisablementMessageEvent;
import fr.immotronic.ubikit.pems.enocean.event.in.TemperatureAndSetPointEvent;
import fr.immotronic.ubikit.pems.enocean.impl.DatabaseManager;
import fr.immotronic.ubikit.pems.enocean.impl.DeviceManager;
import fr.immotronic.ubikit.pems.enocean.impl.EnoceanSensorAndActuatorDeviceImpl;
import fr.immotronic.ubikit.pems.enocean.impl.NoControllerChannelLeftException;
import fr.immotronic.ubikit.pems.enocean.impl.item.datahandler.EEP07201011DataHandler;
import fr.immotronic.ubikit.pems.enocean.impl.item.data.EEP07201011DataImpl;

public final class IntesisBoxDKRCENO1i1iCDevice extends EnoceanSensorAndActuatorDeviceImpl
        implements TemperatureAndSetPointEvent.Listener, GenericHVACInterfaceDisablementMessageEvent.Listener,
        GenericHVACInterfaceControlEvent.Listener, HVACDevice {
    private float temperatureMultiplier = (255f / 40f);

    private FourByteSensorController controller_20_10;
    private FourByteSensorController controller_20_11;
    private FourByteSensorController controller_10_03;

    private float setPointTemperature = 20f;
    private float ambientTemperature = 20f;

    public IntesisBoxDKRCENO1i1iCDevice(EventGate eventGate, DatabaseManager.Record record,
            DeviceManager deviceManager) {
        super(record.getUID(), record.getEnoceanUID(), SensorActuatorProfile.INTESIS_BOX_DK_RC_ENO_1i1iC_DEVICE,
                record.getManufacturerUID(), deviceManager, null);

        setPropertiesFromJSONObject(record.getPropertiesAsJSON());
        addCapability(SensorActuatorProfile.INTESIS_BOX_DK_RC_ENO_1i1iC_DEVICE.name());

        int eep2010id = (int) Long.parseLong(getPropertyValue(EnoceanEquipmentProfileV20.EEP_07_20_10.name()), 16);
        int eep2011id = (int) Long.parseLong(getPropertyValue(EnoceanEquipmentProfileV20.EEP_07_20_11.name()), 16);

        // Registering additional Enocean UID in device manager
        if (getEnoceanUID() == eep2010id) {
            deviceManager.registerAdditionalEnoceanUID(getEnoceanUID(), eep2011id);
        } else {
            deviceManager.registerAdditionalEnoceanUID(getEnoceanUID(), eep2010id);
        }

        // Create Data handler
        EEP07201011DataHandler dh = new EEP07201011DataHandler(eventGate, getUID(), record.getLastKnownData());
        dh.setTransmitterUID(EnoceanEquipmentProfileV20.EEP_07_20_10, eep2010id);
        dh.setTransmitterUID(EnoceanEquipmentProfileV20.EEP_07_20_11, eep2011id);
        setDataHandler(dh);

        // Create controllers
        String[] controllers = record.getData().split(" ");
        controller_20_10 = (FourByteSensorController) deviceManager.getController(Integer.parseInt(controllers[0]));
        controller_20_10.markAsUsed();
        controller_20_11 = (FourByteSensorController) deviceManager.getController(Integer.parseInt(controllers[1]));
        controller_20_11.markAsUsed();
        controller_10_03 = (FourByteSensorController) deviceManager.getController(Integer.parseInt(controllers[2]));
        controller_10_03.markAsUsed();
    }

    public IntesisBoxDKRCENO1i1iCDevice(EventGate eventGate, int enoceanUID, DeviceManager deviceManager,
            JSONObject userProperties) throws NoControllerChannelLeftException {
        super(enoceanUID, SensorActuatorProfile.INTESIS_BOX_DK_RC_ENO_1i1iC_DEVICE, 0x19, deviceManager, null);

        setPropertiesFromJSONObject(userProperties);
        addCapability(SensorActuatorProfile.INTESIS_BOX_DK_RC_ENO_1i1iC_DEVICE.name());

        int eep2010id = (int) Long.parseLong(getPropertyValue(EnoceanEquipmentProfileV20.EEP_07_20_10.name()), 16);
        int eep2011id = (int) Long.parseLong(getPropertyValue(EnoceanEquipmentProfileV20.EEP_07_20_11.name()), 16);

        // Registering additional Enocean UID in device manager
        if (getEnoceanUID() == eep2010id) {
            deviceManager.registerAdditionalEnoceanUID(getEnoceanUID(), eep2011id);
        } else {
            deviceManager.registerAdditionalEnoceanUID(getEnoceanUID(), eep2010id);
        }

        // Create Data handler
        EEP07201011DataHandler dh = new EEP07201011DataHandler(eventGate, getUID(), null);
        dh.setTransmitterUID(EnoceanEquipmentProfileV20.EEP_07_20_10, eep2010id);
        dh.setTransmitterUID(EnoceanEquipmentProfileV20.EEP_07_20_11, eep2011id);
        setDataHandler(dh);

        // Create controllers
        controller_20_10 = (FourByteSensorController) deviceManager
                .getController(ControllerProfile.FOUR_BYTE_SENSOR_CONTROLLER, 1);
        if (controller_20_10 == null) {
            throw new NoControllerChannelLeftException();
        }
        controller_20_10.markAsUsed();

        controller_20_11 = (FourByteSensorController) deviceManager
                .getController(ControllerProfile.FOUR_BYTE_SENSOR_CONTROLLER, 1);
        if (controller_20_11 == null) {
            throw new NoControllerChannelLeftException();
        }
        controller_20_11.markAsUsed();

        controller_10_03 = (FourByteSensorController) deviceManager
                .getController(ControllerProfile.FOUR_BYTE_SENSOR_CONTROLLER, 1);
        if (controller_10_03 == null) {
            throw new NoControllerChannelLeftException();
        }
        controller_10_03.markAsUsed();
    }

    @Override
    public FourByteSensorController[] releaseController() {
        if (controller_20_10 != null && controller_20_11 != null && controller_10_03 != null) {
            FourByteSensorController[] controllers = new FourByteSensorController[3];

            controller_20_10.releaseChannel(1);
            controllers[0] = controller_20_10;
            controller_20_10 = null;

            controller_20_11.releaseChannel(1);
            controllers[1] = controller_20_11;
            controller_20_11 = null;

            controller_10_03.releaseChannel(1);
            controllers[2] = controller_10_03;
            controller_10_03 = null;

            return controllers;
        }

        return null;
    }

    @Override
    public void onEvent(GenericHVACInterfaceControlEvent event) {
        if (event.getSourceItemUID().equals(getUID()) && controller_20_10 != null) {
            sendCommand(event.getMode(), event.getVanePosition(), event.getFanSpeed(), event.getRoomOccupancy(),
                    event.getOnOrOff());
        }
    }

    public void setMode(Mode mode) {
        sendCommand(mode, VanePosition.NO_ACTION, FanSpeed.NO_ACTION, getLastKnownData().getRoomOccupancy(),
                getLastKnownData().getOnOffStatus());
    }

    public void setVanePosition(VanePosition vanePosition) {
        sendCommand(Mode.NO_ACTION, vanePosition, FanSpeed.NO_ACTION, getLastKnownData().getRoomOccupancy(),
                getLastKnownData().getOnOffStatus());
    }

    public void setFanSpeed(FanSpeed fanSpeed) {
        sendCommand(Mode.NO_ACTION, VanePosition.NO_ACTION, fanSpeed, getLastKnownData().getRoomOccupancy(),
                getLastKnownData().getOnOffStatus());
    }

    public void setOnOrOff(OnOffStatus onOffStatus) {
        sendCommand(Mode.NO_ACTION, VanePosition.NO_ACTION, FanSpeed.NO_ACTION,
                getLastKnownData().getRoomOccupancy(), onOffStatus);
    }

    private void sendCommand(Mode mode, VanePosition position, FanSpeed speed, RoomOccupancy roomOccupancy,
            OnOffStatus turnOnOff) {
        if (controller_20_10 != null) {
            EEP07201011Data data = getLastKnownData();
            data = new EEP07201011DataImpl((mode != Mode.NO_ACTION) ? mode : data.getMode(),
                    (position != VanePosition.NO_ACTION) ? position : data.getVanePosition(),
                    (speed != FanSpeed.NO_ACTION) ? speed : data.getFanSpeed(), data.getRoomOccupancy(), turnOnOff,
                    data.getErrorCode(), data.getWindowContactDisablement(), data.getKeyCardDisablement(),
                    data.getExternalDisablement(), data.getRemoteControllerDisablement(), data.getWindowContact(),
                    data.getAlarmState(), data.getDate());
            ((EEP07201011DataHandler) getDataHandler()).setData(data);

            byte[] bytes = { (byte) (((roomOccupancy.getValue() << 1) | (turnOnOff.getValue())) & 0x7), // DB_0 : RoomOccupancy & On/Off data
                    0x00, // DB_1 : Not used
                    (byte) ((position.getValue() << 4 | speed.getValue()) & 0xff), // DB_2 : Vane position (4 MSB) & Fan speed (4 LSB)
                    mode.getValue() // DB_3 : Mode
            };
            controller_20_10.sendDataTelegram(bytes);
        }
    }

    @Override
    public void onEvent(GenericHVACInterfaceDisablementMessageEvent event) {
        if (event.getSourceItemUID().equals(getUID()) && controller_20_11 != null) {
            sendDisablementMessage(event.hasExternalDisablement(), event.isRemoteControllerDisable(),
                    event.isWindowClosed());
        }
    }

    public void setExternalDisablement(Disablement disablement) {
        sendDisablementMessage(disablement, getLastKnownData().getRemoteControllerDisablement(),
                getLastKnownData().getWindowContact());
    }

    public void setRemoteControllerDisablement(Disablement disablement) {
        sendDisablementMessage(getLastKnownData().getExternalDisablement(), disablement,
                getLastKnownData().getWindowContact());
    }

    public void setWindowsStatus(WindowsStatus windowsStatus) {
        sendDisablementMessage(getLastKnownData().getExternalDisablement(),
                getLastKnownData().getRemoteControllerDisablement(), windowsStatus);
    }

    private void sendDisablementMessage(Disablement hasExternalDisablement, Disablement remoteControllerDisable,
            WindowsStatus windowStatus) {
        if (controller_20_11 != null) {
            EEP07201011Data data = getLastKnownData();
            data = new EEP07201011DataImpl(data.getMode(), data.getVanePosition(), data.getFanSpeed(),
                    data.getRoomOccupancy(), data.getOnOffStatus(), data.getErrorCode(),
                    data.getWindowContactDisablement(), data.getKeyCardDisablement(), hasExternalDisablement,
                    remoteControllerDisable, windowStatus, data.getAlarmState(), data.getDate());
            ((EEP07201011DataHandler) getDataHandler()).setData(data);
            byte[] bytes = {
                    (byte) (((windowStatus.getValue() << 1) | (remoteControllerDisable.getValue() << 2)) & 0x6), // DB_0
                    hasExternalDisablement.getValue(), // DB_1                
                    0x00, // DB_2 : Not used
                    0x00 // DB_3 : Not used
            };
            controller_20_11.sendDataTelegram(bytes);
        }
    }

    @Override
    public void onEvent(TemperatureAndSetPointEvent event) {
        if (event.getSourceItemUID().equals(getUID()) && controller_10_03 != null) {
            sendDataTemperature(event.getSetPoint(), event.getCurrentTemperature());
        }
    }

    @Override
    public void setSetPointTemperature(float setPointTemperature) {
        sendDataTemperature(setPointTemperature, this.ambientTemperature);
    }

    @Override
    public void setAmbientTemperature(float ambientTemperature) {
        sendDataTemperature(this.setPointTemperature, ambientTemperature);
    }

    private void sendDataTemperature(float setPointTemperature, float ambientTemperature) {
        if (setPointTemperature != Float.MIN_VALUE) {
            this.setPointTemperature = setPointTemperature;
        }

        if (ambientTemperature != Float.MIN_VALUE) {
            this.ambientTemperature = ambientTemperature;
        }

        if (controller_10_03 != null) {
            byte setPoint;
            if (this.setPointTemperature < 0)
                setPoint = 0x00;
            else if (this.setPointTemperature > 40)
                setPoint = (byte) 0xff;
            else
                setPoint = (byte) ((int) (this.setPointTemperature * temperatureMultiplier) & 0xff);

            byte temp;
            if (this.ambientTemperature < 0)
                temp = (byte) 0xff;
            else if (this.ambientTemperature > 40)
                temp = 0x00;
            else
                temp = (byte) ((int) ((255 - (this.ambientTemperature * temperatureMultiplier))) & 0xff);

            byte[] bytes = { 0x8, temp, setPoint, 0x0 };
            controller_10_03.sendDataTelegram(bytes);
        }
    }

    private EEP07201011DataImpl getLastKnownData() {
        return (EEP07201011DataImpl) getDataHandler().getLastKnownData();
    }

    @Override
    public DatabaseManager.Record getDeviceRecord() {
        DatabaseManager.Record rec = this.getPreFilledRecordWithoutData();
        rec.setData(Integer.toString(controller_20_10.getControllerIndex()) + " "
                + Integer.toString(controller_20_11.getControllerIndex()) + " "
                + Integer.toString(controller_10_03.getControllerIndex()));
        rec.setLastKnownData(getDataHandler().getLastKnownData().getRecordAsJSON());
        return rec;
    }

    @Override
    public void sendPairingSignals(int signalID) {
        if (controller_20_10 != null && controller_20_11 != null && controller_10_03 != null) {
            controller_20_10.sendPairingSignal((byte) 0x20, (byte) 0x10, (byte) 0x00, (byte) 0x80);
            controller_20_11.sendPairingSignal((byte) 0x20, (byte) 0x11, (byte) 0x00, (byte) 0x80);
            controller_10_03.sendPairingSignal((byte) 0x10, (byte) 0x03, (byte) 0x00, (byte) 0x80);
        }
    }

    @Override
    public boolean isModeSupported(Mode mode) {
        switch (mode) {
        case AUTO:
        case HEAT:
        case COOL:
        case FAN_ONLY:
        case DRY:
        case NO_ACTION:
            return true;
        default:
            return false;
        }
    }

    @Override
    public boolean isFanSpeedSupported(FanSpeed fanSpeed) {
        switch (fanSpeed) {
        case SPEED_1:
        case SPEED_2:
        case SPEED_3:
        case NO_ACTION:
            return true;
        default:
            return false;
        }
    }

    @Override
    public boolean isVanePositionSupported(VanePosition vanePosition) {
        switch (vanePosition) {
        case HORIZONTAL:
        case POSITION_2:
        case POSITION_3:
        case POSITION_4:
        case VERTICAL:
        case VERTICAL_SWING:
        case NO_ACTION:
            return true;
        default:
            return false;
        }
    }

    @Override
    public boolean isRoomOccupancySupported(RoomOccupancy fanSpeed) {
        return true;
    }

    @Override
    protected void terminate() {
        // Release channel should be done here, not in deviceManager.
    }
}