Search in sources :

Example 1 with MaxCulBindingProvider

use of org.openhab.binding.maxcul.MaxCulBindingProvider in project openhab1-addons by openhab.

the class MaxCulBinding method internalReceiveCommand.

/**
     * @{inheritDoc
     */
@Override
protected void internalReceiveCommand(final String itemName, Command command) {
    Timer pairModeTimer = null;
    MaxCulBindingConfig bindingConfig = null;
    for (MaxCulBindingProvider provider : super.providers) {
        bindingConfig = provider.getConfigForItemName(itemName);
        if (bindingConfig != null) {
            break;
        }
    }
    logger.debug("Received command " + command.toString() + " for item " + itemName);
    if (bindingConfig != null) {
        logger.debug("Found config for " + itemName);
        switch(bindingConfig.getDeviceType()) {
            case PAIR_MODE:
                if ((command instanceof OnOffType)) {
                    switch((OnOffType) command) {
                        case ON:
                            /*
                                 * turn on pair mode and schedule disabling of pairing
                                 * mode
                                 */
                            pairMode = true;
                            TimerTask task = new TimerTask() {

                                @Override
                                public void run() {
                                    logger.debug(itemName + " pairMode timeout executed");
                                    pairMode = false;
                                    eventPublisher.postUpdate(itemName, OnOffType.OFF);
                                }
                            };
                            pairModeTimer = timers.get(itemName);
                            if (pairModeTimer != null) {
                                pairModeTimer.cancel();
                                timers.remove(itemName);
                            }
                            pairModeTimer = new Timer();
                            timers.put(itemName, pairModeTimer);
                            pairModeTimer.schedule(task, pairModeTimeout);
                            logger.debug(itemName + " pairMode enabled & timeout scheduled");
                            break;
                        case OFF:
                            /*
                                 * we are manually disabling, so clear the timer and the
                                 * flag
                                 */
                            pairMode = false;
                            pairModeTimer = timers.get(itemName);
                            if (pairModeTimer != null) {
                                logger.debug(itemName + " pairMode timer cancelled");
                                pairModeTimer.cancel();
                                timers.remove(itemName);
                            }
                            logger.debug(itemName + " pairMode cleared");
                            break;
                    }
                } else {
                    logger.warn("Command not handled for " + bindingConfig.getDeviceType() + " that is not OnOffType");
                }
                break;
            case LISTEN_MODE:
                if (command instanceof OnOffType) {
                    this.messageHandler.setListenMode(((OnOffType) command == OnOffType.ON));
                } else {
                    logger.warn("Command not handled for " + bindingConfig.getDeviceType() + " that is not OnOffType");
                }
                break;
            case LED_MODE:
                if (command instanceof OnOffType) {
                    this.messageHandler.setLedMode(((OnOffType) command == OnOffType.ON));
                } else {
                    logger.warn("Command not handled for " + bindingConfig.getDeviceType() + " that is not OnOffType");
                }
                break;
            case RADIATOR_THERMOSTAT:
            case RADIATOR_THERMOSTAT_PLUS:
            case WALL_THERMOSTAT:
                if (bindingConfig.getFeature() == MaxCulFeature.THERMOSTAT) {
                    /* clear out old pacing timer */
                    if (pacedBindingTransmitTimers.containsKey(bindingConfig)) {
                        pacedBindingTransmitTimers.get(bindingConfig).cancel();
                        pacedBindingTransmitTimers.remove(bindingConfig);
                    }
                    /* schedule new timer */
                    Timer pacingTimer = new Timer();
                    pacedBindingTransmitTimers.put(bindingConfig, pacingTimer);
                    pacingTimer.schedule(new MaxCulPacedThermostatTransmitTask(command, bindingConfig, messageHandler, super.providers), PACED_TRANSMIT_TIME);
                } else if (bindingConfig.getFeature() == MaxCulFeature.DISPLAYSETTING) {
                    messageHandler.sendSetDisplayActualTemp(bindingConfig.getDevAddr(), ((OnOffType) command == OnOffType.ON));
                } else if (bindingConfig.getFeature() == MaxCulFeature.RESET) {
                    messageHandler.sendReset(bindingConfig.getDevAddr());
                } else {
                    logger.warn("Command not handled for " + bindingConfig.getDeviceType() + " that is not OnOffType or DecimalType");
                }
                break;
            case SHUTTER_CONTACT:
                if (bindingConfig.getFeature() == MaxCulFeature.RESET) {
                    messageHandler.sendReset(bindingConfig.getDevAddr());
                }
                break;
            default:
                logger.warn("Command not handled for " + bindingConfig.getDeviceType());
                break;
        }
    }
    updateCreditMonitors();
}
Also used : Timer(java.util.Timer) TimerTask(java.util.TimerTask) OnOffType(org.openhab.core.library.types.OnOffType) MaxCulBindingProvider(org.openhab.binding.maxcul.MaxCulBindingProvider)

