/** * Gets a SerialMessage with the THERMOSTAT_SETPOINT_GET command * * @param setpointType the setpoint type to get * @return the serial message */ public SerialMessage getMessage(SetpointType setpointType) { if (setpointType == null) { return null; } logger.debug( "NODE {}: Creating new message for application command THERMOSTAT_SETPOINT_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage( this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Get); byte[] payload = { (byte) this.getNode().getNodeId(), 3, (byte) getCommandClass().getKey(), THERMOSTAT_SETPOINT_GET, (byte) setpointType.getKey() }; result.setMessagePayload(payload); return result; }
/** * Processes a THERMOSTAT_SETPOINT_REPORT message. * * @param serialMessage the incoming message to process. * @param offset the offset position from which to start message processing. * @param endpoint the endpoint or instance number this message is meant for. */ protected void processThermostatSetpointReport( SerialMessage serialMessage, int offset, int endpoint) { int setpointTypeCode = serialMessage.getMessagePayloadByte(offset + 1); int scale = (serialMessage.getMessagePayloadByte(offset + 2) >> 3) & 0x03; try { BigDecimal value = extractValue(serialMessage.getMessagePayload(), offset + 2); logger.debug( "NODE {}: Thermostat Setpoint report Scale = {}", this.getNode().getNodeId(), scale); logger.debug("NODE {}: Thermostat Setpoint Value = {}", this.getNode().getNodeId(), value); SetpointType setpointType = SetpointType.getSetpointType(setpointTypeCode); if (setpointType == null) { logger.error( "NODE {}: Unknown Setpoint Type = {}, ignoring report.", this.getNode().getNodeId(), setpointTypeCode); return; } // setpoint type seems to be supported, add it to the list. if (!this.setpointTypes.contains(setpointType)) this.setpointTypes.add(setpointType); logger.debug( "NODE {}: Setpoint Type = {} ({})", this.getNode().getNodeId(), setpointType.getLabel(), setpointTypeCode); logger.debug( "NODE {}: Thermostat Setpoint Report value = {}", this.getNode().getNodeId(), value.toPlainString()); ZWaveThermostatSetpointValueEvent zEvent = new ZWaveThermostatSetpointValueEvent( this.getNode().getNodeId(), endpoint, setpointType, scale, value); this.getController().notifyEventListeners(zEvent); } catch (NumberFormatException e) { return; } }
/** * Gets a SerialMessage with the THERMOSTAT_SETPOINT_SET command * * @param scale the scale (DegC or DegF) * @param setpointType the setpoint type to set * @param setpoint the setpoint to set. * @return the serial message */ public SerialMessage setMessage(int scale, SetpointType setpointType, BigDecimal setpoint) { logger.debug( "NODE {}: Creating new message for application command THERMOSTAT_SETPOINT_SET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage( this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.SendData, SerialMessagePriority.Set); try { byte[] encodedValue = encodeValue(setpoint); byte[] payload = ArrayUtils.addAll( new byte[] { (byte) this.getNode().getNodeId(), (byte) (3 + encodedValue.length), (byte) getCommandClass().getKey(), THERMOSTAT_SETPOINT_SET, (byte) setpointType.getKey() }, encodedValue); // Add the scale payload[5] += (byte) (scale << 3); result.setMessagePayload(payload); return result; } catch (ArithmeticException e) { logger.error( "NODE {}: Got an arithmetic exception converting value {} to a valid Z-Wave value. Ignoring THERMOSTAT_SETPOINT_SET message.", this.getNode().getNodeId(), setpoint); return null; } }
/** {@inheritDoc} */ @Override public void handleApplicationCommandRequest( SerialMessage serialMessage, int offset, int endpoint) { logger.debug("NODE {}: Received Thermostat Setpoint Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); switch (command) { case THERMOSTAT_SETPOINT_SET: case THERMOSTAT_SETPOINT_GET: case THERMOSTAT_SETPOINT_SUPPORTED_GET: logger.warn("NODE {}: Command {} not implemented.", this.getNode().getNodeId(), command); return; case THERMOSTAT_SETPOINT_SUPPORTED_REPORT: logger.debug( "NODE {}: Process Thermostat Supported Setpoint Report", this.getNode().getNodeId()); int payloadLength = serialMessage.getMessagePayload().length; for (int i = offset + 1; i < payloadLength; ++i) { int bitMask = serialMessage.getMessagePayloadByte(i); for (int bit = 0; bit < 8; ++bit) { if ((bitMask & (1 << bit)) == 0) continue; int index = ((i - (offset + 1)) * 8) + bit; if (index >= SetpointType.values().length) continue; // (n)th bit is set. n is the index for the setpoint type enumeration. SetpointType setpointTypeToAdd = SetpointType.getSetpointType(index); if (setpointTypeToAdd == null) { logger.warn( "NODE {}: Unknown Setpoint Type = {}, ignoring report.", this.getNode().getNodeId(), index); return; } this.setpointTypes.add(setpointTypeToAdd); logger.debug( "NODE {}: Added setpoint type {} {}", this.getNode().getNodeId(), setpointTypeToAdd.getLabel(), index); } } this.getNode().advanceNodeStage(NodeStage.DYNAMIC); break; case THERMOSTAT_SETPOINT_REPORT: logger.trace("NODE {}: Process Thermostat Setpoint Report", this.getNode().getNodeId()); processThermostatSetpointReport(serialMessage, offset, endpoint); if (this.getNode().getNodeStage() != NodeStage.DONE) this.getNode().advanceNodeStage(NodeStage.DONE); break; default: logger.warn( "NODE {}: Unsupported Command {} for command class {} ({}).", this.getNode().getNodeId(), command, this.getCommandClass().getLabel(), this.getCommandClass().getKey()); } }