Banglerun with a custom mobile app

Posted on
  • Hi everyone,
    i'm trying to use Bangle.js in a university project.
    I state that I have never programmed in javascript before, but i have experience with python and C#.
    I'd like to modify the app Banglerun, in order to send measured data to a mobile app made by me, that uses them to produce charts and things like that.
    But it's very hard to do that due to the way it is implemented, it's in typescript and the file app.js is a single line code illegible and not editable. How can i do that?

    p.s.
    I tried to use vscode but i can't solve errors that occurs, so i have to use Espruino ide that doesn't support typescript.

  • Yes, sorry about that - the Banglerun app is literally the only app in the app store that's written in this way, and you're not the only one to find it difficult to modify.

    What did you actually want to do with your mobile app? Stream the data live, or retrieve recorded data?

    As I understand it the BangleRun app actually creates a log of each run anyway: https://github.com/espruino/BangleApps/blob/master/apps/banglerun/src/log.ts#L25

    So you could actually just connect to the Bangle and grab the data from each run even without having to modify the app.

    In fact if you were happy to write a webpage (progressive web app) to retrieve the data (rather than a native phone app) then you could use the interface.html from the GPS recorder app https://github.com/espruino/BangleApps/tree/master/apps/gpsrec as a starting point - it has most of what's needed to list files, read data and dump it - so you just need to interpret the slightly different BangleRun data which has a few more columns.

    If it helps there's even code to graph stuff here: https://github.com/espruino/EspruinoApps/blob/master/apps/bletemplogger/interface.html

  • What did you actually want to do with your mobile app? Stream the data live, or retrieve recorded data?

    I'd like to stream data to my app and create some live charts, like HR one and intensity excercise one, but also save them in order to see these charts after the run.
    I saw in the code that the app creates a log of each run, so for that task it's easy, but i need also to implement data streaming for the project (it is one of the task asked). Initially i wanted to write the app by myself, but reading the typescript code of banglerun it's well written, also in terms of measurements, with the kalman filters to noise reduction, so i decided to modify it in order to stream data, that is why i wanted to use vscode.
    Do you think it is possible to modify the file app.js by hands, making it readable? @Gordon.

    If it helps there's even code to graph stuff here:https://github.com/espruino/EspruinoApps­/blob/master/apps/bletemplogger/interfac­e.html

    Thank you very much, it will be very usefull in future work.

  • Well, it might be possible to modify the file by hand, but if there's any way to avoid it I would!

    I just did:

    npm install rollup  rollup-plugin-typescript rollup-plugin-terser typescript
    rollup -c
    

    And it generated app.js, so I'd definitely try doing it that way if you can make it work

  • I'm trying to do that, but i don't understand how this can fix the way app.js appers. I've nevere used before rollup, i'm reading now the documentation, but running

    rollup -c
    

    gave me errors.
    Otherwise, running rollup app.js it seems like is rollup to generate app.js in that way.
    Maybe i misunderstood what you said, but i keep trying to fix this, if i solve, will publish the code of corrected file in this conversation.

    Thank's you @Gordon.

  • Ok i think i found a way to modify the app, it is a little bit twisted but it should work. I'm going to explain how for future people that will might have the same problem.
    After installing all the package nedded (see preavious posts to understand), you can modify the code inside \src folder. After that, running the rollup.config.js file in that way:

    rollup --config  rollup.config.js
    

    it will be created a new file app.js with your modifications. After that, the file app.js can be copied and pasted in Espruino IDE and finally runned in bangle.js.

    I don't know id it is the best way to do that but it works.

  • Great, glad you got it going! I think that's the correct way of doing it.

    I'm surprised rollup -c didn't do it for you though

  • Hi all,

    I'm the developer of BangleRun... Sorry to have missed this discussion, but I'm glad that you managed to modify the app anyway :)

    I used typescript and rollup because:

    1. strong typing helps me a lot (especially for not-so-simple projects like this app)
    2. it's the language I'm more familiar with, and
    3. the plain javascript code was too big to fit in memory during runtime.

    The app started as a weekend project, and then became something more... I wasn't expecting much interest from other people, but now it's probably time to document the thing a bit and add at least a README file on how to compile it :)

  • Thanks - a README for it would be awesome actually :)

  • Sorry for returning to this post after months, I'm back on the project, and now I need to modify banglerun to accomplish my task. I added a new src page in the code, where I'd like to establish a BLE connection with my smartphone app. My problem is that I can not run the code because NRF.setService for example gives me an error. Do I have to add some extensions? Do you have some advices to do this ? @Gordon

  • @valap95 I can't be much help without knowing what the code or error was - maybe you could post up in a new Thread?

    However have you considered just connecting from your phone to Bangle.js using the standard Nordic UART service that's implemented in the Bangle? (eg https://www.espruino.com/Interfacing#bluetooth-le)

    You can then just send JS commands to control the app. While the code in the BangleRun app is all minified, you could add code like Global.myFn = function...., then you can call this code just by sending the text "myFn('some data')\n" down the UART connection

  • hi @Gordon,
    I added this typescript code to banglerun:

    import { AppState} from './state';
    
    declare var NRF: any;
    
    function startStreaming(state:AppState):void{
     
        SetServices(state);
    }
    
    
    //Setto i servizi per preparare la connessione 
    function SetServices(state:AppState){
      NRF.setServices({
        // activity services
        'f8b20001-89ad-4220-8c9f-d81756009f0c': {
            'f8b20002-89ad-4220-8c9f-d81756009f0c': {
            descriptio: 'duration',
            notify: true,
            readable: true,
            value: []
          },
          'f8b20003-89ad-4220-8c9f-d81756009f0c':{
              description: 'distance',
              notify:'true',
              readable: 'true',
              value: [0]
          },
          'f8b20004-89ad-4220-8c9f-d81756009f0c':{
            description: 'speed',
            notify:'true',
            readable: 'true',
            value: [0]
          },
          'f8b20005-89ad-4220-8c9f-d81756009f0c':{
            description: 'steps',
            notify:'true',
            readable: 'true',
            value: [0]
          },
          'f8b20006-89ad-4220-8c9f-d81756009f0c':{
            description: 'cadence',
            notify:'true',
            readable: 'true',
            value: [0]
          },
    
    
        },
        //HR services
        
        'f8b20007-89ad-4220-8c9f-d81756009f0c': {
            'f8b20008-89ad-4220-8c9f-d81756009f0c': {
            description:'HR',
            readable: true,
            notify: true,
            value : [0],
        }
      }       
    });
    UpdateServices(state);
    }
    
    
    
        function UpdateServices(state: AppState): void {
          NRF.updateServices({
            // activity services
            'f8b20001-89ad-4220-8c9f-d81756009f0c': {
                'f8b20002-89ad-4220-8c9f-d81756009f0c': {
                descriptio: 'duration',
                notify: true,
                readable: true,
                value: [state.duration]
              },
              'f8b20003-89ad-4220-8c9f-d81756009f0c':{
                  description: 'distance',
                  notify:'true',
                  readable: 'true',
                  value: [state.distance]
              },
              'f8b20004-89ad-4220-8c9f-d81756009f0c':{
                description: 'speed',
                notify:'true',
                readable: 'true',
                value: [state.speed]
              },
              'f8b20005-89ad-4220-8c9f-d81756009f0c':{
                description: 'steps',
                notify:'true',
                readable: 'true',
                value: [state.steps]
              },
              'f8b20006-89ad-4220-8c9f-d81756009f0c':{
                description: 'cadence',
                notify:'true',
                readable: 'true',
                value: [state.cadence]
              },
        
        
            },
            //HR services
            
            'f8b20007-89ad-4220-8c9f-d81756009f0c': {
                'f8b20008-89ad-4220-8c9f-d81756009f0c': {
                description:'HR',
                readable: true,
                notify: true,
                value : [state.hr],
            }  
          }     
        });
     }
    
    

    this code, when the app starts, set services, and when you press start button should start to update value. But when I run the code i obtain this error:


    1 Attachment

    • fileErr.PNG
  • The BLE Connected message isn't actually an error - it's just letting you know that you need to disconnect + reconnect for the services to appear.

    It looks like Execution Interrupted happened just because your code (or other widgets installed) used so much memory that Bangle.js ran out and had to stop execution

  • Hi @Gordon,
    I've just implemented a code that allows to stream data via BLE (in my case to a mobile app developed for a specific task). Idk if it is interesting for you (in terms of adding this part to the original app) or others for private use, in any case, I post it in this post.

    import { ActivityStatus, AppState} from './state';
    
    declare var NRF: any;
    
    
    
    
    //Setto i servizi per preparare la connessione 
    function SetServices(state:AppState){
      NRF.setServices({
        // activity services
        'f8b20001-89ad-4220-8c9f-d81756009f0c': {
            'f8b20002-89ad-4220-8c9f-d81756009f0c': {
            descriptio: 'duration',
            notify: true,
            readable: true,
            value: [state.duration]
          },
          'f8b20003-89ad-4220-8c9f-d81756009f0c':{
              description: 'distance',
              notify:'true',
              readable: 'true',
              value: [state.distance]
          },
          'f8b20004-89ad-4220-8c9f-d81756009f0c':{
            description: 'speed',
            notify:'true',
            readable: 'true',
            value: [state.speed]
          },
          'f8b20005-89ad-4220-8c9f-d81756009f0c':{
            description: 'steps',
            notify:'true',
            readable: 'true',
            value: [state.steps]
          },
          'f8b20006-89ad-4220-8c9f-d81756009f0c':{
            description: 'cadence',
            notify:'true',
            readable: 'true',
            value: [state.cadence]
          },
    
    
        },
        //HR services
        
        'f8b20007-89ad-4220-8c9f-d81756009f0c': {
            'f8b20008-89ad-4220-8c9f-d81756009f0c': {
            description:'HR',
            readable: true,
            notify: true,
            value : [state.hr],
        }
      }       
    });
    
    }
    
    
    
        function UpdateServices(state: AppState): void {
          NRF.updateServices({
            // activity services
            'f8b20001-89ad-4220-8c9f-d81756009f0c': {
                'f8b20002-89ad-4220-8c9f-d81756009f0c': {
                descriptio: 'duration',
                notify: true,
                readable: true,
                value: [state.duration]
              },
              'f8b20003-89ad-4220-8c9f-d81756009f0c':{
                  description: 'distance',
                  notify:'true',
                  readable: 'true',
                  value: [state.distance]
              },
              'f8b20004-89ad-4220-8c9f-d81756009f0c':{
                description: 'speed',
                notify:'true',
                readable: 'true',
                value: [state.speed]
              },
              'f8b20005-89ad-4220-8c9f-d81756009f0c':{
                description: 'steps',
                notify:'true',
                readable: 'true',
                value: [state.steps]
              },
              'f8b20006-89ad-4220-8c9f-d81756009f0c':{
                description: 'cadence',
                notify:'true',
                readable: 'true',
                value: [state.cadence]
              },
        
        
            },
            //HR services
            
            'f8b20007-89ad-4220-8c9f-d81756009f0c': {
                'f8b20008-89ad-4220-8c9f-d81756009f0c': {
                description:'HR',
                readable: true,
                notify: true,
                value : [state.hr],
            }  
          }     
        });
     }
    
     export {SetServices,UpdateServices};
    

    I added this .ts file to the src folder in my fork of BangleApps and ran using rollup in vs code. Then I took app.js content and with it, I created my own app.

    Kind Regards

    Valerio

  • That's great - thanks! Are the services made to match anything in particular, or are they just custom services you created for your app?

  • They are custom services, that I read in my app. In that case, they pass to the app measures made by banglerun algorithm. If it can be useful i can share also the C# code that manages connection in my app.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Banglerun with a custom mobile app

Posted by Avatar for valap95 @valap95

Actions