Example 2 with MaxCulBindingProvider

use of org.openhab.binding.maxcul.MaxCulBindingProvider in project openhab1-addons by openhab.

the class MaxCulBinding method updateCreditMonitors.

private void updateCreditMonitors() {
    /* find and update credit monitor binding if it exists */
    int credit10ms = messageHandler.getCreditStatus();
    for (MaxCulBindingProvider provider : super.providers) {
        Collection<MaxCulBindingConfig> bindingConfigs = provider.getCreditMonitorBindings();
        for (MaxCulBindingConfig bc : bindingConfigs) {
            String itemName = provider.getItemNameForConfig(bc);
            eventPublisher.postUpdate(itemName, new DecimalType(credit10ms));
        }
    }
}
Also used : MaxCulBindingProvider(org.openhab.binding.maxcul.MaxCulBindingProvider) DecimalType(org.openhab.core.library.types.DecimalType)

Example 3 with MaxCulBindingProvider

use of org.openhab.binding.maxcul.MaxCulBindingProvider in project openhab1-addons by openhab.

the class MaxCulMsgHandler method dataReceived.

@Override
public void dataReceived(String data) {
    logger.debug("MaxCulSender Received " + data);
    if (data.startsWith("Z")) {
        if (listenMode) {
            listenModeHandler(data);
            return;
        }
        /* Check message is destined for us */
        if (BaseMsg.isForUs(data, srcAddr)) {
            boolean passToBinding = true;
            /* Handle Internal Messages */
            MaxCulMsgType msgType = BaseMsg.getMsgType(data);
            if (msgType == MaxCulMsgType.ACK) {
                passToBinding = false;
                AckMsg msg = new AckMsg(data);
                if (pendingAckQueue.containsKey(msg.msgCount) && msg.dstAddrStr.compareTo(srcAddr) == 0) {
                    SenderQueueItem qi = pendingAckQueue.remove(msg.msgCount);
                    /* verify ACK */
                    if ((qi.msg.dstAddrStr.equalsIgnoreCase(msg.srcAddrStr)) && (qi.msg.srcAddrStr.equalsIgnoreCase(msg.dstAddrStr))) {
                        if (msg.getIsNack()) {
                            /* NAK'd! */
                            // TODO resend?
                            logger.error("Message was NAK'd, packet lost");
                        } else {
                            logger.debug("Message " + msg.msgCount + " ACK'd ok!");
                        }
                    }
                } else {
                    logger.info("Got ACK for message " + msg.msgCount + " but it wasn't in the queue");
                }
            }
            if (sequenceRegister.containsKey(new BaseMsg(data).msgCount)) {
                passToBinding = false;
                /*
                     * message found in sequence register, so it will be handled
                     * by the sequence
                     */
                BaseMsg bMsg = new BaseMsg(data);
                logger.debug("Message " + bMsg.msgCount + " is part of sequence. Running next step in sequence.");
                sequenceRegister.get(bMsg.msgCount).runSequencer(bMsg);
                sequenceRegister.remove(bMsg.msgCount);
            }
            if (passToBinding) {
                /* pass data to binding for processing */
                this.mcbmp.maxCulMsgReceived(data, false);
            }
        } else if (BaseMsg.isForUs(data, "000000")) {
            switch(BaseMsg.getMsgType(data)) {
                case PAIR_PING:
                case WALL_THERMOSTAT_CONTROL:
                case THERMOSTAT_STATE:
                case WALL_THERMOSTAT_STATE:
                    this.mcbmp.maxCulMsgReceived(data, true);
                    break;
                default:
                    /* TODO handle other broadcast */
                    logger.debug("Unhandled broadcast message of type " + BaseMsg.getMsgType(data).toString());
                    break;
            }
        } else {
            // Associated devices send messages that tell of their status to
            // the associated
            // device. We need to spy on devices we know about to extract
            // useful data
            boolean passToBinding = false;
            BaseMsg bMsg = new BaseMsg(data);
            for (MaxCulBindingProvider provider : providers) {
                // look up source device configs
                List<MaxCulBindingConfig> configs = provider.getConfigsForRadioAddr(bMsg.srcAddrStr);
                if (!configs.isEmpty()) {
                    // get asssociated devices with source device
                    String serialNum = configs.get(0).getSerialNumber();
                    HashSet<MaxCulBindingConfig> assocDevs = provider.getAssociations(serialNum);
                    if (!assocDevs.isEmpty()) {
                        // message dest
                        for (MaxCulBindingConfig device : assocDevs) {
                            if (device.getDevAddr().equalsIgnoreCase(bMsg.dstAddrStr)) {
                                passToBinding = true;
                                break;
                            }
                        }
                    }
                }
            }
            if (passToBinding && (BaseMsg.getMsgType(data) != MaxCulMsgType.PAIR_PING && BaseMsg.getMsgType(data) != MaxCulMsgType.ACK)) {
                /*
                     * pass data to binding for processing - pretend it is
                     * broadcast so as not to ACK
                     */
                this.mcbmp.maxCulMsgReceived(data, true);
            }
        }
    }
}
Also used : BaseMsg(org.openhab.binding.maxcul.internal.messages.BaseMsg) AckMsg(org.openhab.binding.maxcul.internal.messages.AckMsg) MaxCulBindingProvider(org.openhab.binding.maxcul.MaxCulBindingProvider) LinkedList(java.util.LinkedList) List(java.util.List) MaxCulMsgType(org.openhab.binding.maxcul.internal.messages.MaxCulMsgType) HashSet(java.util.HashSet)

