-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[iRobot] Vacuum cleaner not cleaning room #11340
Comments
No one can help? |
Pinging the author of the binding: @Sonic-Amiga |
Hello! Sorry for the delay; i don't check my email often, perhaps it's my bad. Since i've got active conversations now, i'll do it quicker.
You're supposed to fork the whole repository; this will be your private repo. In this repository you'll be able to create a branch and post a pull request. You'll post it against the central repo. This is how github works.
gson is built using reflection. During serializing an object, the library will examine data fields names of the given class and produce a respective JSON text. Automatically. Let's consider a simple example:
When serialized to JSON string, this object will produce:
Methods will be completely ignored by the serializer, they are just for convenience of using this class from the code. So there's nothing special about them. Methods are just methods, constructors are just constructors. You can extend Region class constructor in order to accept "type" as a second argument; nothing will break. When deserializing from a JSON string, if some field is missing in the string, a default value will be assigned. In other words, after object instantiation, the respective field won't be "poked" with its value from the JSON (because there's nothing provided). And vice versa, if there's some stuff in the JSON, not present in the class definition, it will be just ignored. However, a special approach needs to be used for reading the string for this to work, see comments in RoombaHandler.receive(). There's a method to make field name in the JSON different from field name in the class. A "@SerializedName" annotation is used for the purpose. In the example we have:
fields pmapId and regionId will be serialized as "pmap_id" and "region_id" respectively. It's done in order to conform to OpenHAB's coding style, where data members must be named in camelCase. Bottom line: basically, this is very much like C(++) struct. |
@Sonic-Amiga, thanks a lot for the extensive answer! So far, so good. The parameter user_pmapv_id was indeed quite easy. But I have a problem adding a user defined type in the class Region. I extend the constructor from public Region(String id) to public Region(String id, String type). Additionally, I changed the line: |
Hello! The answer is:
This construct is called a "closure" AKA "lambda expression". You're calling a map() method of Stream class, which basically iterates over members of the array and calls a function, supplied as argument, on each member. The "i -> new Region(i, type)" expression instantiates an anonymous function of the following contents:
but where does "type" come from? It's called "capturing". When you instantiate this anonymous function, technically, a (anonymous, again) class is created, in whose body a value of "type" is remembered. And an object of this class is instantiated, capturing value of "type". This is more like:
Could this have been written using a conventional "for" loop without this lambda-mumbo-jumbo? Yes, it could, but nowadays it's considered "uncool", people just love lambdas; they are trendy and sexy. P.S. I don't like lambdas; neither i like functional programming; i am very oldschool. |
Hello! |
So in my example one type value would apply to all elements in the list. Do you need to break it and specify "type" for each region string ? Yes, in this case you'll be rewriting the whole thing. And yes, a map() method iterates only one thing, not two things simultaneously. So if you have two arrays, and want to iterate over both of them using the same indices for both, yes, you'd better scrap this modern sexy approach and write a conventional for loop. |
Looks like this issue was fixed with PR #11783, if not please feel te re-open. |
Hello all,
I'm trying to use my iRobot Roomba from Openhab, especially cleaning special rooms is important for me. Unfortunately, my iRobot Roomba i7 starts cleaning everything instead of cleaning only one room.
The problem seems to be the parameter user_pmapv_id, that is omnitted when sending the vacuum cleaner on its mission. The robot expects a command of the syntax
{"command":"start","initiator":"rmtApp","time":1633160056,"ordered":1,"pmap_id":"mymapid123456789012345","regions":[{"region_id":"18","type":"rid"}],"user_pmapv_id":"123456T123456"}
Currently, the iRobot addon does not pass user_pmapv_id. Consequently, last_command contains user_pmapv_id, but it is set to null. Maybe, older versions of the Roomba software did not need this parameter. But now it is obligatory.
I think, I managed somehow to add this feature in the addon (files RoombaHandler.java and MQTTProtocol.java). How do I create branch?
Additionally, the iRobot addon is not able to let the Roomba clean special zones. A region corresponds to whole rooms, zones are user defined rectangle areas within rooms. For zones, the type must not be "rid" but "zid" (zone ID). Currently, in the Java code the type is fixed to "rid". Honestly, I don't know how add this parameter since my Java knowledge is very limited. I feel a bit strange about this gson stuff.
My iRobot uses the software version 3.18.11 (currently up to date).
Thanks for any help in advance!
Regards,
Nuesel
The text was updated successfully, but these errors were encountered: