private static void initMapping() { codeToMeterScaleMapping = new HashMap<MeterType, Map<Integer, MeterScale>>(); nameToMeterScaleMapping = new HashMap<String, MeterScale>(); for (MeterScale s : values()) { if (!codeToMeterScaleMapping.containsKey(s.getMeterType())) codeToMeterScaleMapping.put(s.getMeterType(), new HashMap<Integer, MeterScale>()); codeToMeterScaleMapping.get(s.getMeterType()).put(s.getScale(), s); nameToMeterScaleMapping.put(s.name().toLowerCase(), s); } }
/** * Gets a SerialMessage with the METER_GET command * * @return the serial message */ public SerialMessage getMessage(MeterScale meterScale) { logger.debug( "NODE {}: Creating new message for application command METER_GET", this.getNode().getNodeId()); SerialMessage result = new SerialMessage( this.getNode().getNodeId(), SerialMessageClass.SendData, SerialMessageType.Request, SerialMessageClass.ApplicationCommandHandler, SerialMessagePriority.Get); byte[] newPayload = { (byte) this.getNode().getNodeId(), 3, (byte) getCommandClass().getKey(), (byte) METER_GET, (byte) (meterScale.getScale() << 3) }; result.setMessagePayload(newPayload); return result; }
/** {@inheritDoc} */ @Override public void handleApplicationCommandRequest( SerialMessage serialMessage, int offset, int endpoint) { logger.trace("Handle Message Meter Request"); logger.debug("NODE {}: Received Meter Request", this.getNode().getNodeId()); int command = serialMessage.getMessagePayloadByte(offset); MeterScale scale; int meterTypeIndex; switch (command) { case METER_GET: case METER_SUPPORTED_GET: case METER_RESET: logger.warn("Command {} not implemented.", command); return; case METER_REPORT: logger.trace("Process Meter Report"); logger.debug("NODE {}: Meter report received", this.getNode().getNodeId()); if (serialMessage.getMessagePayload().length < offset + 3) { logger.error( "NODE {}: Buffer too short: length={}, required={}", this.getNode().getNodeId(), serialMessage.getMessagePayload().length, offset + 3); return; } meterTypeIndex = serialMessage.getMessagePayloadByte(offset + 1) & 0x1F; if (meterTypeIndex >= MeterType.values().length) { logger.warn("NODE {}: Invalid meter type {}", this.getNode().getNodeId(), meterTypeIndex); return; } meterType = MeterType.getMeterType(meterTypeIndex); logger.debug( "NODE {}: Meter Type = {} ({})", this.getNode().getNodeId(), meterType.getLabel(), meterTypeIndex); int scaleIndex = (serialMessage.getMessagePayloadByte(offset + 2) & 0x18) >> 0x03; if (this.getVersion() > 2) { // In version 3, an extra scale bit is stored in the meter type byte. scaleIndex |= ((serialMessage.getMessagePayloadByte(offset + 1) & 0x80) >> 0x05); } scale = MeterScale.getMeterScale(meterType, scaleIndex); if (scale == null) { logger.warn("NODE {}: Invalid meter scale {}", this.getNode().getNodeId(), scaleIndex); return; } logger.debug( "NODE {}: Meter Scale = {} ({})", this.getNode().getNodeId(), scale.getUnit(), scale.getScale()); // add scale to the list of supported scales. if (!this.meterScales.contains(scale)) { this.meterScales.add(scale); } try { BigDecimal value = extractValue(serialMessage.getMessagePayload(), offset + 2); logger.debug("NODE {}: Meter Value = {}", this.getNode().getNodeId(), value); ZWaveMeterValueEvent zEvent = new ZWaveMeterValueEvent( this.getNode().getNodeId(), endpoint, meterType, scale, value); this.getController().notifyEventListeners(zEvent); } catch (NumberFormatException e) { return; } if (this.getNode().getNodeStage() != NodeStage.DONE) { this.getNode().advanceNodeStage(NodeStage.DONE); } break; case METER_SUPPORTED_REPORT: logger.trace("Process Meter Supported Report"); canReset = (serialMessage.getMessagePayloadByte(offset + 1) & 0x80) != 0; meterTypeIndex = serialMessage.getMessagePayloadByte(offset + 1) & 0x1F; int supportedScales = serialMessage.getMessagePayloadByte(offset + 2); // only 4 scales are supported in version 2 of the command. if (this.getVersion() == 2) { supportedScales &= 0x0F; } if (meterTypeIndex >= MeterType.values().length) { logger.warn("NODE {}: Invalid meter type {}", this.getNode().getNodeId(), meterTypeIndex); return; } meterType = MeterType.getMeterType(meterTypeIndex); logger.debug( "NODE {}: Identified meter type {} ({})", this.getNode().getNodeId(), meterType.getLabel(), meterTypeIndex); for (int i = 0; i < 8; ++i) { // scale is supported if ((supportedScales & (1 << i)) == (1 << i)) { scale = MeterScale.getMeterScale(meterType, i); if (scale == null) { logger.warn("NODE {}: Invalid meter scale {}", this.getNode().getNodeId(), i); continue; } logger.debug( "NODE {}: Meter Scale = {} ({})", this.getNode().getNodeId(), scale.getUnit(), scale.getScale()); // add scale to the list of supported scales. if (!this.meterScales.contains(scale)) this.meterScales.add(scale); } } this.getNode().advanceNodeStage(NodeStage.DYNAMIC); break; default: logger.warn( String.format( "Unsupported Command 0x%02X for command class %s (0x%02X).", command, this.getCommandClass().getLabel(), this.getCommandClass().getKey())); } }