[miio] map improvement cropping and customizable colors/parameters (#11110)
* [miio] make robo map drawing customizable Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * [miio] Add cropping possibility for vacuum map Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com> * miio minor edit Signed-off-by: Marcel Verpaalen <marcel@verpaalen.com>pull/11133/head
parent
0d286e7a89
commit
62f169d649
|
@ -45,6 +45,7 @@ import org.openhab.binding.miio.internal.cloud.MiCloudException;
|
|||
import org.openhab.binding.miio.internal.robot.ConsumablesType;
|
||||
import org.openhab.binding.miio.internal.robot.FanModeType;
|
||||
import org.openhab.binding.miio.internal.robot.RRMapDraw;
|
||||
import org.openhab.binding.miio.internal.robot.RRMapDrawOptions;
|
||||
import org.openhab.binding.miio.internal.robot.RobotCababilities;
|
||||
import org.openhab.binding.miio.internal.robot.StatusDTO;
|
||||
import org.openhab.binding.miio.internal.robot.StatusType;
|
||||
|
@ -88,7 +89,6 @@ import com.google.gson.JsonObject;
|
|||
@NonNullByDefault
|
||||
public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(MiIoVacuumHandler.class);
|
||||
private static final float MAP_SCALE = 2.0f;
|
||||
private static final DateTimeFormatter DATEFORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss");
|
||||
private static final Gson GSON = new GsonBuilder().serializeNulls().create();
|
||||
private final ChannelUID mapChannelUid;
|
||||
|
@ -110,6 +110,7 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||
private boolean hasChannelStructure;
|
||||
private ConcurrentHashMap<RobotCababilities, Boolean> deviceCapabilities = new ConcurrentHashMap<>();
|
||||
private ChannelTypeRegistry channelTypeRegistry;
|
||||
private RRMapDrawOptions mapDrawOptions = new RRMapDrawOptions();
|
||||
|
||||
public MiIoVacuumHandler(Thing thing, MiIoDatabaseWatchService miIoDatabaseWatchService,
|
||||
CloudConnector cloudConnector, ChannelTypeRegistry channelTypeRegistry) {
|
||||
|
@ -171,7 +172,6 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||
}
|
||||
return null;
|
||||
});
|
||||
updateState(RobotCababilities.SEGMENT_CLEAN.getChannel(), new StringType("-"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -490,6 +490,9 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||
public void initialize() {
|
||||
super.initialize();
|
||||
hasChannelStructure = false;
|
||||
this.mapDrawOptions = RRMapDrawOptions
|
||||
.getOptionsFromFile(BINDING_USERDATA_PATH + File.separator + "mapConfig.json", logger);
|
||||
updateState(RobotCababilities.SEGMENT_CLEAN.getChannel(), new StringType("-"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -651,6 +654,7 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||
if (mapDl != null) {
|
||||
byte[] mapData = mapDl.getBytes();
|
||||
RRMapDraw rrMap = RRMapDraw.loadImage(new ByteArrayInputStream(mapData));
|
||||
rrMap.setDrawOptions(mapDrawOptions);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
if (logger.isDebugEnabled()) {
|
||||
final String mapPath = BINDING_USERDATA_PATH + File.separator + map
|
||||
|
@ -658,7 +662,7 @@ public class MiIoVacuumHandler extends MiIoAbstractHandler {
|
|||
CloudUtil.writeBytesToFileNio(mapData, mapPath);
|
||||
logger.debug("Mapdata saved to {}", mapPath);
|
||||
}
|
||||
ImageIO.write(rrMap.getImage(MAP_SCALE), "jpg", baos);
|
||||
ImageIO.write(rrMap.getImage(), "jpg", baos);
|
||||
byte[] byteArray = baos.toByteArray();
|
||||
if (byteArray != null && byteArray.length > 0) {
|
||||
return new RawType(byteArray, "image/jpeg");
|
||||
|
|
|
@ -62,41 +62,18 @@ public class RRMapDraw {
|
|||
private static final int MAP_WALL = 0x01;
|
||||
private static final int MAP_INSIDE = 0xFF;
|
||||
private static final int MAP_SCAN = 0x07;
|
||||
private static final Color COLOR_MAP_INSIDE = new Color(32, 115, 185);
|
||||
private static final Color COLOR_MAP_OUTSIDE = new Color(19, 87, 148);
|
||||
private static final Color COLOR_MAP_WALL = new Color(100, 196, 254);
|
||||
private static final Color COLOR_CARPET = new Color(0xDF, 0xDF, 0xDF, 0xA0);
|
||||
private static final Color COLOR_GREY_WALL = new Color(93, 109, 126);
|
||||
private static final Color COLOR_PATH = new Color(147, 194, 238);
|
||||
private static final Color COLOR_ZONES = new Color(0xAD, 0xD8, 0xFF, 0x8F);
|
||||
private static final Color COLOR_NO_GO_ZONES = new Color(255, 33, 55, 127);
|
||||
private static final Color COLOR_CHARGER_HALO = new Color(0x66, 0xfe, 0xda, 0x7f);
|
||||
private static final Color COLOR_ROBO = new Color(75, 235, 149);
|
||||
private static final Color COLOR_SCAN = new Color(0xDF, 0xDF, 0xDF);
|
||||
private static final Color ROOM1 = new Color(240, 178, 122);
|
||||
private static final Color ROOM2 = new Color(133, 193, 233);
|
||||
private static final Color ROOM3 = new Color(217, 136, 128);
|
||||
private static final Color ROOM4 = new Color(52, 152, 219);
|
||||
private static final Color ROOM5 = new Color(205, 97, 85);
|
||||
private static final Color ROOM6 = new Color(243, 156, 18);
|
||||
private static final Color ROOM7 = new Color(88, 214, 141);
|
||||
private static final Color ROOM8 = new Color(245, 176, 65);
|
||||
private static final Color ROOM9 = new Color(0xFc, 0xD4, 0x51);
|
||||
private static final Color ROOM10 = new Color(72, 201, 176);
|
||||
private static final Color ROOM11 = new Color(84, 153, 199);
|
||||
private static final Color ROOM12 = new Color(255, 213, 209);
|
||||
private static final Color ROOM13 = new Color(228, 228, 215);
|
||||
private static final Color ROOM14 = new Color(82, 190, 128);
|
||||
private static final Color ROOM15 = new Color(72, 201, 176);
|
||||
private static final Color ROOM16 = new Color(165, 105, 189);
|
||||
private static final Color[] ROOM_COLORS = { ROOM1, ROOM2, ROOM3, ROOM4, ROOM5, ROOM6, ROOM7, ROOM8, ROOM9, ROOM10,
|
||||
ROOM11, ROOM12, ROOM13, ROOM14, ROOM15, ROOM16 };
|
||||
private final @Nullable Bundle bundle = FrameworkUtil.getBundle(getClass());
|
||||
private boolean multicolor = false;
|
||||
private final RRMapFileParser rmfp;
|
||||
|
||||
private final @Nullable Bundle bundle = FrameworkUtil.getBundle(getClass());
|
||||
private final RRMapFileParser rmfp;
|
||||
private final Logger logger = LoggerFactory.getLogger(RRMapDraw.class);
|
||||
|
||||
private RRMapDrawOptions drawOptions = new RRMapDrawOptions();
|
||||
private boolean multicolor = false;
|
||||
private int firstX = 0;
|
||||
private int lastX = 0;
|
||||
private int firstY = 0;
|
||||
private int lastY = 0;
|
||||
|
||||
public RRMapDraw(RRMapFileParser rmfp) {
|
||||
this.rmfp = rmfp;
|
||||
}
|
||||
|
@ -109,6 +86,14 @@ public class RRMapDraw {
|
|||
return rmfp.getImgHeight();
|
||||
}
|
||||
|
||||
public void setDrawOptions(RRMapDrawOptions options) {
|
||||
this.drawOptions = options;
|
||||
}
|
||||
|
||||
public RRMapDrawOptions getDrawOptions() {
|
||||
return drawOptions;
|
||||
}
|
||||
|
||||
public RRMapFileParser getMapParseDetails() {
|
||||
return this.rmfp;
|
||||
}
|
||||
|
@ -145,29 +130,29 @@ public class RRMapDraw {
|
|||
byte walltype = rmfp.getImage()[x + rmfp.getImgWidth() * y];
|
||||
switch (walltype & 0xFF) {
|
||||
case MAP_OUTSIDE:
|
||||
g2d.setColor(COLOR_MAP_OUTSIDE);
|
||||
g2d.setColor(drawOptions.getColorMapOutside());
|
||||
break;
|
||||
case MAP_WALL:
|
||||
g2d.setColor(COLOR_MAP_WALL);
|
||||
g2d.setColor(drawOptions.getColorMapWall());
|
||||
break;
|
||||
case MAP_INSIDE:
|
||||
g2d.setColor(COLOR_MAP_INSIDE);
|
||||
g2d.setColor(drawOptions.getColorMapInside());
|
||||
break;
|
||||
case MAP_SCAN:
|
||||
g2d.setColor(COLOR_SCAN);
|
||||
g2d.setColor(drawOptions.getColorScan());
|
||||
break;
|
||||
default:
|
||||
int obstacle = (walltype & 0x07);
|
||||
int mapId = (walltype & 0xFF) >>> 3;
|
||||
switch (obstacle) {
|
||||
case 0:
|
||||
g2d.setColor(COLOR_GREY_WALL);
|
||||
g2d.setColor(drawOptions.getColorGreyWall());
|
||||
break;
|
||||
case 1:
|
||||
g2d.setColor(Color.BLACK);
|
||||
break;
|
||||
case 7:
|
||||
g2d.setColor(ROOM_COLORS[mapId % 15]);
|
||||
g2d.setColor(drawOptions.getRoomColors()[mapId % 15]);
|
||||
roomIds.add(mapId);
|
||||
multicolor = true;
|
||||
break;
|
||||
|
@ -207,7 +192,7 @@ public class RRMapDraw {
|
|||
// ignore
|
||||
break;
|
||||
default:
|
||||
g2d.setColor(COLOR_CARPET);
|
||||
g2d.setColor(drawOptions.getColorCarpet());
|
||||
float xPos = scale * (rmfp.getImgWidth() - x);
|
||||
float yP = scale * y;
|
||||
g2d.draw(new Line2D.Float(xPos, yP, xPos, yP));
|
||||
|
@ -230,7 +215,7 @@ public class RRMapDraw {
|
|||
switch (pathType) {
|
||||
case RRMapFileParser.PATH:
|
||||
if (!multicolor) {
|
||||
g2d.setColor(COLOR_PATH);
|
||||
g2d.setColor(drawOptions.getColorPath());
|
||||
} else {
|
||||
g2d.setColor(Color.WHITE);
|
||||
}
|
||||
|
@ -268,7 +253,7 @@ public class RRMapDraw {
|
|||
float w = Math.max(x, x1) - sx;
|
||||
float sy = Math.min(y, y1);
|
||||
float h = Math.max(y, y1) - sy;
|
||||
g2d.setColor(COLOR_ZONES);
|
||||
g2d.setColor(drawOptions.getColorZones());
|
||||
g2d.fill(new Rectangle2D.Float(sx, sy, w, h));
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +275,7 @@ public class RRMapDraw {
|
|||
noGo.lineTo(x2, y2);
|
||||
noGo.lineTo(x3, y3);
|
||||
noGo.lineTo(x, y);
|
||||
g2d.setColor(COLOR_NO_GO_ZONES);
|
||||
g2d.setColor(drawOptions.getColorNoGoZones());
|
||||
g2d.fill(noGo);
|
||||
g2d.setColor(area.getKey() == 9 ? Color.RED : Color.WHITE);
|
||||
g2d.draw(noGo);
|
||||
|
@ -316,13 +301,13 @@ public class RRMapDraw {
|
|||
float radius = 3 * scale;
|
||||
Stroke stroke = new BasicStroke(2 * scale);
|
||||
g2d.setStroke(stroke);
|
||||
g2d.setColor(COLOR_CHARGER_HALO);
|
||||
g2d.setColor(drawOptions.getColorChargerHalo());
|
||||
final float chargerX = toXCoord(rmfp.getChargerX()) * scale;
|
||||
final float chargerY = toYCoord(rmfp.getChargerY()) * scale;
|
||||
drawCircle(g2d, chargerX, chargerY, radius, false);
|
||||
drawCenteredImg(g2d, scale / 8, "charger.png", chargerX, chargerY);
|
||||
radius = 3 * scale;
|
||||
g2d.setColor(COLOR_ROBO);
|
||||
g2d.setColor(drawOptions.getColorRobo());
|
||||
final float roboX = toXCoord(rmfp.getRoboX()) * scale;
|
||||
final float roboY = toYCoord(rmfp.getRoboY()) * scale;
|
||||
drawCircle(g2d, roboX, roboY, radius, false);
|
||||
|
@ -410,18 +395,22 @@ public class RRMapDraw {
|
|||
} catch (IOException e) {
|
||||
logger.debug("Error loading image ohlogo.png:: {}", e.getMessage());
|
||||
}
|
||||
if (drawOptions.getText().isBlank()) {
|
||||
return;
|
||||
}
|
||||
String fontName = getAvailableFont("Helvetica,Arial,Roboto,Verdana,Times,Serif,Dialog".split(","));
|
||||
if (fontName == null) {
|
||||
return; // no available fonts to draw text
|
||||
}
|
||||
Font font = new Font(fontName, Font.BOLD, 14);
|
||||
int fz = (int) (drawOptions.getTextFontSize() * scale);
|
||||
Font font = new Font(fontName, Font.BOLD, fz);
|
||||
g2d.setFont(font);
|
||||
String message = "Openhab rocks your Xiaomi vacuum!";
|
||||
String message = drawOptions.getText();
|
||||
FontMetrics fontMetrics = g2d.getFontMetrics();
|
||||
int stringWidth = fontMetrics.stringWidth(message);
|
||||
if ((stringWidth + textPos) > rmfp.getImgWidth() * scale) {
|
||||
font = new Font(fontName, Font.BOLD,
|
||||
(int) Math.floor(14 * (rmfp.getImgWidth() * scale - textPos - offset * scale) / stringWidth));
|
||||
if ((stringWidth + textPos) > width) {
|
||||
int fzn = (int) Math.floor(((float) (width - textPos) / stringWidth) * fz);
|
||||
font = new Font(fontName, Font.BOLD, fzn > 0 ? fzn : 1);
|
||||
g2d.setFont(font);
|
||||
}
|
||||
int stringHeight = fontMetrics.getAscent();
|
||||
|
@ -449,6 +438,39 @@ public class RRMapDraw {
|
|||
return fonts[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the perimeter of the used area in the map
|
||||
*/
|
||||
private void getMapArea(Graphics2D g2d, float scale) {
|
||||
int firstX = rmfp.getImgWidth();
|
||||
int lastX = 0;
|
||||
int firstY = rmfp.getImgHeight();
|
||||
int lastY = 0;
|
||||
for (int y = 0; y < rmfp.getImgHeight() - 1; y++) {
|
||||
for (int x = 0; x < rmfp.getImgWidth() + 1; x++) {
|
||||
int walltype = rmfp.getImage()[x + rmfp.getImgWidth() * y] & 0xFF;
|
||||
if (walltype > MAP_OUTSIDE) {
|
||||
if (y < firstY) {
|
||||
firstY = y;
|
||||
}
|
||||
if (y > lastY) {
|
||||
lastY = y;
|
||||
}
|
||||
if (x < firstX) {
|
||||
firstX = x;
|
||||
}
|
||||
if (x > lastX) {
|
||||
lastX = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.firstX = firstX;
|
||||
this.lastX = lastX;
|
||||
this.firstY = rmfp.getImgHeight() - lastY;
|
||||
this.lastY = rmfp.getImgHeight() - firstY;
|
||||
}
|
||||
|
||||
private @Nullable URL getImageUrl(String image) {
|
||||
final Bundle bundle = this.bundle;
|
||||
if (bundle != null) {
|
||||
|
@ -464,6 +486,10 @@ public class RRMapDraw {
|
|||
}
|
||||
}
|
||||
|
||||
public BufferedImage getImage() {
|
||||
return getImage(drawOptions.getScale());
|
||||
}
|
||||
|
||||
public BufferedImage getImage(float scale) {
|
||||
int width = (int) Math.floor(rmfp.getImgWidth() * scale);
|
||||
int height = (int) Math.floor(rmfp.getImgHeight() * scale);
|
||||
|
@ -481,9 +507,34 @@ public class RRMapDraw {
|
|||
drawRobo(g2d, scale);
|
||||
drawGoTo(g2d, scale);
|
||||
drawObstacles(g2d, scale);
|
||||
g2d = bi.createGraphics();
|
||||
drawOpenHabRocks(g2d, width, height, scale);
|
||||
return bi;
|
||||
if (drawOptions.getCropBorder() < 0) {
|
||||
g2d = bi.createGraphics();
|
||||
if (drawOptions.isShowLogo()) {
|
||||
drawOpenHabRocks(g2d, width, height, scale);
|
||||
}
|
||||
return bi;
|
||||
}
|
||||
// crop the image to the used perimeter
|
||||
getMapArea(g2d, scale);
|
||||
int firstX = (this.firstX - drawOptions.getCropBorder()) > 0 ? this.firstX - drawOptions.getCropBorder() : 0;
|
||||
int lastX = (this.lastX + drawOptions.getCropBorder()) < rmfp.getImgWidth()
|
||||
? this.lastX + drawOptions.getCropBorder()
|
||||
: rmfp.getImgWidth();
|
||||
int firstY = (this.firstY - drawOptions.getCropBorder()) > 0 ? this.firstY - drawOptions.getCropBorder() : 0;
|
||||
int lastY = (this.lastY + drawOptions.getCropBorder() + (int) (8 * scale)) < rmfp.getImgHeight()
|
||||
? this.lastY + drawOptions.getCropBorder() + (int) (8 * scale)
|
||||
: rmfp.getImgHeight();
|
||||
int nwidth = (int) Math.floor((lastX - firstX) * scale);
|
||||
int nheight = (int) Math.floor((lastY - firstY) * scale);
|
||||
BufferedImage bo = new BufferedImage(nwidth, nheight, BufferedImage.TYPE_3BYTE_BGR);
|
||||
Graphics2D crop = bo.createGraphics();
|
||||
crop.transform(AffineTransform.getTranslateInstance(-firstX * scale, -firstY * scale));
|
||||
crop.drawImage(bi, 0, 0, null);
|
||||
if (drawOptions.isShowLogo()) {
|
||||
crop = bo.createGraphics();
|
||||
drawOpenHabRocks(crop, nwidth, nheight, scale * .75f);
|
||||
}
|
||||
return bo;
|
||||
}
|
||||
|
||||
public boolean writePic(String filename, String formatName, float scale) throws IOException {
|
||||
|
|
|
@ -0,0 +1,317 @@
|
|||
/**
|
||||
* Copyright (c) 2010-2021 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.miio.internal.robot;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* This class provides the configuration for the vacuum map drawing
|
||||
*
|
||||
* @author Marcel Verpaalen - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RRMapDrawOptions {
|
||||
|
||||
private static final Color COLOR_MAP_INSIDE = new Color(32, 115, 185);
|
||||
private static final Color COLOR_MAP_OUTSIDE = new Color(19, 87, 148);
|
||||
private static final Color COLOR_MAP_WALL = new Color(100, 196, 254);
|
||||
private static final Color COLOR_CARPET = new Color(0xDF, 0xDF, 0xDF, 0xA0);
|
||||
private static final Color COLOR_GREY_WALL = new Color(93, 109, 126);
|
||||
private static final Color COLOR_PATH = new Color(147, 194, 238);
|
||||
private static final Color COLOR_ZONES = new Color(0xAD, 0xD8, 0xFF, 0x8F);
|
||||
private static final Color COLOR_NO_GO_ZONES = new Color(255, 33, 55, 127);
|
||||
private static final Color COLOR_CHARGER_HALO = new Color(0x66, 0xfe, 0xda, 0x7f);
|
||||
private static final Color COLOR_ROBO = new Color(75, 235, 149);
|
||||
private static final Color COLOR_SCAN = new Color(0xDF, 0xDF, 0xDF);
|
||||
private static final Color ROOM1 = new Color(240, 178, 122);
|
||||
private static final Color ROOM2 = new Color(133, 193, 233);
|
||||
private static final Color ROOM3 = new Color(217, 136, 128);
|
||||
private static final Color ROOM4 = new Color(52, 152, 219);
|
||||
private static final Color ROOM5 = new Color(205, 97, 85);
|
||||
private static final Color ROOM6 = new Color(243, 156, 18);
|
||||
private static final Color ROOM7 = new Color(88, 214, 141);
|
||||
private static final Color ROOM8 = new Color(245, 176, 65);
|
||||
private static final Color ROOM9 = new Color(0xFc, 0xD4, 0x51);
|
||||
private static final Color ROOM10 = new Color(72, 201, 176);
|
||||
private static final Color ROOM11 = new Color(84, 153, 199);
|
||||
private static final Color ROOM12 = new Color(255, 213, 209);
|
||||
private static final Color ROOM13 = new Color(228, 228, 215);
|
||||
private static final Color ROOM14 = new Color(82, 190, 128);
|
||||
private static final Color ROOM15 = new Color(72, 201, 176);
|
||||
private static final Color ROOM16 = new Color(165, 105, 189);
|
||||
private static final Color[] ROOM_COLORS = { ROOM1, ROOM2, ROOM3, ROOM4, ROOM5, ROOM6, ROOM7, ROOM8, ROOM9, ROOM10,
|
||||
ROOM11, ROOM12, ROOM13, ROOM14, ROOM15, ROOM16 };
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting()
|
||||
.registerTypeAdapter(Color.class, new JsonSerializer<Color>() {
|
||||
@Override
|
||||
public JsonElement serialize(Color src, @Nullable Type typeOfSrc,
|
||||
@Nullable JsonSerializationContext context) {
|
||||
JsonObject colorSave = new JsonObject();
|
||||
colorSave.addProperty("red", src.getRed());
|
||||
colorSave.addProperty("green", src.getGreen());
|
||||
colorSave.addProperty("blue", src.getBlue());
|
||||
colorSave.addProperty("alpha", src.getAlpha());
|
||||
return colorSave;
|
||||
}
|
||||
}).registerTypeAdapter(Color.class, new JsonDeserializer<Color>() {
|
||||
@Override
|
||||
@Nullable
|
||||
public Color deserialize(@Nullable JsonElement json, @Nullable Type typeOfT,
|
||||
@Nullable JsonDeserializationContext context) throws JsonParseException {
|
||||
if (json == null) {
|
||||
throw new JsonParseException("missing json text");
|
||||
}
|
||||
JsonObject colorSave = json.getAsJsonObject();
|
||||
Color color = new Color(colorSave.get("red").getAsInt(), colorSave.get("green").getAsInt(),
|
||||
colorSave.get("blue").getAsInt(), colorSave.get("alpha").getAsInt());
|
||||
return color;
|
||||
}
|
||||
}).create();
|
||||
|
||||
@SerializedName("colorMapInside")
|
||||
@Expose
|
||||
private Color colorMapInside = COLOR_MAP_INSIDE;
|
||||
@SerializedName("colorMapOutside")
|
||||
@Expose
|
||||
private Color colorMapOutside = COLOR_MAP_OUTSIDE;
|
||||
@SerializedName("colorMapWall")
|
||||
@Expose
|
||||
private Color colorMapWall = COLOR_MAP_WALL;
|
||||
@SerializedName("colorCarpet")
|
||||
@Expose
|
||||
private Color colorCarpet = COLOR_CARPET;
|
||||
@SerializedName("colorGreyWall")
|
||||
@Expose
|
||||
private Color colorGreyWall = COLOR_GREY_WALL;
|
||||
@SerializedName("colorPath")
|
||||
@Expose
|
||||
private Color colorPath = COLOR_PATH;
|
||||
@SerializedName("colorZones")
|
||||
@Expose
|
||||
private Color colorZones = COLOR_ZONES;
|
||||
@SerializedName("colorNoGoZones")
|
||||
@Expose
|
||||
private Color colorNoGoZones = COLOR_NO_GO_ZONES;
|
||||
@SerializedName("colorChargerHalo")
|
||||
@Expose
|
||||
private Color colorChargerHalo = COLOR_CHARGER_HALO;
|
||||
@SerializedName("colorRobo")
|
||||
@Expose
|
||||
private Color colorRobo = COLOR_ROBO;
|
||||
@SerializedName("colorScan")
|
||||
@Expose
|
||||
private Color colorScan = COLOR_SCAN;
|
||||
|
||||
@SerializedName("roomColors")
|
||||
@Expose
|
||||
private Color[] roomColors = ROOM_COLORS;
|
||||
|
||||
@SerializedName("showLogo")
|
||||
@Expose
|
||||
private boolean showLogo = true;
|
||||
@SerializedName("text")
|
||||
@Expose
|
||||
private String text = "Openhab rocks your Xiaomi vacuum!";
|
||||
@SerializedName("textFontSize")
|
||||
@Expose
|
||||
private int textFontSize = 12;
|
||||
@SerializedName("scale")
|
||||
@Expose
|
||||
private float scale = 2.0f;
|
||||
@SerializedName("cropBorder")
|
||||
@Expose
|
||||
private int cropBorder = 10;
|
||||
|
||||
public Color getColorMapInside() {
|
||||
return colorMapInside;
|
||||
}
|
||||
|
||||
public void setColorMapInside(Color colorMapInside) {
|
||||
this.colorMapInside = colorMapInside;
|
||||
}
|
||||
|
||||
public Color getColorMapOutside() {
|
||||
return colorMapOutside;
|
||||
}
|
||||
|
||||
public void setColorMapOutside(Color colorMapOutside) {
|
||||
this.colorMapOutside = colorMapOutside;
|
||||
}
|
||||
|
||||
public Color getColorMapWall() {
|
||||
return colorMapWall;
|
||||
}
|
||||
|
||||
public void setColorMapWall(Color colorMapWall) {
|
||||
this.colorMapWall = colorMapWall;
|
||||
}
|
||||
|
||||
public Color getColorCarpet() {
|
||||
return colorCarpet;
|
||||
}
|
||||
|
||||
public void setColorCarpet(Color colorCarpet) {
|
||||
this.colorCarpet = colorCarpet;
|
||||
}
|
||||
|
||||
public Color getColorGreyWall() {
|
||||
return colorGreyWall;
|
||||
}
|
||||
|
||||
public void setColorGreyWall(Color colorGreyWall) {
|
||||
this.colorGreyWall = colorGreyWall;
|
||||
}
|
||||
|
||||
public Color getColorPath() {
|
||||
return colorPath;
|
||||
}
|
||||
|
||||
public void setColorPath(Color colorPath) {
|
||||
this.colorPath = colorPath;
|
||||
}
|
||||
|
||||
public Color getColorZones() {
|
||||
return colorZones;
|
||||
}
|
||||
|
||||
public void setColorZones(Color colorZones) {
|
||||
this.colorZones = colorZones;
|
||||
}
|
||||
|
||||
public Color getColorNoGoZones() {
|
||||
return colorNoGoZones;
|
||||
}
|
||||
|
||||
public void setColorNoGoZones(Color colorNoGoZones) {
|
||||
this.colorNoGoZones = colorNoGoZones;
|
||||
}
|
||||
|
||||
public Color getColorChargerHalo() {
|
||||
return colorChargerHalo;
|
||||
}
|
||||
|
||||
public void setColorChargerHalo(Color colorChargerHalo) {
|
||||
this.colorChargerHalo = colorChargerHalo;
|
||||
}
|
||||
|
||||
public Color getColorRobo() {
|
||||
return colorRobo;
|
||||
}
|
||||
|
||||
public void setColorRobo(Color colorRobo) {
|
||||
this.colorRobo = colorRobo;
|
||||
}
|
||||
|
||||
public Color getColorScan() {
|
||||
return colorScan;
|
||||
}
|
||||
|
||||
public void setColorScan(Color colorScan) {
|
||||
this.colorScan = colorScan;
|
||||
}
|
||||
|
||||
public Color[] getRoomColors() {
|
||||
return roomColors;
|
||||
}
|
||||
|
||||
public void setRoomColors(Color[] roomColors) {
|
||||
this.roomColors = roomColors;
|
||||
}
|
||||
|
||||
public boolean isShowLogo() {
|
||||
return showLogo;
|
||||
}
|
||||
|
||||
public void setShowLogo(boolean showLogo) {
|
||||
this.showLogo = showLogo;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public final int getTextFontSize() {
|
||||
return textFontSize;
|
||||
}
|
||||
|
||||
public final void setTextFontSize(int textFontSize) {
|
||||
this.textFontSize = textFontSize;
|
||||
}
|
||||
|
||||
public float getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
public void setScale(float scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
public final int getCropBorder() {
|
||||
return cropBorder;
|
||||
}
|
||||
|
||||
public final void setCropBorder(int cropBorder) {
|
||||
this.cropBorder = cropBorder;
|
||||
}
|
||||
|
||||
public static void writeOptionsToFile(RRMapDrawOptions options, String fileName, Logger logger) {
|
||||
String json = GSON.toJson(options, RRMapDrawOptions.class);
|
||||
try (PrintWriter pw = new PrintWriter(fileName)) {
|
||||
pw.println(json);
|
||||
logger.debug("Vacuum map draw options file created: {}", fileName);
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.info("Error writing Vacuum map draw options file: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static RRMapDrawOptions getOptionsFromFile(String fileName, Logger logger) {
|
||||
try {
|
||||
RRMapDrawOptions options = GSON.fromJson(new FileReader(fileName), RRMapDrawOptions.class);
|
||||
return options;
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.debug("Vacuum map draw options file {} not found. Using defaults", fileName);
|
||||
return new RRMapDrawOptions();
|
||||
} catch (JsonParseException e) {
|
||||
logger.info("Error reading vacuum map draw options file {}: {}", fileName, e.getMessage());
|
||||
}
|
||||
logger.info("Write default map draw options to {}", fileName);
|
||||
RRMapDrawOptions options = new RRMapDrawOptions();
|
||||
writeOptionsToFile(options, fileName, logger);
|
||||
return new RRMapDrawOptions();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue