/* * Copyright 2012-2014 Nikolay A. Viguro * <p/> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ru.iris.devices.noolite; import com.avaje.ebean.Ebean; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import ru.iris.common.database.model.devices.Device; import ru.iris.common.database.model.devices.DeviceValue; import ru.iris.common.helpers.DBLogger; import ru.iris.common.messaging.JsonEnvelope; import ru.iris.common.messaging.JsonMessaging; import ru.iris.common.messaging.JsonNotification; import ru.iris.common.messaging.model.devices.GenericAdvertisement; import ru.iris.common.modulestatus.Status; import ru.iris.noolite4j.sender.PC1132; import java.util.UUID; public class NooliteTXService { private final Logger LOGGER = LogManager.getLogger(NooliteTXService.class.getName()); private JsonMessaging jsonMessaging; private PC1132 pc; public NooliteTXService() { Status status = new Status("Noolite-TX"); if (status.checkExist()) { status.running(); } else { status.addIntoDB("Noolite TX", "Service that produce Noolite commands"); } try { // Initialize the libusb context pc = new PC1132(); pc.open(); jsonMessaging = new JsonMessaging(UUID.randomUUID(), "devices-noolite-tx"); jsonMessaging.subscribe("event.devices.setvalue"); jsonMessaging.subscribe("event.devices.noolite.value.set"); jsonMessaging.subscribe("event.devices.noolite.tx.bindchannel"); jsonMessaging.subscribe("event.devices.noolite.tx.unbindchannel"); jsonMessaging.setNotification(new JsonNotification() { @Override public void onNotification(JsonEnvelope envelope) throws InterruptedException { // pause for next cmd Thread.sleep(500); if (envelope.getObject() instanceof GenericAdvertisement) { GenericAdvertisement advertisement = envelope.getObject(); Device device = null; byte channel; String uuid = (String) advertisement.getValue("uuid"); if (uuid == null) uuid = (String) advertisement.getValue(); if (!advertisement.getLabel().equals("BindTXChannel") && !advertisement.getLabel().equals("UnbindTXChannel")) { device = Ebean.find(Device.class).where().eq("uuid", uuid).findUnique(); if (device != null && !device.getSource().equals("noolite")) { LOGGER.info("Device with UUID " + uuid + " is not Noolite!"); return; } if (device == null) { LOGGER.info("Cant find device with UUID " + uuid); return; } channel = Byte.valueOf(device.getValue("channel").getValue()); } else { channel = Double.valueOf(advertisement.getValue().toString()).byteValue(); } switch (advertisement.getLabel()) { case "DeviceOn": LOGGER.info("Turn on device on channel " + channel); updateValue(device, "Level", "255"); DBLogger.info("Device is ON", device.getUuid()); pc.turnOn(channel); break; case "DeviceOff": LOGGER.info("Turn off device on channel " + channel); updateValue(device, "Level", "0"); DBLogger.info("Device is OFF", device.getUuid()); pc.turnOff(channel); break; case "DeviceSetLevel": byte level; if ((Byte) advertisement.getValue("Level") == 255) level = 100; else level = (Byte) advertisement.getValue("Level"); //if noolite device dimmer (user set) if (device.getValue("type") != null && device.getValue("type").getValue().contains("dimmer")) { if (level > 99 || level == 99) { LOGGER.info("Turn on device on channel " + channel); updateValue(device, "Level", "255"); DBLogger.info("Device is ON", device.getUuid()); pc.turnOn(channel); } else if (level < 0) { LOGGER.info("Turn off device on channel " + channel); updateValue(device, "Level", "0"); DBLogger.info("Device is OFF", device.getUuid()); pc.turnOff(channel); } else { updateValue(device, "Level", String.valueOf(level)); DBLogger.info("Device level set: " + level, device.getUuid()); LOGGER.info("Setting device on channel " + channel + " to level " + level); pc.setLevel(channel, level); } } else { if (level < 0 || level == 0) { LOGGER.info("Turn off device on channel " + channel); updateValue(device, "Level", "0"); DBLogger.info("Device is OFF", device.getUuid()); pc.turnOff(channel); } else { // turn on LOGGER.info("Turn on device on channel " + channel); updateValue(device, "Level", "255"); DBLogger.info("Device is ON", device.getUuid()); pc.turnOn(channel); } } break; case "DeviceDim": //TODO break; case "DeviceBright": //TODO break; case "DeviceStopDimBright": //TODO break; case "BindTXChannel": LOGGER.debug("Get BindTXChannel advertisement"); LOGGER.info("Binding device to channel " + channel); DBLogger.info("Binding device to channel " + channel); pc.bindChannel(channel); break; case "UnbindTXChannel": LOGGER.debug("Get UnbindTXChannel advertisement"); LOGGER.info("Unbinding device from channel " + channel); DBLogger.info("Unbinding device from channel " + channel); pc.unbindChannel(channel); break; default: LOGGER.debug("Unknown command type: " + advertisement.getLabel()); break; } // save device and values if (device != null) device.save(); } else if (envelope.getReceiverInstance() == null) { // We received unknown broadcast message. Lets make generic log entry. LOGGER.info("Received broadcast " + " from " + envelope.getSenderInstance() + " to " + envelope.getReceiverInstance() + " at '" + envelope.getSubject() + ": " + envelope.getObject()); } else { // We received unknown request message. Lets make generic log entry. LOGGER.info("Received request " + " from " + envelope.getSenderInstance() + " to " + envelope.getReceiverInstance() + " at '" + envelope.getSubject() + ": " + envelope.getObject()); } } }); jsonMessaging.start(); } catch (final Throwable t) { LOGGER.error("Error in Noolite-TX!"); status.crashed(); t.printStackTrace(); } } private void updateValue(Device device, String label, String value) { DeviceValue deviceValue = device.getValue(label); if (deviceValue == null) { deviceValue = new DeviceValue(); deviceValue.setLabel(label); deviceValue.setValue(value); deviceValue.setReadonly(false); deviceValue.setValueId("{ }"); } else { device.setValue(label, value); } } public void stop() { jsonMessaging.close(); pc.close(); } }