public static Device create(byte[] raw, List<DeviceConfiguration> configurations) { if (raw.length == 0) { return null; } String rfAddress = Utils.toHex(raw[0] & 0xFF, raw[1] & 0xFF, raw[2] & 0xFF); // Based on the RF address and the corresponding configuration, // create the device based on the type specified in it's configuration Device device = Device.create(rfAddress, configurations); if (device == null) { logger.warn("Can't create device from received message, returning NULL."); return null; } return Device.update(raw, configurations, device); }
public static Device update(byte[] raw, List<DeviceConfiguration> configurations, Device device) { String rfAddress = device.getRFAddress(); // byte 4 is skipped // multiple device information are encoded in those particular bytes boolean[] bits1 = Utils.getBits(Utils.fromByte(raw[4])); boolean[] bits2 = Utils.getBits(Utils.fromByte(raw[5])); device.setInitialized(bits1[1]); device.setAnswer(bits1[2]); device.setError(bits1[3]); device.setValid(bits1[4]); device.setDstSettingActive(bits2[3]); device.setGatewayKnown(bits2[4]); device.setPanelLocked(bits2[5]); device.setLinkStatusError(bits2[6]); device.setBatteryLow(bits2[7]); logger.trace( "Device {} type {} L Message length: {} content: {}", rfAddress, device.getType().toString(), raw.length, Utils.getHex(raw)); // TODO move the device specific readings into the sub classes switch (device.getType()) { case WallMountedThermostat: case HeatingThermostat: case HeatingThermostatPlus: HeatingThermostat heatingThermostat = (HeatingThermostat) device; // "xxxx xx00 = automatic, xxxx xx01 = manual, xxxx xx10 = vacation, xxxx xx11 = boost": if (bits2[1] == false && bits2[0] == false) { heatingThermostat.setMode(ThermostatModeType.AUTOMATIC); } else if (bits2[1] == false && bits2[0] == true) { heatingThermostat.setMode(ThermostatModeType.MANUAL); } else if (bits2[1] == true && bits2[0] == false) { heatingThermostat.setMode(ThermostatModeType.VACATION); } else if (bits2[1] == true && bits2[0] == true) { heatingThermostat.setMode(ThermostatModeType.BOOST); } else { logger.debug("Device {}: Unknown mode", rfAddress); } heatingThermostat.setValvePosition(raw[6] & 0xFF); heatingThermostat.setTemperatureSetpoint(raw[7] & 0x7F); // 9 2 858B Date until (05-09-2011) (see Encoding/Decoding // date/time) // B 1 2E Time until (23:00) (see Encoding/Decoding date/time) String hexDate = Utils.toHex(raw[8] & 0xFF, raw[9] & 0xFF); int dateValue = Utils.fromHex(hexDate); int timeValue = raw[10] & 0xFF; Date date = Utils.resolveDateTime(dateValue, timeValue); heatingThermostat.setDateSetpoint(date); int actualTemp = 0; if (device.getType() == DeviceType.WallMountedThermostat) { actualTemp = (raw[11] & 0xFF) + (raw[7] & 0x80) * 2; } else { if (heatingThermostat.getMode() != ThermostatModeType.VACATION && heatingThermostat.getMode() != ThermostatModeType.BOOST) { actualTemp = (raw[8] & 0xFF) * 256 + (raw[9] & 0xFF); } else { logger.debug( "Device {}: No temperature reading in {} mode", rfAddress, heatingThermostat.getMode()); } } logger.trace("Device {}: Actual Temperature : {}", rfAddress, (double) actualTemp / 10); heatingThermostat.setTemperatureActual((double) actualTemp / 10); break; case EcoSwitch: String eCoSwitchData = Utils.toHex(raw[3] & 0xFF, raw[4] & 0xFF, raw[5] & 0xFF); logger.trace("EcoSwitch Device {} status bytes : {}", rfAddress, eCoSwitchData); EcoSwitch ecoswitch = (EcoSwitch) device; // xxxx xx10 = shutter open, xxxx xx00 = shutter closed if (bits2[1] == true && bits2[0] == false) { ecoswitch.setEcoMode(OnOffType.ON); logger.trace("Device {} status: ON", rfAddress); } else if (bits2[1] == false && bits2[0] == false) { ecoswitch.setEcoMode(OnOffType.OFF); logger.trace("Device {} status: OFF", rfAddress); } else { logger.trace("Device {} status switch status Unknown (true-true)", rfAddress); } break; case ShutterContact: ShutterContact shutterContact = (ShutterContact) device; // xxxx xx10 = shutter open, xxxx xx00 = shutter closed if (bits2[1] == true && bits2[0] == false) { shutterContact.setShutterState(OpenClosedType.OPEN); logger.trace("Device {} status: Open", rfAddress); } else if (bits2[1] == false && bits2[0] == false) { shutterContact.setShutterState(OpenClosedType.CLOSED); logger.trace("Device {} status: Closed", rfAddress); } else { logger.trace("Device {} status switch status Unknown (true-true)", rfAddress); } break; default: logger.debug("Unhandled Device. DataBytes: " + Utils.getHex(raw)); break; } return device; }