mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-31 13:34:22 +02:00
[bambulab] Support REFRESH command for all channels (#18457)
* allow refresh Signed-off-by: Martin Grześlowski <martin.grzeslowski@gmail.com>
This commit is contained in:
+15
-8
@@ -30,6 +30,7 @@ import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -38,11 +39,12 @@ import org.slf4j.LoggerFactory;
|
||||
* @author Martin Grześlowski - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class AmsDeviceHandlerFactory extends BaseThingHandler {
|
||||
private Logger logger = LoggerFactory.getLogger(AmsDeviceHandlerFactory.class);
|
||||
public class AmsDeviceHandler extends BaseThingHandler {
|
||||
private Logger logger = LoggerFactory.getLogger(AmsDeviceHandler.class);
|
||||
private @Nullable AmsDeviceConfiguration config;
|
||||
private @Nullable PrinterHandler printer;
|
||||
|
||||
public AmsDeviceHandlerFactory(Thing thing) {
|
||||
public AmsDeviceHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@@ -57,11 +59,11 @@ public class AmsDeviceHandlerFactory extends BaseThingHandler {
|
||||
}
|
||||
|
||||
private void internalInitialize() throws InitializationException {
|
||||
var printer = validateBridge();
|
||||
printer = validateBridge();
|
||||
var config = this.config = getConfigAs(AmsDeviceConfiguration.class);
|
||||
config.validateNumber();
|
||||
logger = LoggerFactory.getLogger("%s.%s.%d".formatted(AmsDeviceHandlerFactory.class.getName(),
|
||||
printer.getSerialNumber(), config.number));
|
||||
logger = LoggerFactory.getLogger(
|
||||
"%s.%s.%d".formatted(AmsDeviceHandler.class.getName(), printer.getSerialNumber(), config.number));
|
||||
updateStatus(ONLINE);
|
||||
}
|
||||
|
||||
@@ -80,7 +82,11 @@ public class AmsDeviceHandlerFactory extends BaseThingHandler {
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
// no commands to handle
|
||||
if (command == RefreshType.REFRESH) {
|
||||
Optional.ofNullable(printer)//
|
||||
.flatMap(p -> p.findLatestAms(getAmsNumber()))//
|
||||
.ifPresent(this::updateAms);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAms(Map<String, Object> ams) {
|
||||
@@ -222,7 +228,8 @@ public class AmsDeviceHandlerFactory extends BaseThingHandler {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
printer = null;
|
||||
config = null;
|
||||
logger = LoggerFactory.getLogger(AmsDeviceHandlerFactory.class);
|
||||
logger = LoggerFactory.getLogger(AmsDeviceHandler.class);
|
||||
}
|
||||
}
|
||||
+10
-3
@@ -41,7 +41,7 @@ public class BambuLabBindingConstants {
|
||||
public static final ThingTypeUID AMS_THING_TYPE = new ThingTypeUID(BINDING_ID, "ams-device");
|
||||
|
||||
@SuppressWarnings("StaticMethodOnlyUsedInOneClass")
|
||||
public enum Channel {
|
||||
public enum PrinterChannel {
|
||||
CHANNEL_COMMAND("command", true),
|
||||
CHANNEL_NOZZLE_TEMPERATURE("nozzle-temperature"),
|
||||
CHANNEL_NOZZLE_TARGET_TEMPERATURE("nozzle-target-temperature"),
|
||||
@@ -51,6 +51,7 @@ public class BambuLabBindingConstants {
|
||||
CHANNEL_MC_PRINT_STAGE("mc-print-stage"),
|
||||
CHANNEL_MC_PERCENT("mc-percent"),
|
||||
CHANNEL_MC_REMAINING_TIME("mc-remaining-time"),
|
||||
CHANNEL_END_DATE("end-date"),
|
||||
CHANNEL_WIFI_SIGNAL("wifi-signal"),
|
||||
CHANNEL_BED_TYPE("bed-type"),
|
||||
CHANNEL_GCODE_FILE("gcode-file", true),
|
||||
@@ -96,12 +97,12 @@ public class BambuLabBindingConstants {
|
||||
private final String name;
|
||||
private final boolean supportCommand;
|
||||
|
||||
Channel(String name, boolean supportCommand) {
|
||||
PrinterChannel(String name, boolean supportCommand) {
|
||||
this.name = name;
|
||||
this.supportCommand = supportCommand;
|
||||
}
|
||||
|
||||
private Channel(String name) {
|
||||
private PrinterChannel(String name) {
|
||||
this(name, false);
|
||||
}
|
||||
|
||||
@@ -121,6 +122,12 @@ public class BambuLabBindingConstants {
|
||||
public boolean is(ChannelUID channelUID) {
|
||||
return name.equals(channelUID.getId());
|
||||
}
|
||||
|
||||
public static Optional<PrinterChannel> findChannel(ChannelUID channel) {
|
||||
return stream(values())//
|
||||
.filter(c -> c.is(channel))//
|
||||
.findAny();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AmsChannel {
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ public class BambuLabHandlerFactory extends BaseThingHandlerFactory {
|
||||
}
|
||||
|
||||
if (AMS_THING_TYPE.equals(thingTypeUID)) {
|
||||
return new AmsDeviceHandlerFactory(thing);
|
||||
return new AmsDeviceHandler(thing);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+1
-1
@@ -14,8 +14,8 @@ package org.openhab.binding.bambulab.internal;
|
||||
|
||||
import static java.lang.Thread.interrupted;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.Channel.*;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.NO_CAMERA_CERT;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.PrinterChannel.*;
|
||||
import static org.openhab.binding.bambulab.internal.PrinterConfiguration.Series.X;
|
||||
import static org.openhab.core.library.types.OnOffType.*;
|
||||
import static org.openhab.core.thing.ThingStatus.*;
|
||||
|
||||
+163
-199
@@ -19,10 +19,8 @@ import static java.util.Objects.requireNonNull;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static java.util.function.Function.identity;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.AmsChannel.*;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.Channel.*;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.PrinterChannel.*;
|
||||
import static org.openhab.binding.bambulab.internal.StateParserHelper.*;
|
||||
import static org.openhab.binding.bambulab.internal.TrayHelper.updateTrayLoaded;
|
||||
import static org.openhab.core.library.unit.SIUnits.CELSIUS;
|
||||
import static org.openhab.core.thing.ThingStatus.OFFLINE;
|
||||
import static org.openhab.core.thing.ThingStatus.ONLINE;
|
||||
import static org.openhab.core.thing.ThingStatus.UNKNOWN;
|
||||
@@ -34,11 +32,10 @@ import static pl.grzeslowski.jbambuapi.mqtt.PrinterClient.Channel.PushingCommand
|
||||
import static pl.grzeslowski.jbambuapi.mqtt.PrinterClientConfig.requiredFields;
|
||||
|
||||
import java.net.URI;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -48,9 +45,8 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.binding.bambulab.internal.BambuLabBindingConstants.PrinterChannel;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
@@ -60,6 +56,7 @@ import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseBridgeHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.RefreshType;
|
||||
import org.openhab.core.types.State;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -90,7 +87,7 @@ public class PrinterHandler extends BaseBridgeHandler
|
||||
private final AtomicReference<@Nullable ScheduledFuture<?>> reconnectSchedule = new AtomicReference<>();
|
||||
private final PrinterWatcher printerWatcher = new PrinterWatcher();
|
||||
private @Nullable PrinterClientConfig config;
|
||||
private final Collection<AmsDeviceHandlerFactory> amses = synchronizedList(new ArrayList<>());
|
||||
private final Collection<AmsDeviceHandler> amses = synchronizedList(new ArrayList<>());
|
||||
private final AtomicReference<@Nullable Report> latestPrinterState = new AtomicReference<>();
|
||||
|
||||
public PrinterHandler(Bridge bridge) {
|
||||
@@ -99,7 +96,12 @@ public class PrinterHandler extends BaseBridgeHandler
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
if (CHANNEL_LED_CHAMBER_LIGHT.is(channelUID) || CHANNEL_LED_WORK_LIGHT.is(channelUID)) {
|
||||
if (command instanceof RefreshType) {
|
||||
Optional.of(latestPrinterState)//
|
||||
.map(AtomicReference::get)//
|
||||
.map(Report::print)//
|
||||
.ifPresent(printer -> updateState(channelUID, printer));
|
||||
} else if (CHANNEL_LED_CHAMBER_LIGHT.is(channelUID) || CHANNEL_LED_WORK_LIGHT.is(channelUID)) {
|
||||
var ledNode = CHANNEL_LED_CHAMBER_LIGHT.is(channelUID) ? CHAMBER_LIGHT : WORK_LIGHT;
|
||||
var bambuCommand = "ON".equals(command.toFullString()) ? on(ledNode) : off(ledNode);
|
||||
sendCommand(bambuCommand);
|
||||
@@ -130,6 +132,16 @@ public class PrinterHandler extends BaseBridgeHandler
|
||||
}
|
||||
}
|
||||
|
||||
private void updateState(ChannelUID channelUid, Report.Print print) {
|
||||
var someChannel = findChannel(channelUid);
|
||||
if (someChannel.isEmpty()) {
|
||||
logger.warn("Cannot find channel for {}", channelUid);
|
||||
return;
|
||||
}
|
||||
var channel = someChannel.get();
|
||||
updateState(channel, print);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
try {
|
||||
@@ -305,132 +317,143 @@ public class PrinterHandler extends BaseBridgeHandler
|
||||
if (delta == null) {
|
||||
return;
|
||||
}
|
||||
updatePrinterChannels(delta);
|
||||
var print = delta.print();
|
||||
if (print == null) {
|
||||
return;
|
||||
}
|
||||
stream(PrinterChannel.values()).forEach(channel -> updateState(channel, print));
|
||||
|
||||
// if got new Printer state (and not failed) then make sure that thing status in ONLINE
|
||||
updateStatus(ONLINE);
|
||||
}
|
||||
|
||||
private void updatePrinterChannels(Report state) {
|
||||
// Print
|
||||
var print = state.print();
|
||||
if (print == null) {
|
||||
return;
|
||||
}
|
||||
// tempers
|
||||
updateCelsiusState(CHANNEL_NOZZLE_TEMPERATURE, print.nozzleTemper());
|
||||
updateCelsiusState(CHANNEL_NOZZLE_TARGET_TEMPERATURE, print.nozzleTargetTemper());
|
||||
updateCelsiusState(CHANNEL_BED_TEMPERATURE, print.bedTemper());
|
||||
updateCelsiusState(CHANNEL_BED_TARGET_TEMPERATURE, print.bedTargetTemper());
|
||||
updateCelsiusState(CHANNEL_CHAMBER_TEMPERATURE, print.chamberTemper());
|
||||
// string
|
||||
updateStringState(CHANNEL_MC_PRINT_STAGE, print.mcPrintStage());
|
||||
updateStringState(CHANNEL_BED_TYPE, print.bedType());
|
||||
updateStringState(CHANNEL_GCODE_FILE, print.gcodeFile());
|
||||
updateStringState(CHANNEL_GCODE_STATE, print.gcodeState());
|
||||
updateStringState(CHANNEL_REASON, print.reason());
|
||||
updateStringState(CHANNEL_RESULT, print.result());
|
||||
// percent
|
||||
updatePercentState(CHANNEL_MC_PERCENT, print.mcPercent());
|
||||
updatePercentState(CHANNEL_GCODE_FILE_PREPARE_PERCENT, print.gcodeFilePreparePercent());
|
||||
// decimal
|
||||
parseTimeMinutes(print.mcRemainingTime())//
|
||||
.ifPresent(time -> updateState(CHANNEL_MC_REMAINING_TIME, time));
|
||||
updateDecimalState(CHANNEL_BIG_FAN_1_SPEED, print.bigFan1Speed());
|
||||
updateDecimalState(CHANNEL_BIG_FAN_2_SPEED, print.bigFan2Speed());
|
||||
updateDecimalState(CHANNEL_HEAT_BREAK_FAN_SPEED, print.heatbreakFanSpeed());
|
||||
updateDecimalState(CHANNEL_LAYER_NUM, print.layerNum());
|
||||
if (print.spdLvl() != null) {
|
||||
var speedLevel = PrintSpeedCommand.findByLevel(print.spdLvl());
|
||||
updateState(CHANNEL_SPEED_LEVEL, new StringType(speedLevel.toString()));
|
||||
}
|
||||
// boolean
|
||||
updateBooleanState(CHANNEL_TIME_LAPS, print.timelapse());
|
||||
updateBooleanState(CHANNEL_USE_AMS, print.useAms());
|
||||
updateBooleanState(CHANNEL_VIBRATION_CALIBRATION, print.vibrationCali());
|
||||
// lights
|
||||
updateLightState("chamber_light", CHANNEL_LED_CHAMBER_LIGHT, print.lightsReport());
|
||||
updateLightState("work_light", CHANNEL_LED_WORK_LIGHT, print.lightsReport());
|
||||
// other
|
||||
if (print.wifiSignal() != null) {
|
||||
updateState(CHANNEL_WIFI_SIGNAL, parseWifiChannel(print.wifiSignal()));
|
||||
}
|
||||
// ams
|
||||
Optional.of(print)//
|
||||
.map(Report.Print::ams)//
|
||||
.ifPresent(ams -> {
|
||||
updateState(CHANNEL_AMS_TRAY_NOW, updateTrayLoaded(ams.trayNow()));
|
||||
updateState(CHANNEL_AMS_TRAY_PREVIOUS, updateTrayLoaded(ams.trayPre()));
|
||||
});
|
||||
Optional.of(print)//
|
||||
.map(Report.Print::ams)//
|
||||
.map(Report.Print.Ams::ams)//
|
||||
.stream()//
|
||||
.flatMap(Collection::stream)//
|
||||
.forEach(this::updateAms);
|
||||
// vtray
|
||||
Optional.of(print)//
|
||||
.map(Report.Print::vtTray)//
|
||||
.ifPresent(this::updateVtray);
|
||||
}
|
||||
|
||||
private void updateVtray(Report.Print.VtTray vtTray) {
|
||||
Optional.ofNullable(vtTray.trayType())//
|
||||
.map(Object::toString)//
|
||||
.flatMap(TrayType::findTrayType)//
|
||||
.map(Enum::name)//
|
||||
.flatMap(StateParserHelper::parseStringType)//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_TYPE, trayType));
|
||||
Optional.ofNullable(vtTray.trayColor())//
|
||||
.map(Object::toString)//
|
||||
.map(StateParserHelper::parseColor)//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_COLOR, trayType));
|
||||
parseTemperatureType(vtTray.nozzleTempMax())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_NOZZLE_TEMPERATURE_MAX, trayType));
|
||||
parseTemperatureType(vtTray.nozzleTempMin())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_NOZZLE_TEMPERATURE_MIN, trayType));
|
||||
Optional.ofNullable(vtTray.remain())//
|
||||
.flatMap(StateParserHelper::parsePercentType)//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_REMAIN, trayType));
|
||||
parseDecimalType(vtTray.k())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_K, trayType));
|
||||
parseDecimalType(vtTray.n())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_N, trayType));
|
||||
parseStringType(vtTray.tagUid())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TAG_UUID, trayType));
|
||||
parseStringType(vtTray.trayIdName())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_ID_NAME, trayType));
|
||||
parseStringType(vtTray.trayInfoIdx())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_INFO_IDX, trayType));
|
||||
parseStringType(vtTray.traySubBrands())
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_SUB_BRANDS, trayType));
|
||||
parseDecimalType(vtTray.trayWeight())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_WEIGHT, trayType));
|
||||
parseDecimalType(vtTray.trayDiameter())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_DIAMETER, trayType));
|
||||
parseTemperatureType(vtTray.trayTemp())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_TEMPERATURE, trayType));
|
||||
parseDecimalType(vtTray.trayTime())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_TRAY_TIME, trayType));
|
||||
parseStringType(vtTray.bedTempType())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_BED_TEMPERATURE_TYPE, trayType));
|
||||
parseTemperatureType(vtTray.bedTemp())//
|
||||
.or(StateParserHelper::undef)//
|
||||
.ifPresent(trayType -> updateState(CHANNEL_VTRAY_BED_TEMPERATURE, trayType));
|
||||
private void updateState(PrinterChannel channel, Report.Print print) {
|
||||
var vtray = Optional.of(print).map(Report.Print::vtTray);
|
||||
Optional<State> state = switch (channel) {
|
||||
// temper
|
||||
case CHANNEL_NOZZLE_TEMPERATURE -> parseTemperatureType(print.nozzleTemper());
|
||||
case CHANNEL_NOZZLE_TARGET_TEMPERATURE -> parseTemperatureType(print.nozzleTargetTemper());
|
||||
case CHANNEL_BED_TEMPERATURE -> parseTemperatureType(print.bedTemper());
|
||||
case CHANNEL_BED_TARGET_TEMPERATURE -> parseTemperatureType(print.bedTargetTemper());
|
||||
case CHANNEL_CHAMBER_TEMPERATURE -> parseTemperatureType(print.chamberTemper());
|
||||
// string
|
||||
case CHANNEL_MC_PRINT_STAGE -> parseStringType(print.mcPrintStage());
|
||||
case CHANNEL_BED_TYPE -> parseStringType(print.bedType());
|
||||
case CHANNEL_GCODE_FILE -> parseStringType(print.gcodeFile());
|
||||
case CHANNEL_GCODE_STATE -> parseStringType(print.gcodeState());
|
||||
case CHANNEL_REASON -> parseStringType(print.reason());
|
||||
case CHANNEL_RESULT -> parseStringType(print.result());
|
||||
// percents
|
||||
case CHANNEL_MC_PERCENT -> parsePercentType(print.mcPercent());
|
||||
case CHANNEL_GCODE_FILE_PREPARE_PERCENT -> parsePercentType(print.gcodeFilePreparePercent());
|
||||
// time
|
||||
case CHANNEL_MC_REMAINING_TIME -> parseTimeMinutes(print.mcRemainingTime());
|
||||
// wifi
|
||||
case CHANNEL_WIFI_SIGNAL -> parseWifiChannel(print.wifiSignal());
|
||||
// decimal
|
||||
case CHANNEL_BIG_FAN_1_SPEED -> parseDecimalType(print.bigFan1Speed());
|
||||
case CHANNEL_BIG_FAN_2_SPEED -> parseDecimalType(print.bigFan2Speed());
|
||||
case CHANNEL_HEAT_BREAK_FAN_SPEED -> parseDecimalType(print.heatbreakFanSpeed());
|
||||
case CHANNEL_LAYER_NUM -> parseDecimalType(print.layerNum());
|
||||
// boolean
|
||||
case CHANNEL_TIME_LAPS -> parseOnOffType(print.timelapse());
|
||||
case CHANNEL_USE_AMS -> parseOnOffType(print.useAms());
|
||||
case CHANNEL_VIBRATION_CALIBRATION -> parseOnOffType(print.vibrationCali());
|
||||
// lights
|
||||
case CHANNEL_LED_CHAMBER_LIGHT -> parseChamberLightType(print.lightsReport());
|
||||
case CHANNEL_LED_WORK_LIGHT -> parseWorkLightType(print.lightsReport());
|
||||
// vtray
|
||||
case CHANNEL_VTRAY_TRAY_TYPE -> //
|
||||
vtray.map(Report.Print.VtTray::trayType)//
|
||||
.flatMap(StateParserHelper::parseTrayType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TRAY_COLOR -> //
|
||||
vtray.map(Report.Print.VtTray::trayColor)//
|
||||
.map(StateParserHelper::parseColor)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_NOZZLE_TEMPERATURE_MAX -> //
|
||||
vtray.map(Report.Print.VtTray::nozzleTempMax)//
|
||||
.flatMap(StateParserHelper::parseTemperatureType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_NOZZLE_TEMPERATURE_MIN -> //
|
||||
vtray.map(Report.Print.VtTray::nozzleTempMin)//
|
||||
.flatMap(StateParserHelper::parseTemperatureType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_REMAIN -> //
|
||||
vtray.map(Report.Print.VtTray::remain)//
|
||||
.flatMap(StateParserHelper::parsePercentType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_K -> //
|
||||
vtray.map(Report.Print.VtTray::k)//
|
||||
.flatMap(StateParserHelper::parseDecimalType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_N -> //
|
||||
vtray.map(Report.Print.VtTray::n)//
|
||||
.flatMap(StateParserHelper::parseDecimalType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TAG_UUID -> //
|
||||
vtray.map(Report.Print.VtTray::trayUuid)//
|
||||
.flatMap(StateParserHelper::parseStringType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TRAY_ID_NAME -> //
|
||||
vtray.map(Report.Print.VtTray::trayIdName)//
|
||||
.flatMap(StateParserHelper::parseStringType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TRAY_INFO_IDX -> //
|
||||
vtray.map(Report.Print.VtTray::trayInfoIdx)//
|
||||
.flatMap(StateParserHelper::parseStringType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TRAY_SUB_BRANDS -> //
|
||||
vtray.map(Report.Print.VtTray::traySubBrands)//
|
||||
.flatMap(StateParserHelper::parseStringType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TRAY_WEIGHT -> //
|
||||
vtray.map(Report.Print.VtTray::trayWeight)//
|
||||
.flatMap(StateParserHelper::parseDecimalType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TRAY_DIAMETER -> //
|
||||
vtray.map(Report.Print.VtTray::trayDiameter)//
|
||||
.flatMap(StateParserHelper::parseDecimalType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TRAY_TEMPERATURE -> //
|
||||
vtray.map(Report.Print.VtTray::trayTemp)//
|
||||
.flatMap(StateParserHelper::parseTemperatureType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_TRAY_TIME -> //
|
||||
vtray.map(Report.Print.VtTray::trayTime)//
|
||||
.flatMap(StateParserHelper::parseDecimalType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_BED_TEMPERATURE_TYPE -> //
|
||||
vtray.map(Report.Print.VtTray::bedTempType)//
|
||||
.flatMap(StateParserHelper::parseStringType)//
|
||||
.or(StateParserHelper::undef);
|
||||
case CHANNEL_VTRAY_BED_TEMPERATURE -> //
|
||||
vtray.map(Report.Print.VtTray::bedTemp)//
|
||||
.flatMap(StateParserHelper::parseTemperatureType)//
|
||||
.or(StateParserHelper::undef);
|
||||
// ams
|
||||
case CHANNEL_AMS_TRAY_NOW -> //
|
||||
Optional.of(print)//
|
||||
.map(Report.Print::ams)//
|
||||
.map(Report.Print.Ams::trayNow)//
|
||||
.flatMap(TrayHelper::findStateForTrayLoaded);
|
||||
case CHANNEL_AMS_TRAY_PREVIOUS -> //
|
||||
Optional.of(print)//
|
||||
.map(Report.Print::ams)//
|
||||
.map(Report.Print.Ams::trayPre)//
|
||||
.flatMap(TrayHelper::findStateForTrayLoaded);
|
||||
// misc
|
||||
case CHANNEL_SPEED_LEVEL -> parseSpeedLevel(print.spdLvl());
|
||||
case CHANNEL_END_DATE -> //
|
||||
Optional.ofNullable(print.mcRemainingTime())//
|
||||
.map(time -> ZonedDateTime.now().plusMinutes(time))//
|
||||
.map(StateParserHelper::parseDateTimeType);
|
||||
// surrogate channels
|
||||
case CHANNEL_COMMAND -> Optional.empty();
|
||||
case CHANNEL_CAMERA_IMAGE -> Optional.empty();
|
||||
case CHANNEL_CAMERA_RECORD -> Optional.empty();
|
||||
};
|
||||
state.ifPresent(s -> updateState(channel, s));
|
||||
}
|
||||
|
||||
private void updateAms(Map<String, Object> amsMap) {
|
||||
@@ -448,68 +471,6 @@ public class PrinterHandler extends BaseBridgeHandler
|
||||
.forEach(ams -> ams.updateAms(amsMap));
|
||||
}
|
||||
|
||||
private void updateCelsiusState(BambuLabBindingConstants.Channel channelId, @Nullable Double temperature) {
|
||||
if (temperature == null) {
|
||||
return;
|
||||
}
|
||||
updateState(channelId, new QuantityType<>(temperature, CELSIUS));
|
||||
}
|
||||
|
||||
private void updateStringState(BambuLabBindingConstants.Channel channelId, @Nullable String string) {
|
||||
if (string == null) {
|
||||
return;
|
||||
}
|
||||
updateState(channelId, new StringType(string));
|
||||
}
|
||||
|
||||
private void updateDecimalState(BambuLabBindingConstants.Channel channelId, @Nullable Number number) {
|
||||
if (number == null) {
|
||||
return;
|
||||
}
|
||||
updateState(channelId, new DecimalType(number));
|
||||
}
|
||||
|
||||
private void updateDecimalState(BambuLabBindingConstants.Channel channelId, @Nullable String number) {
|
||||
if (number == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var state = new DecimalType(Double.parseDouble(number));
|
||||
updateState(channelId, state);
|
||||
} catch (NumberFormatException e) {
|
||||
logger.debug("Cannot parse decimal number {}", number, e);
|
||||
updateState(channelId, UNDEF);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBooleanState(BambuLabBindingConstants.Channel channelId, @Nullable Boolean bool) {
|
||||
if (bool == null) {
|
||||
return;
|
||||
}
|
||||
updateState(channelId, OnOffType.from(bool));
|
||||
}
|
||||
|
||||
private void updatePercentState(BambuLabBindingConstants.Channel channelId, @Nullable Integer integer) {
|
||||
parsePercentType(integer).ifPresent(state -> updateState(channelId, state));
|
||||
}
|
||||
|
||||
private void updatePercentState(BambuLabBindingConstants.Channel channelId, @Nullable String integer) {
|
||||
parsePercentType(integer).ifPresent(state -> updateState(channelId, state));
|
||||
}
|
||||
|
||||
private void updateLightState(String lightName, BambuLabBindingConstants.Channel channel,
|
||||
@Nullable List<Map<String, String>> lights) {
|
||||
Optional.ofNullable(lights)//
|
||||
.stream()//
|
||||
.flatMap(Collection::stream)//
|
||||
.filter(map -> lightName.equalsIgnoreCase(map.get("node")))//
|
||||
.map(map -> map.get("mode"))//
|
||||
.filter(Objects::nonNull)//
|
||||
.map(OnOffType::from)//
|
||||
.findAny()//
|
||||
.ifPresent(command -> updateState(channel, command));
|
||||
}
|
||||
|
||||
public void sendCommand(String command) {
|
||||
sendCommand(CommandParser.parseCommand(command));
|
||||
}
|
||||
@@ -528,7 +489,7 @@ public class PrinterHandler extends BaseBridgeHandler
|
||||
}
|
||||
}
|
||||
|
||||
private void updateState(BambuLabBindingConstants.Channel channelID, State state) {
|
||||
private void updateState(PrinterChannel channelID, State state) {
|
||||
updateState(channelID.getName(), state);
|
||||
}
|
||||
|
||||
@@ -559,11 +520,15 @@ public class PrinterHandler extends BaseBridgeHandler
|
||||
|
||||
@Override
|
||||
public void childHandlerInitialized(ThingHandler childHandler, Thing childThing) {
|
||||
if (!(childHandler instanceof AmsDeviceHandlerFactory ams)) {
|
||||
if (!(childHandler instanceof AmsDeviceHandler ams)) {
|
||||
return;
|
||||
}
|
||||
amses.add(ams);
|
||||
Optional.of(latestPrinterState)//
|
||||
findLatestAms(ams.getAmsNumber()).ifPresent(ams::updateAms);
|
||||
}
|
||||
|
||||
public Optional<Map<String, Object>> findLatestAms(int amsNumber) {
|
||||
return Optional.of(latestPrinterState)//
|
||||
.map(AtomicReference::get)//
|
||||
.map(Report::print).map(Report.Print::ams)//
|
||||
.map(Report.Print.Ams::ams)//
|
||||
@@ -572,13 +537,12 @@ public class PrinterHandler extends BaseBridgeHandler
|
||||
.filter(map -> map.containsKey("id"))//
|
||||
.filter(map -> map.get("id") != null)//
|
||||
// in code, we are using 1-4 ordering; in API 0-3 ordering is used
|
||||
.filter(map -> parseInt(map.get("id").toString()) + 1 == ams.getAmsNumber())//
|
||||
.forEach(ams::updateAms);
|
||||
.filter(map -> parseInt(map.get("id").toString()) + 1 == amsNumber).findAny();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void childHandlerDisposed(ThingHandler childHandler, Thing childThing) {
|
||||
if (!(childHandler instanceof AmsDeviceHandlerFactory ams)) {
|
||||
if (!(childHandler instanceof AmsDeviceHandler ams)) {
|
||||
return;
|
||||
}
|
||||
var removed = amses.remove(ams);
|
||||
|
||||
+65
-5
@@ -18,12 +18,19 @@ import static org.openhab.core.library.unit.Units.*;
|
||||
import static org.openhab.core.types.UnDefType.UNDEF;
|
||||
import static tech.units.indriya.unit.Units.PERCENT;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.types.State;
|
||||
@@ -31,6 +38,8 @@ import org.openhab.core.util.ColorUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import pl.grzeslowski.jbambuapi.mqtt.PrinterClient.Channel.PrintSpeedCommand;
|
||||
|
||||
/**
|
||||
* @author Martin Grześlowski - Initial contribution
|
||||
*/
|
||||
@@ -44,9 +53,15 @@ public class StateParserHelper {
|
||||
.map(time -> new QuantityType<>(time, MINUTE));
|
||||
}
|
||||
|
||||
public static Optional<State> parseTemperatureType(@Nullable Number value) {
|
||||
return Optional.ofNullable(value).map(d -> new QuantityType<>(d, CELSIUS));
|
||||
}
|
||||
|
||||
public static Optional<State> parseTemperatureType(@Nullable String value) {
|
||||
try {
|
||||
return Optional.ofNullable(value).map(Double::parseDouble).map(d -> new QuantityType<>(d, CELSIUS));
|
||||
return Optional.ofNullable(value)//
|
||||
.map(Double::parseDouble)//
|
||||
.flatMap(StateParserHelper::parseTemperatureType);
|
||||
} catch (NumberFormatException ex) {
|
||||
logger.debug("Cannot parse: {}", value, ex);
|
||||
return Optional.of(UNDEF);
|
||||
@@ -85,20 +100,23 @@ public class StateParserHelper {
|
||||
return Optional.ofNullable(string).map(StringType::new);
|
||||
}
|
||||
|
||||
public static State parseWifiChannel(String wifi) {
|
||||
public static Optional<State> parseWifiChannel(@Nullable String wifi) {
|
||||
if (wifi == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
var matcher = DBM_PATTERN.matcher(wifi);
|
||||
if (!matcher.matches()) {
|
||||
logger.debug("Cannot match {} to {}", wifi, DBM_PATTERN);
|
||||
return UNDEF;
|
||||
return Optional.of(UNDEF);
|
||||
}
|
||||
|
||||
var integer = matcher.group(1);
|
||||
try {
|
||||
var value = parseInt(integer);
|
||||
return new QuantityType<>(value, DECIBEL_MILLIWATTS);
|
||||
return Optional.of(new QuantityType<>(value, DECIBEL_MILLIWATTS));
|
||||
} catch (NumberFormatException e) {
|
||||
logger.debug("Cannot parse integer {} from wifi {}", integer, wifi, e);
|
||||
return UNDEF;
|
||||
return Optional.of(UNDEF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,4 +133,46 @@ public class StateParserHelper {
|
||||
public static Optional<State> undef() {
|
||||
return Optional.of(UNDEF);
|
||||
}
|
||||
|
||||
public static Optional<State> parseOnOffType(@Nullable Boolean bool) {
|
||||
return Optional.ofNullable(bool).map(OnOffType::from);
|
||||
}
|
||||
|
||||
public static Optional<State> parseSpeedLevel(@Nullable Integer speedLvl) {
|
||||
return Optional.ofNullable(speedLvl)//
|
||||
.map(PrintSpeedCommand::findByLevel)//
|
||||
.map(Object::toString)//
|
||||
.flatMap(StateParserHelper::parseStringType);
|
||||
}
|
||||
|
||||
public static Optional<State> parseTrayType(@Nullable String trayType) {
|
||||
return Optional.ofNullable(trayType).map(Object::toString)//
|
||||
.flatMap(BambuLabBindingConstants.AmsChannel.TrayType::findTrayType)//
|
||||
.map(Enum::name)//
|
||||
.flatMap(StateParserHelper::parseStringType);
|
||||
}
|
||||
|
||||
public static Optional<State> parseChamberLightType(@Nullable List<Map<String, String>> lights) {
|
||||
return parseLightType("chamber_light", lights);
|
||||
}
|
||||
|
||||
public static Optional<State> parseWorkLightType(@Nullable List<Map<String, String>> lights) {
|
||||
return parseLightType("work_light", lights);
|
||||
}
|
||||
|
||||
private static Optional<State> parseLightType(String lightName, @Nullable List<Map<String, String>> lights) {
|
||||
return Optional.ofNullable(lights)//
|
||||
.stream()//
|
||||
.flatMap(Collection::stream)//
|
||||
.filter(map -> lightName.equalsIgnoreCase(map.get("node")))//
|
||||
.map(map -> map.get("mode"))//
|
||||
.filter(Objects::nonNull)//
|
||||
.map(OnOffType::from)//
|
||||
.map(state -> (State) state)//
|
||||
.findAny();
|
||||
}
|
||||
|
||||
public static State parseDateTimeType(ZonedDateTime dateTime) {
|
||||
return new DateTimeType(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-5
@@ -16,6 +16,8 @@ import static java.lang.Integer.parseInt;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.AmsChannel.*;
|
||||
import static org.openhab.core.types.UnDefType.UNDEF;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
@@ -31,20 +33,20 @@ class TrayHelper {
|
||||
static final int MAX_TRAY_VALUE = MAX_AMS * MAX_AMS_TRAYS - 1;
|
||||
private static final Logger logger = LoggerFactory.getLogger(TrayHelper.class);
|
||||
|
||||
static State updateTrayLoaded(@Nullable String tray) {
|
||||
static Optional<State> findStateForTrayLoaded(@Nullable String tray) {
|
||||
if (tray == null) {
|
||||
return UNDEF;
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
var integer = parseInt(tray);
|
||||
return findStateForTrayLoaded(integer);
|
||||
return Optional.of(parseTrayLoaded(integer));
|
||||
} catch (NumberFormatException e) {
|
||||
logger.debug("Cannot parse: {}", tray, e);
|
||||
return UNDEF;
|
||||
return Optional.of(UNDEF);
|
||||
}
|
||||
}
|
||||
|
||||
private static State findStateForTrayLoaded(int tray) {
|
||||
private static State parseTrayLoaded(int tray) {
|
||||
if (tray < 0) {
|
||||
return UNDEF;
|
||||
}
|
||||
|
||||
+3
@@ -30,6 +30,8 @@ thing-type.bambulab.printer.channel.chamber-temperature.label = Chamber Temperat
|
||||
thing-type.bambulab.printer.channel.chamber-temperature.description = Current temperature inside the printer chamber.
|
||||
thing-type.bambulab.printer.channel.command.label = Command
|
||||
thing-type.bambulab.printer.channel.command.description = Send command to run. See <a href="https://github.com/openhab/openhab-addons/tree/main/bundles/org.openhab.binding.bambulab#sendcommand">Actions > sendCommand</a>
|
||||
thing-type.bambulab.printer.channel.end-date.label = End Time of the Print
|
||||
thing-type.bambulab.printer.channel.end-date.description = Estimated end date of the print.
|
||||
thing-type.bambulab.printer.channel.gcode-file.label = G-code File
|
||||
thing-type.bambulab.printer.channel.gcode-file.description = Name of the currently loaded G-code file.
|
||||
thing-type.bambulab.printer.channel.gcode-file-prepare-percent.label = G-code Preparation Progress
|
||||
@@ -170,6 +172,7 @@ channel-type.bambulab.temperature-measurement.label = Current Temperature
|
||||
channel-type.bambulab.temperature-setpoint.label = Target Temperature
|
||||
channel-type.bambulab.time-min.label = Time (min)
|
||||
channel-type.bambulab.time-min.state.pattern = %1$tHh:%1$tMm
|
||||
channel-type.bambulab.timestamp.label = Time Stamp
|
||||
channel-type.bambulab.tray-color.label = Tray Color
|
||||
channel-type.bambulab.tray-loaded.label = Currently Loaded Tray
|
||||
channel-type.bambulab.tray-loaded.state.option.EMPTY = No tray loaded
|
||||
|
||||
@@ -63,6 +63,12 @@
|
||||
<label>Time (min)</label>
|
||||
<state readOnly="true" pattern="%1$tHh:%1$tMm"/>
|
||||
</channel-type>
|
||||
<channel-type id="timestamp">
|
||||
<item-type>DateTime</item-type>
|
||||
<label>Time Stamp</label>
|
||||
<category>time</category>
|
||||
<state readOnly="true"/>
|
||||
</channel-type>
|
||||
<channel-type id="number-advanced" advanced="true">
|
||||
<item-type>Number</item-type>
|
||||
<label>Advanced Number Channel</label>
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
<label>Remaining Print Time</label>
|
||||
<description>Estimated time remaining for the print in seconds.</description>
|
||||
</channel>
|
||||
<channel id="end-date" typeId="timestamp">
|
||||
<label>End Time of the Print</label>
|
||||
<description>Estimated end date of the print.</description>
|
||||
</channel>
|
||||
<channel id="wifi-signal" typeId="wifi">
|
||||
<label>WiFi Signal Strength</label>
|
||||
<description>Current WiFi signal strength.</description>
|
||||
|
||||
+6
-6
@@ -15,7 +15,7 @@ package org.openhab.binding.bambulab.internal;
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.function.Predicate.not;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.Channel.*;
|
||||
import static org.openhab.binding.bambulab.internal.BambuLabBindingConstants.PrinterChannel.*;
|
||||
import static pl.grzeslowski.jbambuapi.mqtt.PrinterClient.Channel.LedControlCommand.*;
|
||||
import static pl.grzeslowski.jbambuapi.mqtt.PrinterClient.Channel.LedControlCommand.LedNode.*;
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.openhab.binding.bambulab.internal.BambuLabBindingConstants.Channel;
|
||||
import org.openhab.binding.bambulab.internal.BambuLabBindingConstants.PrinterChannel;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
@@ -57,7 +57,7 @@ class PrinterHandlerTest {
|
||||
|
||||
@ParameterizedTest(name = "Should handle {0} command for {1} channel and send {2}")
|
||||
@MethodSource
|
||||
public void testSendLightCommand(OnOffType command, Channel channel, Command sendCommand) {
|
||||
public void testSendLightCommand(OnOffType command, PrinterChannel channel, Command sendCommand) {
|
||||
// Given
|
||||
var channelUID = new ChannelUID("bambulab:printer:test:" + channel);
|
||||
|
||||
@@ -109,7 +109,7 @@ class PrinterHandlerTest {
|
||||
|
||||
@ParameterizedTest(name = "Command to channel {0} should not invoke `client.sendCommand`")
|
||||
@MethodSource
|
||||
public void notImplementedCommands(Channel channel) {
|
||||
public void notImplementedCommands(PrinterChannel channel) {
|
||||
// Given
|
||||
var channelUID = new ChannelUID("bambulab:printer:test:" + channel);
|
||||
|
||||
@@ -122,8 +122,8 @@ class PrinterHandlerTest {
|
||||
}
|
||||
|
||||
static Stream<Arguments> notImplementedCommands() {
|
||||
return stream(Channel.values())//
|
||||
.filter(not(Channel::isSupportCommand))//
|
||||
return stream(PrinterChannel.values())//
|
||||
.filter(not(PrinterChannel::isSupportCommand))//
|
||||
.map(Arguments::of);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -100,9 +100,11 @@ class StateParserHelperTest {
|
||||
var wifiString = "-75dBm";
|
||||
|
||||
// When
|
||||
var result = StateParserHelper.parseWifiChannel(wifiString);
|
||||
var someResult = StateParserHelper.parseWifiChannel(wifiString);
|
||||
|
||||
// Then
|
||||
assertThat(someResult).isNotEmpty();
|
||||
var result = someResult.get();
|
||||
assertThat(result).isInstanceOf(QuantityType.class);
|
||||
var quantityType = (QuantityType<?>) result;
|
||||
assertThat(quantityType.intValue()).isEqualTo(-75);
|
||||
|
||||
+11
-10
@@ -28,6 +28,7 @@ import org.openhab.core.library.types.StringType;
|
||||
/**
|
||||
* @author Martin Grześlowski - Initial contribution
|
||||
*/
|
||||
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
||||
@NonNullByDefault
|
||||
class TrayHelperTest {
|
||||
|
||||
@@ -38,7 +39,7 @@ class TrayHelperTest {
|
||||
var tray = "255";
|
||||
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray);
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray).get();
|
||||
|
||||
// Then
|
||||
assertThat(result).isInstanceOf(StringType.class);
|
||||
@@ -52,7 +53,7 @@ class TrayHelperTest {
|
||||
var tray = "254";
|
||||
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray);
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray).get();
|
||||
|
||||
// Then
|
||||
assertThat(result).isInstanceOf(StringType.class);
|
||||
@@ -63,7 +64,7 @@ class TrayHelperTest {
|
||||
@MethodSource
|
||||
public void happyPath(int tray, String expected) {
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray + "");
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray + "").get();
|
||||
|
||||
// Then
|
||||
assertThat(result.toString()).isEqualTo(expected);
|
||||
@@ -100,10 +101,10 @@ class TrayHelperTest {
|
||||
String tray = null;
|
||||
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray);
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray);
|
||||
|
||||
// Then
|
||||
assertThat(result).isEqualTo(UNDEF);
|
||||
assertThat(result).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -113,7 +114,7 @@ class TrayHelperTest {
|
||||
var tray = "not-a-number";
|
||||
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray);
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray).get();
|
||||
|
||||
// Then
|
||||
assertThat(result).isEqualTo(UNDEF);
|
||||
@@ -126,7 +127,7 @@ class TrayHelperTest {
|
||||
var tray = "";
|
||||
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray);
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray).get();
|
||||
|
||||
// Then
|
||||
assertThat(result).isEqualTo(UNDEF);
|
||||
@@ -139,7 +140,7 @@ class TrayHelperTest {
|
||||
var tray = "-5";
|
||||
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray);
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray).get();
|
||||
|
||||
// Then
|
||||
assertThat(result).isEqualTo(UNDEF);
|
||||
@@ -152,7 +153,7 @@ class TrayHelperTest {
|
||||
var tray = (TrayHelper.MAX_TRAY_VALUE + 1) + "";
|
||||
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray);
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray).get();
|
||||
|
||||
// Then
|
||||
assertThat(result).isEqualTo(UNDEF);
|
||||
@@ -165,7 +166,7 @@ class TrayHelperTest {
|
||||
var tray = TrayHelper.MAX_TRAY_VALUE + "";
|
||||
|
||||
// When
|
||||
var result = TrayHelper.updateTrayLoaded(tray);
|
||||
var result = TrayHelper.findStateForTrayLoaded(tray).get();
|
||||
|
||||
// Then
|
||||
assertThat(result.toString()).isEqualTo("AMS_4_4");
|
||||
|
||||
Reference in New Issue
Block a user