2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.lcn.internal.common;
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
21 * Represents an LCN module address.
22 * Can be used as a key in maps.
23 * Hash codes are guaranteed to be unique as long as {@link #isValid()} is true.
25 * @author Tobias Jüttner - Initial Contribution
28 public class LcnAddrMod extends LcnAddr implements Comparable<LcnAddrMod> {
29 private final Logger logger = LoggerFactory.getLogger(LcnAddrMod.class);
30 private final int moduleId;
33 * Constructs a module address with (logical) segment id and module id.
35 * @param segId the segment id
36 * @param modId the module id
38 public LcnAddrMod(int segId, int modId) {
40 this.moduleId = modId;
46 * @return the module id
48 public int getModuleId() {
53 public boolean isValid() {
55 // 0 = Local, 1..2 = Not allowed (but "seen in the wild")
56 // 3 = Broadcast, 4 = Status messages, 5..127, 128 = Segment-bus disabled (valid value)
58 // 1 = LCN-PRO, 2 = LCN-GVS/LCN-W, 4 = PCHK, 5..254, 255 = Unprog. (valid, but irrelevant here)
59 return this.segmentId >= 0 && this.segmentId <= 128 && this.moduleId >= 1 && this.moduleId <= 254;
63 public boolean isGroup() {
73 public int hashCode() {
74 // Reversing the bits helps to generate better balanced trees as ids tend to be "user-sorted"
77 return ReverseNumber.reverseUInt8(this.moduleId) << 8 + ReverseNumber.reverseUInt8(this.segmentId);
79 } catch (LcnException ex) {
80 logger.warn("Could not calculate hash code");
86 public boolean equals(@Nullable Object obj) {
87 if (!(obj instanceof LcnAddrMod)) {
90 return this.segmentId == ((LcnAddrMod) obj).segmentId && this.moduleId == ((LcnAddrMod) obj).moduleId;
94 public int compareTo(LcnAddrMod other) {
95 return this.hashCode() - other.hashCode();
99 public String toString() {
100 return this.isValid() ? String.format("S%03dM%03d", this.segmentId, this.moduleId) : "Invalid";