/** * verifies response on availability of data * * @param response of heat pump * @param request request defined for heat pump response * @return Map of Strings with name and values */ public Map<String, String> parseRecords(final byte[] response, Request request) throws StiebelHeatPumpException { Map<String, String> map = new HashMap<String, String>(); logger.debug("Parse bytes: {}", DataParser.bytesToHex(response)); if (response.length < 2) { logger.error( "response does not have a valid length of bytes: {}", DataParser.bytesToHex(response)); return map; } // parse response and fill map for (RecordDefinition recordDefinition : request.getRecordDefinitions()) { try { String value = parseRecord(response, recordDefinition); logger.debug( "Parsed value {} -> {} with pos: {} , len: {}", recordDefinition.getName(), value, recordDefinition.getPosition(), recordDefinition.getLength()); map.put(recordDefinition.getName(), value); } catch (StiebelHeatPumpException e) { continue; } } return map; }
/** * parses a single record * * @param response of heat pump * @param RecordDefinition that shall be used for parsing the heat pump response * @return string value of the parse response * @throws StiebelHeatPumpException */ public String parseRecord(byte[] response, RecordDefinition recordDefinition) throws StiebelHeatPumpException { try { if (response.length < 2) { logger.error( "response does not have a valid length of bytes: {}", DataParser.bytesToHex(response)); throw new StiebelHeatPumpException(); } ByteBuffer buffer = ByteBuffer.wrap(response); short number = 0; byte[] bytes = null; switch (recordDefinition.getLength()) { case 1: bytes = new byte[1]; System.arraycopy(response, recordDefinition.getPosition(), bytes, 0, 1); number = Byte.valueOf(buffer.get(recordDefinition.getPosition())); break; case 2: bytes = new byte[2]; System.arraycopy(response, recordDefinition.getPosition(), bytes, 0, 2); number = buffer.getShort(recordDefinition.getPosition()); break; } if (recordDefinition.getBitPosition() > 0) { int returnValue = getBit(bytes, recordDefinition.getBitPosition()); return String.valueOf(returnValue); } if (recordDefinition.getScale() != 1.0) { double myDoubleNumber = number * recordDefinition.getScale(); myDoubleNumber = Math.round(myDoubleNumber * 100.0) / 100.0; String returnString = String.format("%s", myDoubleNumber); return returnString; } return String.valueOf(number); } catch (Exception e) { logger.error( "response {} could not be parsed for record definition {} ", DataParser.bytesToHex(response), recordDefinition.getName()); throw new StiebelHeatPumpException(); } }
/** * composes the new value of a record definition into a updated set command that can be send back * to heat pump * * @param response of heat pump that should be updated with new value * @param RecordDefinition that shall be used for compose the new value into the heat pump set * command * @param string value to be compose * @return byte[] ready to send to heat pump * @throws StiebelHeatPumpException */ public byte[] composeRecord(String value, byte[] response, RecordDefinition recordDefinition) throws StiebelHeatPumpException { short newValue = 0; if (recordDefinition.getDataType() != Type.Settings) { logger.warn( "The record {} can not be set as it is not a setable value!", recordDefinition.getName()); throw new StiebelHeatPumpException("record is not a setting!"); } double number = Double.parseDouble(value); if (number > recordDefinition.getMax() || number < recordDefinition.getMin()) { logger.warn( "The record {} can not be set to value {} as allowed range is {}<-->{} !", recordDefinition.getName(), value, recordDefinition.getMax(), recordDefinition.getMin()); throw new StiebelHeatPumpException("invalid value !"); } // change response byte to setting command response[1] = SET; // reverse the scale if (recordDefinition.getScale() != 1.0) { number = number / recordDefinition.getScale(); newValue = (short) number; } // set new bit values in a byte if (recordDefinition.getBitPosition() > 0) { byte[] abyte = new byte[] {response[recordDefinition.getPosition()]}; abyte = setBit(abyte, recordDefinition.getBitPosition(), newValue); response[recordDefinition.getPosition()] = abyte[0]; return response; } // create byte values for single and double byte values // and update response switch (recordDefinition.getLength()) { case 1: byte newByteValue = (byte) number; response[recordDefinition.getPosition()] = newByteValue; break; case 2: byte[] newByteValues = shortToByte(newValue); int position = recordDefinition.getPosition(); response[position] = newByteValues[1]; response[position + 1] = newByteValues[0]; break; } response[2] = this.calculateChecksum(response); response = this.addDuplicatedBytes(response); logger.debug( "Updated record {} at position {} to value {}.", recordDefinition.getName(), recordDefinition.getPosition(), value); return response; }