-
I'll admit that this threw me off a bit too at first.
It does appear that there is some inconsistency in the standard app UIs as to what Back does, which is unfortunate since it probably makes things more confusing than they could be. For instance, in the Alarms app, going to the menu to create a new alarm or timer, then immediately tapping Back without making changes, immediately creates a new alarm or timer with default settings, which isn't really what I personally would expect to happen. I'd expect the operation to be canceled, or perhaps a prompt asking whether I meant to save the new item. But then in most other places, Back actually does cancel the changes rather than confirming them. It's not really obvious which “rule” is in effect on a particular menu.
In the case of the number-changer screen, perhaps having an OK button on Bangle 2 to set the value would be a bit more intuitive, assuming there is space for it.
-
Thanks! That seems to work. Darn, I had a back-of-the-mind thought about trying the offline compiler but really didn't expect it to change anything. Looks like I was wrong.
Should we update
dane_arwes.js
as well? I'm not sure what uses that, but its correspondingdane_arwes.min.js
also appears to have a mismatched commit/timestamp. This looks like the only other minified file inmodules/
that I can see. -
I'm having some confusion regarding the Layout library: I suspect the version of the code in the current emulator and my Bangle.js device does not match what I see in
master
on GitHub, and I'm not clear on how versioning works. The docs seem to say that the current version of modules are supposed to be automatically loaded from the app loader, but I seem to still have a version of Layout.js that is almost a year old despite having used my fork of the development app loader definitely much more recently than this.Then I happened to notice in the BangleApps repo that there is a Layout.js and a Layout.min.js file, and the latter is several months older than the former, the former containing the functionality I was looking for but in fact I'm guessing the older minified version is in fact the version that is actually getting deployed. I can confirm this by manually installing the non-minified version into the IDE emulator under a different name (different because apparently if I use “Layout” the built-in version still takes precedence), and I see that the specific behavior of the newer code then works.
Assuming someone simply forgot to update the minified files when making changes, I was going to use EspruinoDocs/bin/minify.js to update the minified modules and PR the update, but I can't get the minifier to work for Layout.js (though I've successfully used it for other files). I get errors I don't really understand; I guess the script doesn't understand the result from the Closure compiler. I've attached the full output log of the minify script.
If anyone could shed some light on how this works or let me know if I'm barking up the wrong tree somewhere that would be great.
-
That's odd - how exactly were you listing files?
I was seeing the duplication both in the app loader's app list and when browsing the Storage files in the IDE.
I can't be exactly sure when I first noticed it, but it was pretty soon after unboxing. I think the very first thing I did upon plugging it in to charge and powering up was to update the firmware (since the app loader suggested it). I think the old FW was 2v16 or 2v17, can't remember for sure, and I installed 2v18. I think I tried installing apps directly after that.
Anyway, I noticed that the duplicate files did not appear in the ZIP produced by the backup feature, so I tried what you said and made a backup and restored it, erasing storage before the restore. Everything seems intact but with only one “sched” app instead of two, so it seems that solved it.
-
The codes in the debug log definitely look like terminal escapes, though I'm not sure exactly what formatting they're for. Normally colors and formatting aren't that essential, but perhaps other characters in certain output might be important. If it is just the same output that the left pane in the IDE would display, I wonder if it would make sense to have a button or tab shortcut there for viewing the contents of the debug log using the same VT100 interpretation of escape codes. I'm not sure if the debug log file is an Espruino- or just Bangle-specific implementation, but it seems like a quick-view feature could be a handy debug tool.
The BLE interval makes sense. That would also explain why the response in the console sometimes seemed a little laggy for a moment. Checking the running app is a good point; I should have thought of that but didn't. I've mainly been using Timer Clock as the clock, but I just tried it with the default Anton clock and the first page of Settings and didn't notice any difference in behavior—it still happens the same.
I played with setConnectInterval and do notice that any interval higher than about 100ms seems to consistently reproduce the bad behavior. Lower intervals work okay. So far it seems that this is the only thing that causes the weird behavior.
Yes - this is more laziness in implementation I think. The text is added to the filename in the Storage window so you can see that the files are different (as this can be important), but then when saving the original filename should really be used.
Although... I have to juggle a lot of stuff with Espruino - it is literally just me working full time on this - and it's unlikely I'll get time to put in fixes for all this stuff. If you'd be willing to jump in and make some fixes, that'd be great - as with the app loader you can just fork the IDE and host your own copy with GitHub pages for development if that's easier than having a local serverUnderstandable. I'm kind of overwhelmed with various ideas myself and it's hard to decide what to do when. :) It looks like the priorities are in the right places, though, as the important underlying functionality seems pretty solid. Most of the things I'm encountering are fairly minor UI/polish type stuff, and that can always be fixed. I may consider taking a stab at some of it at some point.
-
Oof… I just posted the pull request, but I just realized something else that bothers me. In the Health UI, movement data per hour frequently measures above 255, even though the DB field for it is only uint8, so I think it must be adding together all of the values per hour. My PR generates the daily summary by averaging everything instead, so it still looks a bit low compared to the by-hour graph.
The daily summaries alone should at least still be useful for comparing with themselves, but they wouldn't be appropriate for comparing with the hourly values shown on the graph. I guess in that case one way to make them consistent would be to add up the values per hour, then average the hourly values? That's a bit more complicated. I'm not really sure what the right thing to do here is, given that it doesn't seem well defined what exactly the “movement” metric and its summary means, apart from being a somewhat arbitrary reference.
-
Quite likely it is binary (or maybe even UTF-8 now?) = there is some non-ASCII byte there. Often there is a button there to switch to text mode, maybe it should be there always (currently it is not).
There are what look like random escape codes in the tracebacks and such, which look like formatting codes for terminal emulators. But they're not really that useful for a written .txt log in a file, given that they confuse programs.
The only button I get is for “decode JS”, but that doesn't seem to do anything in this case. Having a way to force it to treat the file as text would be helpful, though, especially in cases like these where I know it really is text with just a couple of stray rouge bytes that can be safely ignored.
Which OS or browser it is? On Windows in Chrome it definitely adds just .txt
For some reason on Ubuntu and Chromium it wants to add the string “ (StorageFile)” to the end of the filename, which confuses the system file save dialog. I can rename it but it's annoying. That's what displays in the storage list in the UI, too, but I'd argue that the “(StorageFile)” prefix should be dropped in the suggested filename when saving (or else placed just before the extension, or at the very start of the name or something).
It may be out of memory (or low stack?) situation. Maybe some app that use lot of memory/stack is running? Do you see some error or exception message in the 'dump of strings' or series of dots inside of (json) output?
It doesn't appear that there is a memory issue. There are no errors or exceptions, either, just the list of strings. However, I am starting to notice the pattern: It seems to happen consistently if the watch has been idle for a minute or so before I request the list. If the Bluetooth link was just active, it works fine, but after a couple of minutes, the odd delay and strange behavior occur, only for it to work fine if I immediately try again. It sort of makes me wonder if it could have anything to do with power management on the Bluetooth link somehow causing problems.
I happened to catch this in the IDE error log when it happened:
>>> Receiving... WARNING: No result found for "require('Storage').list().forEach(x=>print(JSON.stringify(x)));" - just got "< <<\r\n\".bootcde\"\r\n\"launch.app.js\"\r\n\"launch.settings.js\"\r\n\"launch.info\"\r\n\"antonclk.app.js\"\r\n\"antonclk.img\"\r\n\"antonclk.info\"\r\n\"about.app.js\"\r\n\"about.img\"\r\n\"about.info\"\r\n\"widlock.wid.js\"\r\n\"widlock.info\"\r\n\"widbat.wid.js\"\r\n\"widbat.info\"\r\n\"welcome.boot.js\"\r\n\"welcome.app.js\"\r\n\"welcome.settings.js\"\r\n\"welcome.img\"\r\n\"welcome.info\"\r\n\"health.img\"\r\n\"health.settings.js\"\r\n\"setting.img\"\r\n\"sched.bo" >>> getFileList TypeError: Cannot read properties of undefined (reading 'trim')
Which clearly looks like the data it received is being interrupted somehow (although I then get what looks like an untruncated dump of it in the debug pane, whereas normally when it works correctly nothing at all appears there except a new prompt).
As far as I know, I haven't seen other issues when doing other actions after such inactivity (such as sending/receiving apps with the App Loader, etc.) Just the storage list in the IDE.
-
I notice that when I list my apps on my Bangle.js 2 the
sched
app/library in particular shows up twice, the same version number in both instances. If I look at the list of storage files, I see that each file making up thesched
app similarly appears in duplicate (that is, each filename of that app appears twice in the list). I was wondering if there was some reason for this. As far as I know, it's been this way ever since I received the watch new. -
I encountered a couple of slightly annoying things working with the IDE today and was wondering if these were known issues. I wasn't sure if I should post here on the forum first or open issues on GitHub, but here's a brief description of each:
The first is that viewing the Bangle.js debug log (which seems to be written to storage file
log.txt
, if I'm not mistaken) is quite fiddly because the IDE insists that it's a binary file when it should be text. The hex dump is not helpful (nor does it help that the window appears too narrow in my browser to display properly even though there would be plenty of space), so I'm forced to save the file and then open it manually in a text editor. Further complicating matters is the fact that the default filename lacks the correct extension (it'slog.txt (Storage file)
instead of something ending in.txt
), and renaming it adds an additional unnecessary step to the process. Ideally, a file ending in .txt should be just that, and it should open as text in one step without a hassle.The other one is a bit weird, and I'm not sure how to debug it. Occasionally (I haven't been able to discern any particular pattern) when my watch is connected to the IDE and I click the Storage button, the list of storage files fails to appear. Instead, I only get a Send to RAM button and then a dump of strings representing the names of my storage files on the debug pane an instant after the dialog window pops up. Another possible clue is that when this happens there is usually a delay of a couple of seconds, which is longer than it normally takes. If I cancel and try again, it usually works fine, but before long the glitch crops up again.
-
So just as an experiment, I applied a quick hack to the health app on my watch to avoid the double-division to see what would happen. Toward the end of the day I got a daily summary “movement” value in the Health app of about 49. In the debug console I grabbed the log of hourly health data for that day and manually averaged it to compare:
movCnt = 0; movTot = 0; require("health").readDay(new Date('2023-07-27'), (data) => { movCnt += 1; movTot += data.movement; }) movTot / movCnt
and finally got a value that agreed with the written summary for that day, 49.41666666666. This is after making both code changes that I mentioned above, having the Health summary code read the correct byte of the record, and also not dividing the already-divided result when calculating and writing the summary.
I don't want to be too quick to assume things since I'm new here and don't know about all of the design decisions that might have been made, but so far this does seem to confirm my above suspicions. If it is a bug, I'm up to seeing if I can try to put together a pull request.
-
I'm trying to wrap my head around how the movement data tracking works in the health app. The figures in the hourly data make sense, generally ranging from, say, 50 to 800 depending on the amount of movement, but the daily averages for the same metric don't. I'm getting values for each day like 6, 8, 8, 8, 8, 8, etc—definitely not an arithmetical average. That seems fishy to me.
So I'm digging deep into the Health app code and trying to understand how the data is being calculated and written to the underlying DB. The first thing I notice is this part where it writes the daily summaries: I think it's reading byte 2 of the record for movement data, but that seems to be the same byte that it's reading for heart rate data? Other places in the code use byte 3 for movement instead (and 2 for HR), so I wonder if I missed something or if that's actually a bug.
So I tried modifying this code to what I'm guessing it should be, but it doesn't seem to change the result much. Yesterday's movement summary was still just 6. Looking a bit deeper, though, I see the definition of getRecordData(), which bundles the data up into a DB record for writing, and it divides the movement data by 8 before writing. But that gets called twice. I might be reading the code wrong, but it seems like it's doing that when writing normal records (every ten minutes?), but then it gets called again when doing the summary… So I'm wondering if maybe it's accidentally doing the division twice, once for the initial data and then again when averaged for the day (meaning the dailies are now divided by 64 while the hourly is only divided by 8). Which isn't a difference I would expect to see in the user-facing interface when comparing hourly vs. daily data.
If anyone could shed some light on this or confirm/debunk what I'm thinking, that would be helpful.
-
I see. Since most apps don't have that many files, I guess it's not that bad yet.
I have noticed in many cases it does seem simpler to just directly modify an app file on the physical Bangle's storage, especially when I just want to do some longer-term testing of a small tweak in a larger app (and that change may involve a library file that's not meant to be run directly from RAM anyway).
It would indeed be nice if the IDE remembered the source of the file I selected so that it could be written back to its source without having to manually locate and reselect the destination in the list. That would also reduce the chance of accidentally overwriting the wrong file on the device by clicking the wrong name.
It would also be more ideal to have the buttons like “Copy to code editor” accessible immediately without having to scroll all the way to the bottom of the file first to reach them.
Update: By the way, I worked out getting my own personal App Loader fork on Github and testing and pushing experimental changes to apps to my watch from there. It looks like I can do the same with the IDE too if I ever want to tinker with the code. Anyway, just posted my first small PR for BangleApps. :)
-
Thanks! Yes, that's what was happening. I did a force-reload on both browsers and now it's working.
Is there a simpler way to get apps into the emulator which don't have an emulator button in the loader? Unfortunately, one of the first apps I wanted to tinker with seemed to turn out being one of the more complex ones out there (unbeknownst to me at first). It took a while, but I eventually worked out how to manually load each of the app's files into storage with the proper name prefixes, but then it used a module and I had to figure out exactly where that should be stored. To be fair, that turned out being in the documentation somewhere, but for some reason I had some trouble finding the correct info with Google, so it was a little frustrating. In the end, I got it working, though to reload the app I had to use a manual command in the debugger window as it gets stuck on a “Loading…” screen with no error messages if it tries to reload itself—haven't worked that part out just yet. Maybe something to do with the emulator defaulting to not having any of the usual apps installed that the physical Bangle.js ships with?
Anyway, it makes me wonder if I'm missing something more obvious, as this workflow seems a bit more clumsy and long-winded than I was expecting. On the upside, I think in the process I'm starting to get a better context of how the Bangle.js system and apps are structured, so that should help. :)
-
Hi all,
Just got a Bangle.js 2, been spending some time playing around with some apps, and looking forward to eventually seeing what kind of hacking I can do on it. :)
But right now, I cannot for the life of me figure out how to test apps in the emulator. The only docs I can find seem to make it sound as simple as clicking the emulator button for that app in the App Loader, but… evidently not. I click the button, my browser opens the Espruino IDE with an emulator window, but I can't get anything to happen. The emulator window just shows a splash screen, I click and drag every conceivable button and part of the UI but cannot get anything to happen no matter which app I try to test.
I can paste some little tutorial examples into the IDE and those run, but how on Earth do you load an app from the App Loader, view the code, and run that? All I get is a tab with a comment that says “Loading from ”, but no code and no response.
Tried this on both Firefox and Chromium on Ubuntu 20.04 and had the same results. I suppose I could try to install Chrome and test that if I had to, but all the other features (including App Loader connection and transferring apps to my real watch) seem to work fine in Chromium.
Anyone know what I'm missing? I've been up and down Google and every Espruino and tutorial I can find and nothing seems to explain how to actually get the “try in emulator” thing working in any kind of detail.
I estimate that I'm typically getting up to around 2 weeks regularly wearing the watch with:
which seems pretty reasonable. In practice since I use the watch as a daily driver I normally charge a bit more often than that to avoid the battery dying at a bad moment. Since the battery meter tends to hang out around 9–10% for a long time it's hard to be sure what the true max runtime would be without risking that; I consider that level as a sort of “charge as soon as possible” low-battery signal.
I do notice that long use of timers that update in 0.1-second intervals tend to drain the battery particularly rapidly. (At least one app seems to do such updates only when the screen is awake/unlocked and then cuts back to once per second, which seems like a good idea.) But occasional use of once-per-second displays for a few hours here and there doesn't seem to hurt overall runtime too badly.