private int bufferSize = 2048;
private HmGatewayInfo gatewayInfo;
- private int callbackRegistrationRetries;
private int callbackRegTimeout;
/**
private List<Object> parms;
private StringBuilder sb;
private TYPE type;
- public static SimpleDateFormat xmlRpcDateFormat = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
+ public static final SimpleDateFormat XML_RPC_DATEFORMAT = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
public XmlRpcRequest(String methodName) {
this(methodName, TYPE.REQUEST);
} else if (clazz == Boolean.class) {
tag("boolean", ((Boolean) value).booleanValue() ? "1" : "0");
} else if (clazz == Date.class) {
- tag("dateTime.iso8601", xmlRpcDateFormat.format(((Date) value)));
+ synchronized (XML_RPC_DATEFORMAT) {
+ tag("dateTime.iso8601", XML_RPC_DATEFORMAT.format(((Date) value)));
+ }
} else if (value instanceof Calendar calendar) {
generateValue(calendar.getTime());
} else if (value instanceof byte[] bytes) {
break;
case "datetime.iso8601":
try {
- data.add(XmlRpcRequest.xmlRpcDateFormat.parse(currentValue));
+ data.add(XmlRpcRequest.XML_RPC_DATEFORMAT.parse(currentValue));
} catch (ParseException ex) {
throw new SAXException(ex.getMessage(), ex);
}
public class DisplayOptionsParser extends CommonRpcParser<Object, Void> {
private final Logger logger = LoggerFactory.getLogger(DisplayOptionsParser.class);
- private static final String[] onOff = new String[] { "ON", "OFF" };
+ private static final String[] ON_OFF = new String[] { "ON", "OFF" };
private static final int IDX_NOT_FOUND = -1;
private HmChannel channel;
private String text;
String[] dpOpts = dp.getOptions();
String[] options = new String[dpOpts.length - 1];
options = Arrays.copyOfRange(dpOpts, 1, dpOpts.length);
- for (String onOffString : onOff) {
+ for (String onOffString : ON_OFF) {
int onIdx = findInArray(options, onOffString);
if (onIdx != IDX_NOT_FOUND) {
options[onIdx] = datapointName + "_" + onOffString;
public class BatteryTypeVirtualDatapointHandler extends AbstractVirtualDatapointHandler {
private final Logger logger = LoggerFactory.getLogger(BatteryTypeVirtualDatapointHandler.class);
- private static final Properties batteries = new Properties();
+ private static final Properties BATT_PROPERTIES = new Properties();
public BatteryTypeVirtualDatapointHandler() {
Bundle bundle = FrameworkUtil.getBundle(getClass());
try (InputStream stream = bundle.getResource("homematic/batteries.properties").openStream()) {
- batteries.load(stream);
+ BATT_PROPERTIES.load(stream);
} catch (IllegalStateException | IOException e) {
logger.warn("The resource homematic/batteries.properties could not be loaded! Battery types not available",
e);
@Override
public void initialize(HmDevice device) {
- String batteryType = batteries.getProperty(device.getType());
+ String batteryType = BATT_PROPERTIES.getProperty(device.getType());
if (batteryType != null) {
addDatapoint(device, 0, getName(), HmValueType.STRING, batteryType, true);
}
import org.openhab.binding.homematic.internal.model.HmDevice;
import org.openhab.binding.homematic.internal.model.HmValueType;
import org.openhab.core.thing.CommonTriggerEvents;
-import org.openhab.core.thing.DefaultSystemChannelTypeProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A virtual String datapoint which adds a BUTTON datapoint. It will forward key events to the
- * system channel {@link DefaultSystemChannelTypeProvider#SYSTEM_BUTTON}.
+ * system channel {@link org.openhab.core.thing.DefaultSystemChannelTypeProvider#SYSTEM_BUTTON}.
*
* @author Michael Reitler - Initial contribution
*/
/**
* Defines all devices where the state datapoint must be inverted.
*/
- private static final List<StateInvertInfo> stateInvertDevices = new ArrayList<>(3);
+ private static final List<StateInvertInfo> STATE_INVERT_INFO_LIST = new ArrayList<>(3);
static {
- stateInvertDevices.add(new StateInvertInfo(DEVICE_TYPE_SHUTTER_CONTACT));
- stateInvertDevices.add(new StateInvertInfo(DEVICE_TYPE_SHUTTER_CONTACT_2));
- stateInvertDevices.add(new StateInvertInfo(DEVICE_TYPE_INCLINATION_SENSOR));
- stateInvertDevices.add(new StateInvertInfo(DEVICE_TYPE_WIRED_IO_MODULE, 15, 26));
- stateInvertDevices.add(new StateInvertInfo(DEVICE_TYPE_MAX_WINDOW_SENSOR));
- stateInvertDevices.add(new StateInvertInfo(DEVICE_TYPE_SHUTTER_CONTACT_INTERFACE));
+ STATE_INVERT_INFO_LIST.add(new StateInvertInfo(DEVICE_TYPE_SHUTTER_CONTACT));
+ STATE_INVERT_INFO_LIST.add(new StateInvertInfo(DEVICE_TYPE_SHUTTER_CONTACT_2));
+ STATE_INVERT_INFO_LIST.add(new StateInvertInfo(DEVICE_TYPE_INCLINATION_SENSOR));
+ STATE_INVERT_INFO_LIST.add(new StateInvertInfo(DEVICE_TYPE_WIRED_IO_MODULE, 15, 26));
+ STATE_INVERT_INFO_LIST.add(new StateInvertInfo(DEVICE_TYPE_MAX_WINDOW_SENSOR));
+ STATE_INVERT_INFO_LIST.add(new StateInvertInfo(DEVICE_TYPE_SHUTTER_CONTACT_INTERFACE));
}
/**
*/
protected boolean isStateInvertDatapoint(HmDatapoint dp) {
if (DATAPOINT_NAME_STATE.equals(dp.getName())) {
- for (StateInvertInfo stateInvertInfo : stateInvertDevices) {
+ for (StateInvertInfo stateInvertInfo : STATE_INVERT_INFO_LIST) {
if (stateInvertInfo.isToInvert(dp)) {
return true;
}
public class QuantityTypeConverter extends AbstractTypeConverter<QuantityType<? extends Quantity<?>>> {
// this literal is required because some gateway types are mixing up encodings in their XML-RPC responses
- private final String UNCORRECT_ENCODED_CELSIUS = "°C";
+ private static final String UNCORRECT_ENCODED_CELSIUS = "°C";
// "100%" is a commonly used "unit" in datapoints. Generated channel-type is of DecimalType,
// but clients may define a QuantityType if preferred
- private final String HUNDRED_PERCENT = "100%";
+ private static final String HUNDRED_PERCENT = "100%";
@Override
protected boolean toBindingValidation(HmDatapoint dp, Class<? extends Type> typeClass) {
private static final byte UDP_IDENTIFY = 73;
private static final byte UDP_SEPARATOR = 0;
- private static final int senderId = new Random().nextInt() & 0xFFFFFF;
+ private static final int SENDER_ID = new Random().nextInt() & 0xFFFFFF;
private static final String EQ3_DEVICE_TYPE = "eQ3-*";
private static final String EQ3_SERIAL_NUMBER = "*";
* Returns the sender id.
*/
public static int getSenderId() {
- return senderId;
+ return SENDER_ID;
}
/**
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(2);
for (int i = 2; i >= 0; i--) {
- byte temp = (byte) (senderId >> i * 8 & 0xFF);
+ byte temp = (byte) (SENDER_ID >> i * 8 & 0xFF);
baos.write(temp);
}
baos.write(UDP_SEPARATOR);
import java.util.concurrent.Future;
import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.homematic.internal.HomematicBindingConstants;
import org.openhab.binding.homematic.internal.common.HomematicConfig;
import org.openhab.binding.homematic.internal.communicator.HomematicGateway;
import org.openhab.binding.homematic.internal.converter.ConverterException;
* @param datapointName The datapoint that will be updated on the device
* @param currentValue The current value of the datapoint
* @param newValue The value that will be sent to the device
- * @return The rxMode ({@link HomematicBindingConstants#RX_BURST_MODE "BURST"} for burst mode,
- * {@link HomematicBindingConstants#RX_WAKEUP_MODE "WAKEUP"} for wakeup mode, or null for the default mode)
+ * @return The rxMode ({@link org.openhab.binding.homematic.internal.HomematicBindingConstants#RX_BURST_MODE
+ * "BURST"} for burst mode,
+ * {@link org.openhab.binding.homematic.internal.HomematicBindingConstants#RX_WAKEUP_MODE "WAKEUP"} for
+ * wakeup mode, or null for the default mode)
*/
protected String getRxModeForDatapointTransmission(String datapointName, Object currentValue, Object newValue) {
return null;
* @author Gerhard Riegler - Initial contribution
*/
public class SimplePortPool {
- private static int START_PORT = 9125;
+ private static int startPort = 9125;
private List<PortInfo> availablePorts = new ArrayList<>();
}
PortInfo portInfo = new PortInfo();
- while (isPortInUse(START_PORT++)) {
+ while (isPortInUse(startPort++)) {
}
- portInfo.port = START_PORT - 1;
+ portInfo.port = startPort - 1;
portInfo.free = false;
availablePorts.add(portInfo);
* @author Gerhard Riegler - Initial contribution
*/
public class MiscUtils {
- private static final Logger logger = LoggerFactory.getLogger(MiscUtils.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(MiscUtils.class);
/**
* Replaces invalid characters of the text to fit into an openHAB UID.
}
String cleanedText = text.replaceAll("[^A-Za-z0-9_-]", replaceChar);
if (!text.equals(cleanedText)) {
- logger.info("{} '{}' contains invalid characters, new {} '{}'", textType, text, textType, cleanedText);
+ LOGGER.info("{} '{}' contains invalid characters, new {} '{}'", textType, text, textType, cleanedText);
}
return cleanedText;
}
*/
public class MetadataUtils {
- private static final Logger logger = LoggerFactory.getLogger(MetadataUtils.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(MetadataUtils.class);
private static ResourceBundle descriptionsBundle;
private static Map<String, String> descriptions = new HashMap<>();
private static Map<String, Set<String>> standardDatapoints = new HashMap<>();
}
}
} catch (IllegalStateException | IOException e) {
- logger.warn("Can't load standard-datapoints.properties file!", e);
+ LOGGER.warn("Can't load standard-datapoints.properties file!", e);
}
}
public static <T> List<T> generateOptions(HmDatapoint dp, OptionsBuilder<T> optionsBuilder) {
List<T> options = null;
if (dp.getOptions() == null) {
- logger.warn("No options for ENUM datapoint {}", dp);
+ LOGGER.warn("No options for ENUM datapoint {}", dp);
} else {
options = new ArrayList<>();
for (int i = 0; i < dp.getOptions().length; i++) {
}
sb.append(key).append(", ");
}
- if (logger.isTraceEnabled()) {
- logger.trace("Description not found for: {}", sb.toString().substring(0, sb.length() - 2));
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace("Description not found for: {}", sb.toString().substring(0, sb.length() - 2));
}
return null;
}
try {
return new BigDecimal(number.toString());
} catch (Exception ex) {
- logger.warn("Can't create BigDecimal for number: {}", number.toString());
+ LOGGER.warn("Can't create BigDecimal for number: {}", number.toString());
return null;
}
}
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.type.ChannelGroupTypeUID;
import org.openhab.core.thing.type.ChannelTypeUID;
-import org.openhab.core.thing.type.ThingType;
/**
* Allows external definition of
* are henceforth responsible to ...
* <li>provide any excluded ThingType on their own - e.g. in a custom
* {@link org.openhab.core.thing.binding.ThingTypeProvider} or by
- * defining those {@link ThingType}s in XML.</li>
+ * defining those {@link org.openhab.core.thing.type.ThingType}s in XML.</li>
* <li>provide {@link org.openhab.core.thing.type.ChannelType}s
* which are introduced by the provided thing-types</li>
* <li>ensure compatibility and completeness of those thing-types (for any
* {@link HomematicThingTypeExcluder} or not
*
* @param thingType a specific ThingType, specified by its {@link ThingTypeUID}
- * @return <i>true</i>, if the {@link ThingType} is excluded
+ * @return <i>true</i>, if the {@link org.openhab.core.thing.type.ThingType} is excluded
*/
boolean isThingTypeExcluded(ThingTypeUID thingType);
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.jupiter.api.Test;
-import org.openhab.binding.homematic.internal.converter.type.AbstractTypeConverter;
import org.openhab.binding.homematic.internal.model.HmDatapoint;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.ImperialUnits;
+import org.openhab.core.library.unit.SIUnits;
import org.openhab.core.library.unit.Units;
import org.openhab.core.types.State;
-import tech.units.indriya.unit.UnitDimension;
-
/**
- * Tests for {@link AbstractTypeConverter#convertFromBinding(HmDatapoint)}.
+ * Tests for
+ * {@link org.openhab.binding.homematic.internal.converter.type.AbstractTypeConverter#convertFromBinding(HmDatapoint)}.
*
* @author Michael Reitler - Initial Contribution
*
floatQuantityDp.setUnit("°C");
convertedState = temperatureConverter.convertFromBinding(floatQuantityDp);
assertThat(convertedState, instanceOf(QuantityType.class));
- assertThat(((QuantityType<?>) convertedState).getDimension(), is(UnitDimension.TEMPERATURE));
+ assertThat(((QuantityType<?>) convertedState).getDimension(), is(equalTo(SIUnits.CELSIUS.getDimension())));
assertThat(((QuantityType<?>) convertedState).doubleValue(), is(10.5));
assertThat(((QuantityType<?>) convertedState).toUnit(ImperialUnits.FAHRENHEIT).doubleValue(), is(50.9));
floatQuantityDp.setUnit("°C");
- assertThat(((QuantityType<?>) convertedState).getDimension(), is(UnitDimension.TEMPERATURE));
+ assertThat(((QuantityType<?>) convertedState).getDimension(), is(equalTo(SIUnits.CELSIUS.getDimension())));
assertThat(((QuantityType<?>) convertedState).doubleValue(), is(10.5));
integerQuantityDp.setValue(50000);
integerQuantityDp.setUnit("mHz");
convertedState = frequencyConverter.convertFromBinding(integerQuantityDp);
assertThat(convertedState, instanceOf(QuantityType.class));
- assertThat(((QuantityType<?>) convertedState).getDimension(),
- is(UnitDimension.NONE.divide(UnitDimension.TIME)));
+ assertThat(((QuantityType<?>) convertedState).getDimension(), is(equalTo(Units.HERTZ.getDimension())));
assertThat(((QuantityType<?>) convertedState).intValue(), is(50000));
assertThat(((QuantityType<?>) convertedState).toUnit(Units.HERTZ).intValue(), is(50));
floatQuantityDp.setUnit("100%");
convertedState = timeConverter.convertFromBinding(floatQuantityDp);
assertThat(convertedState, instanceOf(QuantityType.class));
- assertThat(((QuantityType<?>) convertedState).getDimension(), is(UnitDimension.NONE));
+ assertThat(((QuantityType<?>) convertedState).getDimension(), is(equalTo(Units.ONE.getDimension())));
assertThat(((QuantityType<?>) convertedState).doubleValue(), is(70.0));
assertThat(((QuantityType<?>) convertedState).getUnit(), is(Units.PERCENT));
assertThat(((QuantityType<?>) convertedState).toUnit(Units.ONE).doubleValue(), is(0.7));
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
-import org.openhab.binding.homematic.internal.converter.type.AbstractTypeConverter;
import org.openhab.binding.homematic.internal.converter.type.DecimalTypeConverter;
import org.openhab.binding.homematic.internal.converter.type.QuantityTypeConverter;
-import org.openhab.binding.homematic.internal.model.HmDatapoint;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.QuantityType;
/**
- * Tests for {@link AbstractTypeConverter#convertToBinding(org.openhab.core.types.Type, HmDatapoint)}.
+ * Tests for
+ * {@link org.openhab.binding.homematic.internal.converter.type.AbstractTypeConverter#convertToBinding(org.openhab.core.types.Type, HmDatapoint)}.
*
* @author Michael Reitler - Initial Contribution
*