Example 4 with MaxCulBindingProvider

use of org.openhab.binding.maxcul.MaxCulBindingProvider in project openhab1-addons by openhab.

the class MaxCulBinding method maxCulMsgReceived.

@Override
public void maxCulMsgReceived(String data, boolean isBroadcast) {
    logger.debug("Received data from CUL: " + data);
    MaxCulMsgType msgType = BaseMsg.getMsgType(data);
    /*
         * Check if it's broadcast and we're in pair mode or a PAIR_PING message
         * directly for us
         */
    if (((pairMode && isBroadcast) || !isBroadcast) && msgType == MaxCulMsgType.PAIR_PING) {
        logger.debug("Got PAIR_PING message");
        MaxCulBindingConfig configWithTempsConfig = null;
        /* process packet */
        PairPingMsg pkt = new PairPingMsg(data);
        /* Match serial number to binding configuration */
        Collection<MaxCulBindingConfig> bindingConfigs = getBindingsBySerial(pkt.serial);
        /*
             * only respond and set pairing info if we found at least one
             * binding config
             */
        if (bindingConfigs != null) {
            logger.debug("Found " + bindingConfigs.size() + " configs for " + pkt.serial);
            for (MaxCulBindingConfig bc : bindingConfigs) {
                /* Set pairing information */
                bc.setPairedInfo(pkt.srcAddrStr);
                /*
                                                       * where it came from gives
                                                       * the addr of the device
                                                       */
                if (bc.isTemperatureConfigSet() && configWithTempsConfig == null) {
                    configWithTempsConfig = bc;
                }
            }
            /* if none have values set then send default from first config */
            if (configWithTempsConfig == null) {
                logger.debug("Using default temperature configuration from config 0");
                configWithTempsConfig = (MaxCulBindingConfig) bindingConfigs.toArray()[0];
            }
            /* get device associations */
            HashSet<MaxCulBindingConfig> associations = null;
            for (MaxCulBindingProvider provider : super.providers) {
                associations = provider.getAssociations(configWithTempsConfig.getSerialNumber());
                if (associations != null && associations.isEmpty() == false) {
                    logger.debug("Found associations");
                    break;
                }
            }
            /* start the initialisation sequence */
            logger.debug("Creating pairing sequencer");
            PairingInitialisationSequence ps = new PairingInitialisationSequence(this.DEFAULT_GROUP_ID, messageHandler, configWithTempsConfig, associations);
            messageHandler.startSequence(ps, pkt);
        } else {
            logger.error("Pairing failed: Unable to find binding config for device " + pkt.serial);
        }
    } else {
        switch(msgType) {
            /*
                 * TODO there are other incoming messages that aren't handled that
                 * could be
                 */
            case WALL_THERMOSTAT_CONTROL:
                WallThermostatControlMsg wallThermCtrlMsg = new WallThermostatControlMsg(data);
                wallThermCtrlMsg.printMessage();
                for (MaxCulBindingProvider provider : super.providers) {
                    Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(wallThermCtrlMsg.srcAddrStr);
                    for (MaxCulBindingConfig bc : bindingConfigs) {
                        if (bc.getFeature() == MaxCulFeature.THERMOSTAT && wallThermCtrlMsg.getDesiredTemperature() != null) {
                            String itemName = provider.getItemNameForConfig(bc);
                            eventPublisher.postUpdate(itemName, new DecimalType(wallThermCtrlMsg.getDesiredTemperature()));
                        } else if (bc.getFeature() == MaxCulFeature.TEMPERATURE && wallThermCtrlMsg.getMeasuredTemperature() != null) {
                            String itemName = provider.getItemNameForConfig(bc);
                            eventPublisher.postUpdate(itemName, new DecimalType(wallThermCtrlMsg.getMeasuredTemperature()));
                        }
                    // TODO switch mode between manual/automatic?
                    }
                }
                /* reply only if not broadcast */
                if (isBroadcast == false) {
                    this.messageHandler.sendAck(wallThermCtrlMsg);
                }
                break;
            case SET_TEMPERATURE:
                SetTemperatureMsg setTempMsg = new SetTemperatureMsg(data);
                setTempMsg.printMessage();
                for (MaxCulBindingProvider provider : super.providers) {
                    Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(setTempMsg.srcAddrStr);
                    for (MaxCulBindingConfig bc : bindingConfigs) {
                        if (bc.getFeature() == MaxCulFeature.THERMOSTAT) {
                            String itemName = provider.getItemNameForConfig(bc);
                            eventPublisher.postUpdate(itemName, new DecimalType(setTempMsg.getDesiredTemperature()));
                        }
                    // TODO switch mode between manual/automatic?
                    }
                }
                /* respond to device */
                if (isBroadcast == false) {
                    this.messageHandler.sendAck(setTempMsg);
                }
                break;
            case THERMOSTAT_STATE:
                ThermostatStateMsg thermStateMsg = new ThermostatStateMsg(data);
                thermStateMsg.printMessage();
                for (MaxCulBindingProvider provider : super.providers) {
                    Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(thermStateMsg.srcAddrStr);
                    for (MaxCulBindingConfig bc : bindingConfigs) {
                        String itemName = provider.getItemNameForConfig(bc);
                        if (bc.getFeature() == MaxCulFeature.THERMOSTAT && thermStateMsg.getDesiredTemperature() != null) {
                            eventPublisher.postUpdate(itemName, new DecimalType(thermStateMsg.getDesiredTemperature()));
                        } else if (bc.getFeature() == MaxCulFeature.TEMPERATURE && thermStateMsg.getMeasuredTemperature() != null) {
                            eventPublisher.postUpdate(itemName, new DecimalType(thermStateMsg.getMeasuredTemperature()));
                        } else if (bc.getFeature() == MaxCulFeature.BATTERY) {
                            eventPublisher.postUpdate(itemName, thermStateMsg.getBatteryLow() ? OnOffType.ON : OnOffType.OFF);
                        } else if (bc.getFeature() == MaxCulFeature.MODE) {
                            eventPublisher.postUpdate(itemName, new DecimalType(thermStateMsg.getControlMode().toInt()));
                        } else if (bc.getFeature() == MaxCulFeature.VALVE_POS) {
                            eventPublisher.postUpdate(itemName, new DecimalType(thermStateMsg.getValvePos()));
                        }
                    // TODO switch mode between manual/automatic?
                    }
                }
                /* respond to device */
                if (isBroadcast == false) {
                    this.messageHandler.sendAck(thermStateMsg);
                }
                break;
            case WALL_THERMOSTAT_STATE:
                WallThermostatStateMsg wallThermStateMsg = new WallThermostatStateMsg(data);
                wallThermStateMsg.printMessage();
                for (MaxCulBindingProvider provider : super.providers) {
                    Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(wallThermStateMsg.srcAddrStr);
                    for (MaxCulBindingConfig bc : bindingConfigs) {
                        String itemName = provider.getItemNameForConfig(bc);
                        if (bc.getFeature() == MaxCulFeature.THERMOSTAT && wallThermStateMsg.getDesiredTemperature() != null) {
                            eventPublisher.postUpdate(itemName, new DecimalType(wallThermStateMsg.getDesiredTemperature()));
                        } else if (bc.getFeature() == MaxCulFeature.TEMPERATURE && wallThermStateMsg.getMeasuredTemperature() != null) {
                            eventPublisher.postUpdate(itemName, new DecimalType(wallThermStateMsg.getMeasuredTemperature()));
                        } else if (bc.getFeature() == MaxCulFeature.BATTERY) {
                            eventPublisher.postUpdate(itemName, wallThermStateMsg.getBatteryLow() ? OnOffType.ON : OnOffType.OFF);
                        } else if (bc.getFeature() == MaxCulFeature.MODE) {
                            eventPublisher.postUpdate(itemName, new DecimalType(wallThermStateMsg.getControlMode().toInt()));
                        }
                    }
                }
                /* respond to device */
                if (isBroadcast == false) {
                    this.messageHandler.sendAck(wallThermStateMsg);
                }
                break;
            case TIME_INFO:
                TimeInfoMsg timeMsg = new TimeInfoMsg(data);
                timeMsg.printMessage();
                TimeUpdateRequestSequence timeSeq = new TimeUpdateRequestSequence(this.tzStr, messageHandler);
                messageHandler.startSequence(timeSeq, timeMsg);
                break;
            case PUSH_BUTTON_STATE:
                PushButtonMsg pbMsg = new PushButtonMsg(data);
                pbMsg.printMessage();
                for (MaxCulBindingProvider provider : super.providers) {
                    Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(pbMsg.srcAddrStr);
                    for (MaxCulBindingConfig bc : bindingConfigs) {
                        String itemName = provider.getItemNameForConfig(bc);
                        if (bc.getFeature() == MaxCulFeature.SWITCH) {
                            // 'AUTO' maps to 'ON' and 'ECO' maps to 'OFF'
                            eventPublisher.postUpdate(itemName, pbMsg.getMode() == PushButtonMode.AUTO ? OnOffType.ON : OnOffType.OFF);
                        } else if (bc.getFeature() == MaxCulFeature.BATTERY) {
                            eventPublisher.postUpdate(itemName, pbMsg.getBatteryLow() ? OnOffType.ON : OnOffType.OFF);
                        }
                    }
                }
                if (isBroadcast == false) {
                    this.messageHandler.sendAck(pbMsg);
                }
                break;
            case SHUTTER_CONTACT_STATE:
                ShutterContactStateMsg shutterContactStateMsg = new ShutterContactStateMsg(data);
                shutterContactStateMsg.printMessage();
                for (MaxCulBindingProvider provider : super.providers) {
                    Collection<MaxCulBindingConfig> bindingConfigs = provider.getConfigsForRadioAddr(shutterContactStateMsg.srcAddrStr);
                    for (MaxCulBindingConfig bc : bindingConfigs) {
                        String itemName = provider.getItemNameForConfig(bc);
                        if (bc.getFeature() == MaxCulFeature.CONTACT) {
                            if (shutterContactStateMsg.getState() == ShutterContactState.CLOSED) {
                                eventPublisher.postUpdate(itemName, OpenClosedType.CLOSED);
                            } else if (shutterContactStateMsg.getState() == ShutterContactState.OPEN) {
                                eventPublisher.postUpdate(itemName, OpenClosedType.OPEN);
                            }
                        } else if (bc.getFeature() == MaxCulFeature.BATTERY) {
                            eventPublisher.postUpdate(itemName, shutterContactStateMsg.getBatteryLow() ? OnOffType.ON : OnOffType.OFF);
                        }
                    }
                }
                /* respond to device */
                if (isBroadcast == false) {
                    this.messageHandler.sendAck(shutterContactStateMsg);
                }
                break;
            default:
                logger.debug("Unhandled message type " + msgType.toString());
                break;
        }
    }
    updateCreditMonitors();
}
Also used : PushButtonMsg(org.openhab.binding.maxcul.internal.messages.PushButtonMsg) SetTemperatureMsg(org.openhab.binding.maxcul.internal.messages.SetTemperatureMsg) MaxCulBindingProvider(org.openhab.binding.maxcul.MaxCulBindingProvider) WallThermostatControlMsg(org.openhab.binding.maxcul.internal.messages.WallThermostatControlMsg) WallThermostatStateMsg(org.openhab.binding.maxcul.internal.messages.WallThermostatStateMsg) PairPingMsg(org.openhab.binding.maxcul.internal.messages.PairPingMsg) ThermostatStateMsg(org.openhab.binding.maxcul.internal.messages.ThermostatStateMsg) WallThermostatStateMsg(org.openhab.binding.maxcul.internal.messages.WallThermostatStateMsg) TimeInfoMsg(org.openhab.binding.maxcul.internal.messages.TimeInfoMsg) DecimalType(org.openhab.core.library.types.DecimalType) TimeUpdateRequestSequence(org.openhab.binding.maxcul.internal.message.sequencers.TimeUpdateRequestSequence) PairingInitialisationSequence(org.openhab.binding.maxcul.internal.message.sequencers.PairingInitialisationSequence) ShutterContactStateMsg(org.openhab.binding.maxcul.internal.messages.ShutterContactStateMsg) MaxCulMsgType(org.openhab.binding.maxcul.internal.messages.MaxCulMsgType)

