New hardwareinterfaces API

Fork done, i started something, logging for the moment to undestand the code :wink:. Is it possible to test interface in browser? it fails for me when i click on index.html (partial exchange with the server)

I update a pull request, i had a version that push event to websocketā€¦ so no polling is needed now.

@Carsten I did a first test with two Arduino boards.

What works:

  1. The server load fully in the Arduino Yun.
  2. The objects are loaded from JSON file.
  3. New Objects are well created via Arduino IDE. This means that the init procedure works.
  4. IO-Points within the same Object can be connected rightfully.
  5. The Objects show up rightfully in the Editor and GUI communicates rightfully with the Server.
  6. Arduino can write values to the Server.

What does not work:

  1. The Server can not write Values to the Arduino.
    I just committed a small fix: Now an index is send via Serial instead of a JS Object.
    It should work now, but it does not. :smiley: This needs more debugging (I can do this after the Workshop next week).
  2. When IO-Points are connected between two Hybrid Objects, no data get received.
    I remember that there where some changes in the objectEngine, afterPluginProcessing, SocketSender or SocketServer that seemed odd to me at the time. The error must be in the decision whether the data is processed internally or externally or in the right format of the message @Carsten could you look at the Socket connection in comparison to version 0.3.1? You can test this with two computers running each a server.

@franck I have not much time next week to look through all the code changes you made, but it is possible that your code inherit some of the problems above (2). Maybe you can help to debug the Socket connection from Server to Server?

@valentin Thx for testing.
I never noticed issue (2) because Iā€™m currently running everything on one server instance. I will look into that problem. I think I might even have caused it, because I messed with the content passed to objectEngine at some point.

UPDATE:
OK, i fixed the bug (2). The socketSender was sending wrong data. I fixed it in the beta_hardwareInterfaces branch and also merged it into the Bugfix_reinit branch. This seems to have solved the realtime monitoring error as well :slight_smile:

@franck Cool, I hope will find the time to look into it this week

I think the problems has something to do with inconsistent ID handling:
https://github.com/openhybrid/object/blob/beta_hardwareInterfaces/server.js

L1351 pos and obj should not be mixed in to one objID at this point.
If I remember right,
the pos or value-ID or objID or IO-Point-ID (we need to call all this IDs that name the same thing just IOPoint in the code) is created in the moment the IO-Point is initialized. From that moment on it can be used as ID (thats what msgContent.pos points to). The code seems to generate obj+pos, where pos represents already obj+pos.
The rest of the code should just use the ID consistently.
In general I think it is good to let the object engine handle what ever ID is given instead of generating them on the spot.
L1359 the formatting seems wrong (check against v0.3.1)
L1362 obj and pos are added together, where it should not be. (check against v0.3.1)
L1371 format is wrong. (check against v0.3.1)
L1490 format is wrong. (check against v0.3.1)

It seems like the IDs are mixed up here and there and a consistent handling through out the code is not happening. We should check this against v0.3.1 so that the final IDs used for data socket connections match between v0.3.1 and the new version.

Itā€™s all a little bit confusing,

When you say format is wrong you are not quite right. The lines you are referring to (L1359, L1371, L1490) call a hardware interfaceā€™s exports.send() function. I changed the signature so that the hardware interface developer only has to deal with the names of the objects and IO points. I donā€™t pass the idā€™s anymore. That totally makes sense.

msgContent.pos is always only the name of a IO point. That is what is send by the UIā€™s object.js write() function. So socketSender() has to send the name of the IO point as well because this format needs to be consistent since it is sent to the same server. Befor I fixed it socketSender() did send an id.

When a link is created by the RealityEditor its locationInA / locationInB is set as IOName + ObjID which is why obj and pos are added together in L1362.

Well I can only say it works now and it makes sense (at least to me :wink: ) Itā€™s a little bit difficult to explain though.

Hemm. I know. Its a bit of a head wrapping around it.
When I am back in Cambridge I can help with debuging.

