Hi,
I have enhanced the rule to support multi zone configuration. In the zone transform file, single zone is defined by numbers, multi zone is a list of single zones, e.g:
entrance=-1.8,0,2,6,1
kitchen=-5,0.5,3.6,2.6,1
livingroom=0,0.5,4.2,5.2,1
diningroom=-1.6,5.9,2.9,2.7,1
groundfloor=entrance,kitchen
The relevant items are:
String Vacuum_Action_Control "Control" (Vacuum) { channel="miio:vacuum:04EFCDCA:actions#control" }
String Vacuum_Action_Command "Command" { channel="miio:vacuum:04EFCDCA:actions#commands" }
String Vacuum_Control "Control" { expire="1s,state=UNDEF" }
String Vacuum_Zone "Zone [%s]" <floor_plan>
And the rule file is:
// Logging name tag
val logName = "Vacuum"
///////////////////////////////////////////////////////////////////////////////
// Function
///////////////////////////////////////////////////////////////////////////////
val Functions$Function1<String, String> getZoneCoordinates =
[zone |
var parameters = zone.split(',')
// Docking point start position
val double x = 25500.0;
val double y = 25500.0;
// Bottom (y) left (x)
val double b = Double::parseDouble(parameters.get(0)) * 1000.0 + x
val double l = Double::parseDouble(parameters.get(1)) * 1000.0 + y
// Top (y) right (x)
val double t = b + Double::parseDouble(parameters.get(2)) * 1000.0
val double r = l + Double::parseDouble(parameters.get(3)) * 1000.0
// Build zone coordinates (and number of times to scan)
val coordinates = String::format("[%.0f,%.0f,%.0f,%.0f,%s]", b, l, t, r, parameters.get(4));
coordinates
]
///////////////////////////////////////////////////////////////////////////////
// Rule
///////////////////////////////////////////////////////////////////////////////
rule "Vacuum control"
when
Item Vacuum_Control received command
then
logInfo(logName, "Vacuum command: {}", receivedCommand.toString)
if (receivedCommand.toString == "vacuum") {
// The final command send to the vacuum
var String command = ""
// Get zone coordinates
var String zone = transform("MAP", "zones.map", Vacuum_Zone.state.toString)
// We still don't know if this is single or multiple zone
var parameters = zone.split(',')
try {
// Single zone only have numbers
Double::parseDouble(parameters.get(0))
command = getZoneCoordinates.apply(zone)
} catch (Throwable t) {
// This is multi zone
parameters.forEach[string z|
zone = transform("MAP", "zones.map", z)
command = command + getZoneCoordinates.apply(zone) + ","
]
// Remove last ','
command = command.substring(0, command.length - 1)
}
command = String::format("[%s]", command)
logInfo(logName, "Clean {} zone coordinates {}", receivedCommand.toString, command)
Vacuum_Action_Command.sendCommand('app_zoned_clean' + command)
} else {
Vacuum_Action_Control.sendCommand(receivedCommand.toString)
}
end
Comments, suggestion, improvements are welocme