Coder Social home page Coder Social logo

Comments (5)

DrAma999 avatar DrAma999 commented on September 24, 2024

I will check this weekend and get back to you.
Thank you for the example.

from littlebluetooth.

DrAma999 avatar DrAma999 commented on September 24, 2024

Hello @NeverwinterMoon about this issue.
First let me try to explain the error characteristicNotFound(_:). Usually is thrown when a specific characteristic identifier is not found in the service. Since the methods taken separately are working it means that no error is made while building the LittleBlueToothCharacteristic.
If tried to replicate your error by using the mocking library that I use to run the tests and it simply works, test is run successfully combining latest values from the characteristics.
I do agree that is not a real word scenario so I tried to use LightBlue application to simulate a peripheral and I've found the issue.
I really don’t know how KMM is working by creating coroutines and the implementation they are using ,since they are still not available(yet) in swift, but the problem is most probably due to the nature of "cold" publisher of combine's publishers of most of combine operators.
What is happening is that here we have 2 publishers (that are subscribed in parallel) that are "listening" to changes for characteristic discoveries. The first command asks to search for the first characteristic, but the second is already subscribed. So while the first successfully get the discovery the second throws an error because it has search for another characteristic but it tries to find a match with the first trigger.
I hope to find a solution soon.

Best,
Andrea

from littlebluetooth.

NeverwinterMoon avatar NeverwinterMoon commented on September 24, 2024

Thanks for looking into it.

As I understand, that the problem is tied to the discovery of the characteristics only. In such a case, why not introduce the discovery for multiple characteristics at once? The discoverCharacteristics(_:for:) method accepts a list of characteristics and peripheral(_:didDiscoverCharacteristicsFor:error:) is called only after all the requested characteristics are discovered, not one by one. After that, discovery/reading can be done on all of them in any order.

In fact, I do have my own implementation doing just that, and I am able to use CombineLatest on several publishers. In my use case, I am actually subscribing to 8 characteristics that way, as the UI need to display metrics from all of them at once.

Except that my code is not very generic, unlike yours, so I am not sure how plausible this is in case of your library.

But what I do:

  • Use discoverCharacteristics(_:for:) to discover all characteristic I want to immediately observe at once.
  • In the discovery callback peripheral(_:didDiscoverCharacteristicsFor:error:), I iterate over all discovered characteristics and call both - readValue(for:) and setNotifyValue:forCharacteristic:on each.
  • In the callback for both of the above, I send the values to one PassthroughSubject.
  • Then, I have a publisher for each of the characteristics based on the PassthroughSubject mentioned above, filtering out the required characteristic and deserializing data.
  • Then I combine latest values of all of these streams to build the model instance containing all the values

from littlebluetooth.

DrAma999 avatar DrAma999 commented on September 24, 2024

@NeverwinterMoon
So basically you opened a pandora box :-D , and I'm glad that you did.
The problem is more profound and really deep into the architecture, basically now my library is safe to be used only if you make operations synchronously as in the example.
The main problem is due to nature of cold publisher of most of combine's publishers.
I'll make you an example when you combineLatest two publishers you basically trigger them to start simultaneously this had some impact on characteristics recognition, but most importantly on reading and writing.
In the pipelines I've put some checks to see for instance if the characteristic you requested is the one that has been sent from the device. Now that we have 2 publishers with different characteristics the pipeline receives 2 values. One is battery and one is speed, depending on which one is sent before the code breaks.
Same happens for reading requests for a specific type, one of the 2 is not the same type you requested in one of your reading, and it breaks.
I'm trying different approaches: one is acting on the back pressure in these way each read is executed until the end and they can be combined together basically I will force a sync process. The other is trying to figure out if I can filter them( by matching characteristics and type).
I really grateful for your suggestion and this bug. I'm pretty sure I will find a solution :-D

from littlebluetooth.

DrAma999 avatar DrAma999 commented on September 24, 2024

I guess that I've was able to fix the issue.
Thank you,
Andrea

from littlebluetooth.

Related Issues (9)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.