val rooms =
We are creating a variable named rooms
val rooms = gVacRoomList.members
Get the list of all the members.
val rooms = gVacRoomList.members.filter[ room | room.state == ON]
Get a list of the members that are ON. At this point we have a list of Items.
val rooms = gVacRoomList.members.filter[ room | room.state == ON].map[ name ]
Convert the list of Items to a list of Strings of the Items names. So at this point we have a list of all the Item names, no more Items.
val rooms = gVacRoomList.members.filter[ room | room.state == ON ].map[ name ].reduce[ ids, name | ids = ids + ", " + names.replace("room", "") ]
Convert the list of Item names to a single String that consists of just the number part of the Item names, separated by commas.
So after the reduce, rooms
should look something like 18, 19, 22, 26
. That’s what you want to send as part of your command to the robot, the list of room numbers to clean.
Because we didn’t pull the Item names. We pulled the actual Item object. But all we want is the Item name so we convert the List of Items to a List of Strings of the Item names. It happens after the filter so the make creates a list of only the Item names that are ON.
reduce takes a list of something and reduces it down to just one something. In this case it creates a single String that is a comma separated list of just the number portion of the Item names. In your example it should be “18, 21”.
That’s why I gave the hint to log out stuff. If you log out rooms you will see exactly what that long line produced.
I should have been more specific.
roomCleaning.sendCommand("app_segment_clean["+rooms+"]")
Ah, yes. Let’s move the removal of “room” to the map instead.
val ids = gVacRoomList.members.filter[ room | room.state == ON ].map[ name.replace("room", "") ].reduce [ ids, name | ids + ", " ]
The reduce function needs to initialize the return variable, in this case ids
. It does so by initializing it with the first element of the list passed to it from the map. But because of that, we never got a chance to remove “room” from the name for that first element. By moving the replace to the “map” we avoid that problem.
Note,
val ids = null
val command = null
This should be generating all sorts of warnings in the logs. The whole point of using val
instead of var
is that you are telling the program that “ids
is a constant, don’t let me change it.” So you should never see ids
anywhere else in your rule with a single =
after it.
The second problem is because you’ve initialized it to null
there is absolutely no information the Rules Engine can use to determine the type of those values. So it’s going to fall back to the lowest common denominator, Object
. That doesn’t matter here because even Object
has a toString
so it can figure out how to do the string operation to build the command. But if ids
were a number or an Item or a timer it would not work.