/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.bticino.internal; import java.util.List; import org.openhab.binding.bticino.internal.BticinoGenericBindingProvider.BticinoBindingConfig; import org.openhab.core.events.EventPublisher; import org.openhab.core.items.Item; import org.openhab.core.library.items.NumberItem; import org.openhab.core.library.items.RollershutterItem; import org.openhab.core.library.items.SwitchItem; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.PercentType; import org.openhab.core.library.types.IncreaseDecreaseType; import org.openhab.core.library.types.StopMoveType; import org.openhab.core.library.types.UpDownType; import org.openhab.core.types.Command; import org.openhab.core.types.State; import org.openhab.core.types.UnDefType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import be.devlaminck.openwebnet.IBticinoEventListener; import be.devlaminck.openwebnet.OpenWebNet; import be.devlaminck.openwebnet.ProtocolRead; /** * This class connects to the openweb gateway of bticino (MH200(N)). It opens a * monitor session to retrieve the events and creates, for every command * received, a command on the bus. * * @author Tom De Vlaminck * @serial 1.0 * @since 1.7.0 */ public class BticinoDevice implements IBticinoEventListener { // The ID of this gateway (corresponds with the .cfg) private String m_gateway_id; // The Bticino binding object (needed to send the events back + retrieve // information about the binding config of the items) private BticinoBinding m_bticino_binding; // Hostname or Host IP (of the MH200) private String m_host = ""; // Port to connect to private int m_port = 0; // Rescan interval in seconds private int m_rescan_interval_secs = 0; // Indicator if this device is started private boolean m_device_is_started = false; // A lock object private Object m_lock = new Object(); // The openweb object that handles connections and events private OpenWebNet m_open_web_net; private static final Logger logger = LoggerFactory.getLogger(BticinoDevice.class); private EventPublisher eventPublisher; public BticinoDevice(String p_gateway_id, BticinoBinding p_bticino_binding) { m_gateway_id = p_gateway_id; m_bticino_binding = p_bticino_binding; } public void setHost(String p_host) { m_host = p_host; } public void setPort(int p_port) { m_port = p_port; } public void setRescanInterval(int p_rescan_interval_secs) { m_rescan_interval_secs = p_rescan_interval_secs; } public void setEventPublisher(EventPublisher eventPublisher) { this.eventPublisher = eventPublisher; } public void unsetEventPublisher(EventPublisher eventPublisher) { this.eventPublisher = null; } /** * Initialize this device * * @throws InitializationException */ public void initialize() throws InitializationException { // Add other initialization stuff here logger.debug("Gateway [" + m_gateway_id + "], initialize OK"); } /** * Start this device * */ public void startDevice() { if (m_open_web_net == null) { m_open_web_net = new OpenWebNet(m_host, m_port, m_rescan_interval_secs); m_open_web_net.addEventListener(this); m_open_web_net.onStart(); } m_device_is_started = true; logger.debug("Gateway [" + m_gateway_id + "], started OK"); } public void stopDevice() { if (m_open_web_net != null) { m_open_web_net.interrupt(); m_open_web_net = null; } m_device_is_started = false; } public boolean isDeviceStarted() { return m_device_is_started; } public void receiveCommand(String itemName, Command command, BticinoBindingConfig itemBindingConfig) { try { synchronized (m_lock) { // A command is received from the openHab system; // analyse it and execute it logger.debug("Gateway [" + m_gateway_id + "], Command '{}' received for item {}", (Object[]) new String[] { command.toString(), itemName }); ProtocolRead l_pr = new ProtocolRead(itemBindingConfig.who + "*" + itemBindingConfig.where); l_pr.addProperty("who", itemBindingConfig.who); l_pr.addProperty("address", itemBindingConfig.where); int l_who = Integer.parseInt(itemBindingConfig.who); switch (l_who) { // Lights case 1: { if (command instanceof IncreaseDecreaseType ) { if( IncreaseDecreaseType.INCREASE.equals(command) ) { logger.debug("Light received INCREASE command."); l_pr.addProperty("what", "30"); } else { logger.debug("Light received DECREASE command."); l_pr.addProperty("what", "31"); } } else if (command instanceof PercentType) { PercentType pType = (PercentType)command; //take percentage and divide by 10, round 1 (ie 0 to 10 is the result, nothing else) int percentValue = (int)(Math.floor(pType.intValue()/10F)); logger.debug("Set light value to {}", percentValue); l_pr.addProperty("what", String.valueOf(percentValue)); } else if (command instanceof OnOffType) { if (OnOffType.ON.equals(command)) { l_pr.addProperty("what", "1"); } else { l_pr.addProperty("what", "0"); } } else { logger.warn("Received unknown command type for lighting: '{}'", command.getClass().getName()); } break; } // Shutter case 2: { if (UpDownType.UP.equals(command)) { l_pr.addProperty("what", "1"); } else if (UpDownType.DOWN.equals(command)) { l_pr.addProperty("what", "2"); } else if (StopMoveType.STOP.equals(command)) { l_pr.addProperty("what", "0"); } break; } // CEN Basic & Evolved case 15: { // Only for the on type, send a CEN event (aka a pushbutton // device) // the CEN can start a scenario on eg. a MH200N gateway // device if (OnOffType.ON.equals(command)) { l_pr.addProperty("what", itemBindingConfig.what); } break; } } m_open_web_net.onCommand(l_pr); } } catch (Exception e) { logger.error("Gateway [" + m_gateway_id + "], Error processing receiveCommand '{}'", (Object[]) new String[] { e.getMessage() }); } } public void handleEvent(ProtocolRead p_protocol_read) throws Exception { // the events on the bus are now received // map them to events on the openhab bus logger.debug("Gateway [" + m_gateway_id + "], Bticino WHO [" + p_protocol_read.getProperty("who") + "], WHAT [" + p_protocol_read.getProperty("what") + "], WHERE [" + p_protocol_read.getProperty("where") + "]"); // Get all the configs that are connected to this (who,where), multiple // possible List<BticinoBindingConfig> l_binding_configs = m_bticino_binding.getItemForBticinoBindingConfig( p_protocol_read.getProperty("who"), p_protocol_read.getProperty("where")); // log it when an event has occured that no item is bound to if (l_binding_configs.isEmpty()) { logger.debug("Gateway [" + m_gateway_id + "], No Item found for bticino event, WHO [" + p_protocol_read.getProperty("who") + "], WHAT [" + p_protocol_read.getProperty("what") + "], WHERE [" + p_protocol_read.getProperty("where") + "]"); } // every item associated with this who/where update the status for (BticinoBindingConfig l_binding_config : l_binding_configs) { // Get the Item out of the config Item l_item = l_binding_config.getItem(); if (l_item instanceof SwitchItem) { // Lights if (p_protocol_read.getProperty("messageType").equalsIgnoreCase("lighting")) { logger.debug("Gateway [" + m_gateway_id + "], RECEIVED EVENT FOR SwitchItem [" + l_item.getName() + "], TRANSLATE TO OPENHAB BUS EVENT"); if (p_protocol_read.getProperty("messageDescription").equalsIgnoreCase("Light ON")) { eventPublisher.postUpdate(l_item.getName(), OnOffType.ON); } else if (p_protocol_read.getProperty("messageDescription").equalsIgnoreCase("Light OFF")) { eventPublisher.postUpdate(l_item.getName(), OnOffType.OFF); } } // CENs else if (p_protocol_read.getProperty("messageType").equalsIgnoreCase("CEN Basic and Evolved")) { // Pushbutton virtual address must match if (l_binding_config.what.equalsIgnoreCase(p_protocol_read.getProperty("what"))) { logger.debug("Gateway [" + m_gateway_id + "], RECEIVED EVENT FOR SwitchItem [" + l_item.getName() + "], TRANSLATE TO OPENHAB BUS EVENT"); if (p_protocol_read.getProperty("messageDescription").equalsIgnoreCase("Virtual pressure")) { // only returns when finished eventPublisher.sendCommand(l_item.getName(), OnOffType.ON); } else if (p_protocol_read.getProperty("messageDescription") .equalsIgnoreCase("Virtual release after short pressure")) { // only returns when finished eventPublisher.sendCommand(l_item.getName(), OnOffType.ON); } else if (p_protocol_read.getProperty("messageDescription") .equalsIgnoreCase("Virtual release after an extended pressure")) { // only returns when finished eventPublisher.sendCommand(l_item.getName(), OnOffType.ON); } else if (p_protocol_read.getProperty("messageDescription") .equalsIgnoreCase("Virtual extended pressure")) { // only returns when finished eventPublisher.sendCommand(l_item.getName(), OnOffType.ON); } } } } else if (l_item instanceof RollershutterItem) { logger.debug("Gateway [" + m_gateway_id + "], RECEIVED EVENT FOR RollershutterItem [" + l_item.getName() + "], TRANSLATE TO OPENHAB BUS EVENT"); if (p_protocol_read.getProperty("messageType").equalsIgnoreCase("automation")) { if (p_protocol_read.getProperty("messageDescription").equalsIgnoreCase("Automation UP")) { eventPublisher.postUpdate(l_item.getName(), UpDownType.UP); } else if (p_protocol_read.getProperty("messageDescription").equalsIgnoreCase("Automation DOWN")) { eventPublisher.postUpdate(l_item.getName(), UpDownType.DOWN); } } } else if (l_item instanceof NumberItem) { logger.debug("Gateway [" + m_gateway_id + "], RECEIVED EVENT FOR NumberItem [" + l_item.getName() + "], TRANSLATE TO OPENHAB BUS EVENT"); // THERMOREGULATION if (p_protocol_read.getProperty("messageType").equalsIgnoreCase("thermoregulation")) { if (p_protocol_read.getProperty("messageDescription").equalsIgnoreCase("Temperature value")) { eventPublisher.postUpdate(l_item.getName(), DecimalType.valueOf(p_protocol_read.getProperty("temperature"))); } } } } } }