Ah, I just understood something I think:

This if statement https://github.com/openhybrid/object/blob/v0.3.1/server.js#L1309 basically checks if the message comes from the UI via write() which only sends the name of the IO point as pos or if it comes from the socketSender() which sends the id of the IO point as pos. If the socketSender() would also send only the name which my fix does now, one branch of the if becomes obsolete and could be removed. But that would mean older versions (like 0.3.1) which send the id would no longer be able to communicate with a newer server.

Personally I think it would be clearer if socketSender() and write() would send in the same format and there was no if statement. But that means we would lose backwards compatibility.

Ahh yes.
I think in the first versions each IOPoint was created with an IOPointName+UUID.
Then I changed it for the Arduino to objectId+IOPointName.
The reason was to minimize the string length saved for each point in the Arduino.
This allowed to always load the same object and IDs.
Making such a strong change might be actually needed.

I belive that it actually is still compatible with the older version.
Because as long as it handles incoming IDs and outgoing IDs the same, the other Object should not have an issue handling it.
I believe that only the object ID has a constrain with 12 UUID chars at the end.

Ok, now the socketSender() is only sending the IOPointName but the socketServer() still accepts both formats. I committed it into the Bugfix_reinit branch.

Well yes, as long as we keep the part in socketServer() which accepts IOPointName + objectID it will be compatible with the older version.

Maybe i can help. What is the socket from server to server ? i donā€™t how to configure this case. 2 OpenHybryd server, and how you connect to each other. I investigate soon

@franck I think I already fixed it, but you are welcome to test. You just have to run the code of Bugfix_reinit on two different physical machines, create a HybridObject on each and connect IOPoints of the two objects with each other.

@Carsten I will test on the pi today , for some reason my Pi desktop has some problems,

@V_Mohammed_Ibrahim did you get to test it yet? :slight_smile:

Ok, I found the time and something to connect to the gpio pins to debug the raspberryPI hardwareInterface myself. Seems to work. I merged the Bugfix_reinit branch into the beta_hardwareInterfaces Branch.

The only thing that is not working so far is the issue Valentin discovered:

Because I donā€™t have a Yun anymore I wonā€™t be able to debug that one.

Iā€™ve got an idea for an extension of the HardwareInterfaces API and would like to hear your opinions:

Iā€™ve found myself wanting to exchange more complex data between the WebUI and the associated HybridObject. Itā€™s not very handy to do that via ā€œinvisibleā€ IOPoints or something. For example if you take a Radio and you want to display the currently playing song in the WebUI, how do you do that? Obviously you donā€™t want to expose that information as an IOPoint. So I thought, we could easily use socket.io for that. Itā€™s already available on both sides. We could either create a new socket server on a different port or somehow use the existing one on port 8080. I didnā€™t think about implementation details like how to direct messages to the right hardware interface and what new API functions would be necessary yet. Itā€™s just a raw idea at this point. Any thoughts?

Any opinions yet?

I think this is a good idea.
But we need to be very careful designing it.

For one I think invisible IOPoints are a necessary feature. We need them to communicate IO Signals that are only for the Web Interface but not for the programming.

I think we can add a text value for each IO Point. This would not be any complex addition.
We can simply create a new data type called ā€œtā€ and handle it with the given infrastructure.

I think it would be good to create a detailed document on what data types are possible.
We need to keep it compact and organized.

What do you think @Carsten?

I think, invisible IOPoints have several downsides:

  1. They are not really invisible. They have got to have a name which is rendered as caption in the RealityEditor.
  2. You have to poll them. Probably @franck has fixed that, we should definitely look at this soon.
  3. I find them counter-intuitive. Itā€™s sort of a breach of concept.

Thatā€™s why I thought about creating another separate communication channel between the HybridObject and the Web Interface solely for the purpose of communicating stuff you donā€™t want to expose as an IOPoint without any restrictions with regards to datatypes.

And yes a detailed document on what data types are possible is a very good idea :slight_smile: