mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[mqtt.espmilighthub] use availability topic to set thing status (#13800)
also refactor a bit so that the thing will work even if the bridge gets added and removed, etc. Signed-off-by: Cody Cutrer <cody@cutrer.us>
This commit is contained in:
parent
3b08217ff7
commit
2088cf067f
@ -31,6 +31,7 @@ import org.openhab.core.thing.ThingTypeUID;
|
||||
public class EspMilightHubBindingConstants {
|
||||
public static final String STATES_BASE_TOPIC = "milight/states/";
|
||||
public static final String COMMANDS_BASE_TOPIC = "milight/commands/";
|
||||
public static final String STATUS_TOPIC = "milight/status";
|
||||
public static final BigDecimal BIG_DECIMAL_100 = new BigDecimal(100);
|
||||
// List of all Thing Type UIDs
|
||||
public static final ThingTypeUID THING_TYPE_RGB_CCT = new ThingTypeUID(BINDING_ID, "rgb_cct");
|
||||
@ -50,4 +51,7 @@ public class EspMilightHubBindingConstants {
|
||||
public static final String CHANNEL_DISCO_MODE = "discoMode";
|
||||
public static final String CHANNEL_BULB_MODE = "bulbMode";
|
||||
public static final String CHANNEL_COMMAND = "command";
|
||||
|
||||
// Status
|
||||
public static final String CONNECTED = "connected";
|
||||
}
|
||||
|
@ -19,6 +19,9 @@ import static org.openhab.binding.mqtt.espmilighthub.internal.EspMilightHubBindi
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
@ -26,8 +29,6 @@ import org.openhab.binding.mqtt.espmilighthub.internal.ConfigOptions;
|
||||
import org.openhab.binding.mqtt.espmilighthub.internal.Helper;
|
||||
import org.openhab.binding.mqtt.handler.AbstractBrokerHandler;
|
||||
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
|
||||
import org.openhab.core.io.transport.mqtt.MqttConnectionObserver;
|
||||
import org.openhab.core.io.transport.mqtt.MqttConnectionState;
|
||||
import org.openhab.core.io.transport.mqtt.MqttMessageSubscriber;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.HSBType;
|
||||
@ -41,7 +42,7 @@ import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingRegistry;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.thing.ThingStatusInfo;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
@ -57,7 +58,7 @@ import org.slf4j.LoggerFactory;
|
||||
* @author Matthew Skinner - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EspMilightHubHandler extends BaseThingHandler implements MqttConnectionObserver, MqttMessageSubscriber {
|
||||
public class EspMilightHubHandler extends BaseThingHandler implements MqttMessageSubscriber {
|
||||
// these are all constants used in color conversion calcuations.
|
||||
// strings are necessary to prevent floating point loss of precision
|
||||
private static final BigDecimal BIG_DECIMAL_THOUSAND = new BigDecimal(1000);
|
||||
@ -451,12 +452,7 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec
|
||||
return;
|
||||
}
|
||||
}
|
||||
Bridge localBridge = getBridge();
|
||||
if (localBridge == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_PENDING,
|
||||
"Globe must have a valid bridge selected before it can come online.");
|
||||
return;
|
||||
} else {
|
||||
|
||||
globeType = thing.getThingTypeUID().getId();// eg rgb_cct
|
||||
String globeLocation = this.getThing().getUID().getId();// eg 0x014
|
||||
remotesGroupID = globeLocation.substring(globeLocation.length() - 1, globeLocation.length());// eg 4
|
||||
@ -466,14 +462,12 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec
|
||||
// Need to remove the lowercase x from 0x12AB in case it contains all numbers
|
||||
String caseCheck = globeLocation.substring(2, globeLocation.length() - 1);
|
||||
if (!caseCheck.equals(caseCheck.toUpperCase())) {
|
||||
logger.warn(
|
||||
"The milight globe {}{} is using lowercase for the remote code when the hub needs UPPERCASE",
|
||||
logger.warn("The milight globe {}{} is using lowercase for the remote code when the hub needs UPPERCASE",
|
||||
remotesIDCode, remotesGroupID);
|
||||
}
|
||||
channelPrefix = BINDING_ID + ":" + globeType + ":" + localBridge.getUID().getId() + ":" + remotesIDCode
|
||||
channelPrefix = BINDING_ID + ":" + globeType + ":" + thing.getBridgeUID().getId() + ":" + remotesIDCode
|
||||
+ remotesGroupID + ":";
|
||||
connectMQTT();
|
||||
}
|
||||
bridgeStatusChanged(getBridgeStatus());
|
||||
}
|
||||
|
||||
private void sendMQTT(String payload) {
|
||||
@ -487,57 +481,64 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec
|
||||
public void processMessage(String topic, byte[] payload) {
|
||||
String state = new String(payload, StandardCharsets.UTF_8);
|
||||
logger.trace("Received the following new Milight state:{}:{}", topic, state);
|
||||
|
||||
if (topic.equals(STATUS_TOPIC)) {
|
||||
if (state.equals(CONNECTED)) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
} else {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Milight Hub is not connected to your MQTT broker.");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
processIncomingState(state);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Failed processing Milight state {} for {}", state, topic, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ThingStatusInfo getBridgeStatus() {
|
||||
Bridge b = getBridge();
|
||||
if (b != null) {
|
||||
return b.getStatusInfo();
|
||||
} else {
|
||||
return new ThingStatusInfo(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionStateChanged(MqttConnectionState state, @Nullable Throwable error) {
|
||||
logger.debug("MQTT brokers state changed to:{}", state);
|
||||
switch (state) {
|
||||
case CONNECTED:
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
break;
|
||||
case CONNECTING:
|
||||
case DISCONNECTED:
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
|
||||
"Bridge (broker) is not connected to your MQTT broker.");
|
||||
public void bridgeStatusChanged(ThingStatusInfo bridgeStatusInfo) {
|
||||
if (bridgeStatusInfo.getStatus() == ThingStatus.OFFLINE) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
connection = null;
|
||||
return;
|
||||
}
|
||||
if (bridgeStatusInfo.getStatus() != ThingStatus.ONLINE) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
public void connectMQTT() {
|
||||
Bridge localBridge = this.getBridge();
|
||||
if (localBridge == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED,
|
||||
"Bridge is missing or offline, you need to setup a working MQTT broker first.");
|
||||
return;
|
||||
}
|
||||
ThingUID thingUID = localBridge.getUID();
|
||||
Thing thing = thingRegistry.get(thingUID);
|
||||
if (thing == null) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED,
|
||||
"Bridge is missing or offline, you need to setup a working MQTT broker first.");
|
||||
return;
|
||||
}
|
||||
ThingHandler handler = thing.getHandler();
|
||||
ThingHandler handler = localBridge.getHandler();
|
||||
if (handler instanceof AbstractBrokerHandler) {
|
||||
AbstractBrokerHandler abh = (AbstractBrokerHandler) handler;
|
||||
MqttBrokerConnection localConnection = abh.getConnection();
|
||||
if (localConnection != null) {
|
||||
localConnection.setKeepAliveInterval(20);
|
||||
localConnection.setQos(1);
|
||||
localConnection.setUnsubscribeOnStop(true);
|
||||
localConnection.addConnectionObserver(this);
|
||||
localConnection.start();
|
||||
localConnection.subscribe(fullStatesTopic + "/#", this);
|
||||
connection = localConnection;
|
||||
if (localConnection.connectionState().compareTo(MqttConnectionState.CONNECTED) == 0) {
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
final MqttBrokerConnection connection;
|
||||
try {
|
||||
connection = abh.getConnectionAsync().get(500, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException ignored) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_UNINITIALIZED,
|
||||
"Bridge handler has no valid broker connection!");
|
||||
return;
|
||||
}
|
||||
this.connection = connection;
|
||||
connection.subscribe(fullStatesTopic, this);
|
||||
connection.subscribe(STATUS_TOPIC, this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -546,7 +547,8 @@ public class EspMilightHubHandler extends BaseThingHandler implements MqttConnec
|
||||
public void dispose() {
|
||||
MqttBrokerConnection localConnection = connection;
|
||||
if (localConnection != null) {
|
||||
localConnection.unsubscribe(fullStatesTopic + "/#", this);
|
||||
localConnection.unsubscribe(fullStatesTopic, this);
|
||||
localConnection.unsubscribe(STATUS_TOPIC, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user