createAnonymousRoutesAsync() confuses DataProcessor

As far as I can tell, I stumbled over a firmware-bug. Or at least I am very confused about that behavior and hope that somebody can help me out :)

I am using a MetaMotion R with version 1.4.5. It seems to me that using createAnonymousRoutesAsync(), scrambles with the board state.
When I have the following code, everything works fine:

public void bug1(MetaWearBoard board) {
    board.getModule(Settings.class).battery().addRouteAsync(source -> source.limit(Passthrough.COUNT, (short) 0).name("battery_log").log(null))
    .continueWith(task -> {
        try {
            board.getModule(DataProcessor.class).edit("battery_log", DataProcessor.PassthroughEditor.class).set((short) 1);
            board.getModule(Settings.class).battery().read();
        }
        catch (Exception e) {
            Log.d("board", "Crash!");
            e.printStackTrace();
        }
        Log.d("board", "Success!");
        return null;
    });
}

But adding a createAnonymousRoutesAsync() in between, leads to a ClassCastException:

public void bug2(MetaWearBoard board) {
    board.getModule(Settings.class).battery().addRouteAsync(source -> source.limit(Passthrough.COUNT, (short) 0).name("battery_log").log(null))
    .continueWithTask((Task<Route> task) ->  board.createAnonymousRoutesAsync())
    .continueWith(task -> {
        try {
            board.getModule(DataProcessor.class).edit("battery_log", DataProcessor.PassthroughEditor.class).set((short) 1);
            board.getModule(Settings.class).battery().read();
        }
        catch (Exception e) {
            Log.d("board", "Crash!");
            e.printStackTrace();
        }
        Log.d("board", "Success!");
        return null;
    });
}

It doesnt seem to make a difference if the results from createAnonymousRoutesAsync() are subscribed to or downloadAsync() is called. As soon as createAnonymousRoutesAsync() is used, "battery_log" in the DataProcessor does not seem to exist anymore. Everything works fine if I call createAnonymousRoutesAsync(), disconnect and reconnect from the board.

Am I doing something wrong here?

Thanks for your help!

Comments

  • Why are you creating an anonymous route with the object that created the original logging route?

  • edited October 7

    @Eric said:
    Why are you creating an anonymous route with the object that created the original logging route?

    I am not. I just simplified the code as much as possible and created a showcase to shed light on behavior I dont really understand :)

    In our app all these steps (creating the DataProcessor, loading the battery state and downloading the data) are used at different points in time.
    The main reason why I am using an anonymous route is because I need to make sure that all data are downloaded even when the board was programmed by another phone.

    This crash is problematic for us because this "error" is also serialized when using board.serialize(). This means that when we download data from the board and then serialize its current state, our app will crash every time the battery state is checked, even after disconnecting the board for a while. Even worse, a second call to createAnonymousRoutesAsync() will crash as well, meaning that no more data can be downloaded without fully resetting the board.

    Is there a reason for that crash and is there a way to avoid it?

  • Anonymous routes are solely for downloading data. If you have the object state available, serialized or original object, you don't need anonymous routes.

  • edited October 9

    I know, but as far as I understand, anonymous routes are the only way to download data that was not programmed by the current phone (which is something our app needs to be prepared for). And it also gives me the option to check which data will be downloaded (by checking the identifier-strings), before I initiate the actual download by calling downloadAsync().

    The code I posted is just a very simplified test. I don't use this code in our app. I just created it to showcase the cause of the problem.

    As far as I understand, createAnonymousRoutesAsync() only checks for existing downloadable routes and does not change the state of the board.
    So, calling createAnonymousRoutesAsync() should not be able to influence if board.getModule(DataProcessor.class).edit("battery_log", DataProcessor.PassthroughEditor.class) crashes or not. But it does.
    That is why I think it must be a problem with the firmware. Or am I overlooking something?

    It should be impossible that the catch block in the following code will ever be reached, right? But it does so on several different boards. Why?

    public void bug(MetaWearBoard board) {
        board.getModule(Settings.class).battery().addRouteAsync(source -> source.limit(Passthrough.COUNT, (short) 0).name("battery_log").log(null))
            .continueWithTask((Task<Route> task) -> {
                if(task.isFaulted())
                    throw task.getError();
                return board.createAnonymousRoutesAsync(); //replace me with "return null;" and no crash will happen!
            })
            .continueWith(task -> {
                if(task.isFaulted()) {
                    Log.d("board", "There were preceding errors. Abort!");
                    return null;
                }
                try {
                    board.getModule(DataProcessor.class).edit("battery_log", DataProcessor.PassthroughEditor.class).set((short) 1);
                    board.getModule(Settings.class).battery().read();
                }
                catch (ClassCastException e) {
                    Log.d("board", "This crash should be impossible!");
                    e.printStackTrace();
                    return null;
                }
                Log.d("board", "Yay! No crash happened.");
                return null;
            });
    }
    

    (Again I dont intend to use this code, I just want to figure out why it is even able to crash)

    Thank you for your help!

Sign In or Register to comment.