-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Circadian Wellness Clock: Initial submission for review #3878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This pull request adds the initial version of the Circadian Wellness Clock app for Bangle.js 2. The app implements a wearable circadian rhythm scoring system for estimating biological time, based on physiological and environmental data. Features:
Authorship & Intellectual Property:
|
See notes on formatting the ChangeLog here: https://github.com/espruino/BangleApps?tab=readme-ov-file#changelog Example the messagegui app ChangeLog: https://github.com/espruino/BangleApps/blob/master/apps/messagegui/ChangeLog |
Hi @spycat111 - thanks for contributing! @gfwilliams would you be able to look at this one? There seems to also be something strange with the sanitychecker and I wont have the time to try and understand it for a while. |
Unfortunately, I don't know what I should fix based on Error: Process completed with exit code 7. However, I tested the app on my watch and it works. |
Yes - thanks for the fixes so far. I don't know either. Let's see if Gordon can look at it tomorrow. ☀️ |
I suspect that this might have been the issue which I fixed: "storage": [ |
Hi - you're right - the metadata doesn't have a The metadata in general looks like a very different format to what's expected though - see https://github.com/espruino/BangleApps?tab=readme-ov-file#metadatajson-format Or the example metadata for a clock is a good start: https://github.com/espruino/BangleApps/blob/111d80a8dea48fd5b9fcd39fe9f53e9a123e1062/apps/_example_clock/metadata.json So you have author/src/patent/changelog fields that you don't need and which might be causing problems - and the icon needs converting to JS. I've just pushed some changes to the metadata itself. But you'll have to add Out of interest, how did you come up with the contents of the metadata file? Was it AI? It seems it wasn't based on any existing apps... |
|
||
const uiOpts = { | ||
mode: "custom", | ||
clock: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this intentional? is this not meant to be a clock? Or you're doing this so that the button can be used to launch the menu
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is intentional. uiOpts.clock is set to false so the app can render a custom biological-time display and use BTN1 for its menu.
drawClock(); | ||
|
||
setInterval(() => { | ||
if (Bangle.isLCDOn()) drawClock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you probably don't care if the LCD is on as the Bangle.js 2 LCD always is?
I'd probably change this logic slightly - most clocks do: https://www.espruino.com/Bangle.js+Clock+Font#simple-clock
// schedule a draw for the next minute
function queueDraw() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
}
Which ensures that the clock will always redraw exactly on the minute - using a simple setInterval could mean the time shown is up to 59 seconds out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good (apart from needing the icon I mentioned) - I'd be a bit concerned that pretty much all clocks on Bangle.js go to the launcher when you press the button, but in this case you're overriding it to go to the menu?
Once this clock is installed, I'm not entirely sure how you're supposed to launch any other apps?
If you really need the button to show a menu and not immediately go to the launcher, maybe you could add a menu item that called Bangle.showLauncher()
(https://www.espruino.com/Reference#l_Bangle_showLauncher) so that users can launch other apps while using your clock?
Reply: Thanks for the feedback! Regarding the icon — I added a 128x128px icon, but it seems that might not be sufficient. Could you clarify what format or size is expected so I can adjust it accordingly? As for the BTN1 override: the reason I routed it to a custom menu instead of the launcher is due to the app’s complexity. It uses a significant portion of the watch’s resources, so it's designed to function as a standalone environment — potentially the only app installed on the watch. That’s why I prioritized keeping the menu accessible within the app context itself. That said, I understand the concern. I can still add a “Go to Launcher” option in the menu using Bangle.showLauncher() for flexibility, just in case users do have other apps installed. |
Thanks for catching that. I actually generated the metadata with AI, which explains why it drifted from the expected format. I’ll re-add the storage field, remove the extra fields (author, src, patent, changelog), and convert the icon to a 48×48 PNG before running it through bin/convert-icon.js to produce app-icon.js. I’ll align the JSON structure with the _example_clock/metadata.json example and push the update. |
Ahh - yes, I thought it might be AI. Increasingly I'm having stuff contributed written using it, and it's a complete pain to try and debug.
I already did that for you - so I think the JSON is all good.
Please just run the 48px icon through http://www.espruino.com/Image+Converter like that link says and I think everything should be fine. |
Thanks for sorting the JSON. I’ll export the icon as a 48×48 PNG, run it through the Espruino Image Converter, and commit the resulting app-icon.js. |
I just created app-icon.js and uploaded icon.png 48x48px. |
Thanks! Looks great - it just passed the tests! So I guess it's just adding the menu item for the launcher?
Actually the way Bangle.js works, adding extra apps won't actually reduce the memory available - when you run your app the device is 'yours' - if you go to the launcher or another app (unless your app explicitly says it's possible) Bangle.js tears everything down and restarts a fresh environment with that new app - so you shouldn't have to worry about making your app the only one on the device. Only slight exception to that is widgets (which you do use) so if more widgets are added then obviously they will use more memory as they're extra code that runs. Looking at your code if you do care about memory usage there's probably quite a lot you could do to help (like storing all your history data in Typed Arrays which are way more compact) - seems like right now you store time and the data value for each, but maybe if you know you're storing data every 10 minutes you don't need time? You can just keep it in an array and you know the 10th item is from 10*10 minutes ago? |
Thank you for the guidance. Here’s a concise summary and my planned update: What the code does now Storage & History: Buffers step, HR, light and sleep-start data in JSON files, batching writes every 5 min. CRS & Bio‐Time: Calculates a 0–100 circadian score from stability metrics and displays bio‐time by applying the user’s phase offset. Sensors & Alerts: Hooks into step, HRM, light sampling and sleep/hydration logic to log data and show alerts. Rendering: Fully custom draw routine (clock:false) that paints bio‐time, CRS, steps, mood and light hours, plus a footer hint. Menu/UI: BTN1/tap/swipe opens menuOpts, which currently includes Stats, Trend, Sleep Window, Hydration, Calibration, Export, Theme, About, Reset and Exit. Proposed change "Go to Launcher": () => Bangle.showLauncher(), placed alongside the existing items in menuOpts. This ensures users can return to the standard app launcher without any other modifications. |
I've added a new touch-menu entry, "Go to Launcher" |
Thanks! @thyttan how do you feel about this? I'd say it's good to merge now? |
Please go ahead 🙂👍 |
Just to verify... there's royalty-free, worldwide patent grant, so this is still free software? |
Thanks for checking. As stated in the README, the code is released under the MIT license unless otherwise noted. However, please be aware that the underlying method is part of a UK patent application (GB2509149.7), and the use of the patented process may require permission or licensing. If you're planning to build on or distribute it beyond personal or experimental use, feel free to reach out. |
After installing the app via the development app loader I ran into a couple of show-stoppers: neither the BT calibration menu nor the sleep-window settings will actually apply, and instead I see garbled characters or odd behavior when I try. Interestingly, when uploading the same script directly via the Web IDE these issues do not occur, which further suggests the problem lies in the loader/minifier/firmware pipeline. On digging into the generated crsclock.app.js, it looks like non-ASCII punctuation in the source is being mangled by the Espruino minifier/firmware: Unicode minus sign (U+2212) in the BT calibration menu (around lines 612–614 in crsclock.js) causes the minifier to emit a malformed regex, leading to: javascript I suspect that mixing these Unicode dashes with plain ASCII hyphens is what’s breaking both parsing and display. I’ll follow up to replace all instances of EN DASH and MINUS SIGN with the standard ASCII hyphen-minus (-) so that the minifier and Bangle.js firmware handle them correctly. Let me know if there are any objections or additional edge cases I should watch out for! — Sleep window string using EN DASH (lines 84–86) Unicode minus sign in BT calibration menu (lines 612–614) Prompts using EN DASH for ranges (lines 714 & 723) |
I don't believe we should have patents limiting software use. People expect to download BangleApps and use them according to the license. I believe this should be dropped from the repository. |
Thanks for your message — I understand your position, but I want to be clear about mine as well. The app is released under the MIT license and is free to use. It also implements a method described in a UK patent application. This doesn’t impose any royalty or restriction for non-commercial or personal use, especially within the open-source context of Bangle.js. This is a prototype of a larger system I’ve been developing over the past few months, and the patent exists to protect that work — not to restrict open use or experimentation. I believe users have the right to be informed if patented methods are used, just as I have the right to share my work under clear terms. I hope that clarifies my position. |
Thanks for spotting the issues - I'm surprised you didn't encounter the problems in the IDE as it uses the same pipeline, but maybe pretokenisation was disabled in the IDE. I'll see if I can get a fix in for the tools/IDE today although obviously for something like a hyphen non-unicode is preferable anyway. Ideally when you submit an app you get it working in your own fork of the app loader first (info here) and then issues like this are less likely to get happen (and the CI tests help you catch issues) - but I know this is your first submission. On the Patent front, I think we're ok (if it weren't MIT I think we have an issue). Obviously I'd prefer anything posted here to be free in every sense of the word, but at the same time it's good to be able to try out new things and also support research/new companies. My concern would be that it would open us to legal action from the patent holder but as being as you're the patent holder and are submitting it, I think that's unlikely! I should add a warning though: There's no click-through license (nor would I want an app that needed one) when someone installs an app there's no guarantee they read that bit in your README about non-commercial and personal use - so policing the use of it would be entirely up to you (if that's a problem then it might be best not to have this app listed). ... also the MIT license does explicitly allow commercial use of the software, so there may be some conflict there. But in a way that's not our problem - if you're fine with that @spycat111 then I'm ok with it too. |
Thanks for the thorough response! Just to clarify, I’m not trying to impose any restriction—I’d simply be interested to know how the app is being used in the real world, purely out of curiosity, and for future development insight. It’s not about policing or enforcing anything. But if people don’t read that part of the README, that’s totally fine, too. Appreciate your openness on the patent topic and the balance you’re striking for the ecosystem here. And thanks again for your help with the character issue and the app loader advice! |
This PR adds the Circadian Wellness Clock app for Bangle.js 2 (Author: Jakub Tencl).
App features:
Request:
Thank you!