Aggregations

MaxCulBindingProvider (org.openhab.binding.maxcul.MaxCulBindingProvider)4 MaxCulMsgType (org.openhab.binding.maxcul.internal.messages.MaxCulMsgType)2 DecimalType (org.openhab.core.library.types.DecimalType)2 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Timer (java.util.Timer)1 TimerTask (java.util.TimerTask)1 PairingInitialisationSequence (org.openhab.binding.maxcul.internal.message.sequencers.PairingInitialisationSequence)1 TimeUpdateRequestSequence (org.openhab.binding.maxcul.internal.message.sequencers.TimeUpdateRequestSequence)1 AckMsg (org.openhab.binding.maxcul.internal.messages.AckMsg)1 BaseMsg (org.openhab.binding.maxcul.internal.messages.BaseMsg)1 PairPingMsg (org.openhab.binding.maxcul.internal.messages.PairPingMsg)1 PushButtonMsg (org.openhab.binding.maxcul.internal.messages.PushButtonMsg)1 SetTemperatureMsg (org.openhab.binding.maxcul.internal.messages.SetTemperatureMsg)1 ShutterContactStateMsg (org.openhab.binding.maxcul.internal.messages.ShutterContactStateMsg)1 ThermostatStateMsg (org.openhab.binding.maxcul.internal.messages.ThermostatStateMsg)1 TimeInfoMsg (org.openhab.binding.maxcul.internal.messages.TimeInfoMsg)1 WallThermostatControlMsg (org.openhab.binding.maxcul.internal.messages.WallThermostatControlMsg)1 WallThermostatStateMsg (org.openhab.binding.maxcul.internal.messages.WallThermostatStateMsg)1