You know Pebble Clay, but have you heard of Rebble Clay? The new revived pebble-package helps you configure your apps on all platforms, including Flint! Help us test the new package by replacing pebble-clay in your package.json with @rebble/clay. https://www.npmjs.com/package/@rebble/clay
Any other differences between pebble-clay and @rebble/clay other than Flint support? And any plans for further changes?
Not right now, the most important parts for now were to make sure it builds and works on all the existing platforms. I do have some improvements in mind, if you find anything you want for yourself, let me know, I might be able to include it in the future releases!
Wonderful to see!
I’m trying this out on my moto maker watchface - it will build when I s/"pebble-clay": "^1.0.4"/"@rebble/clay": "^1.0.4", but fails to build when I add ”flint” to my ”targetPlatforms”. Here is my build output:
pebble clean && pebble build
lavender@orpheus /m/c/U/p/O/D/p/MotoMakerFace (master) [1]> pebble clean && pebble build
'distclean' finished successfully (0.013s)
up to date, audited 2 packages in 553ms
found 0 vulnerabilities
up to date, audited 2 packages in 464ms
found 0 vulnerabilities
Setting top to : /mnt/c/Users/pigge/OneDrive/Documents/pebble-projects/MotoMakerFace
Setting out to : /mnt/c/Users/pigge/OneDrive/Documents/pebble-projects/MotoMakerFace/build
Checking for program 'webpack' : /home/lavender/.pebble-sdk/SDKs/current/node_modules/.bin/webpack
Found Pebble SDK for flint in: : /home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/flint
Checking for program 'gcc, cc' : arm-none-eabi-gcc
Checking for program 'ar' : arm-none-eabi-ar
Checking if the -o link must be split from arguments : Traceback (most recent call last):
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Scripting.py", line 122, in waf_entry_point
run_commands()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Scripting.py", line 185, in run_commands
ctx=run_command(cmd_name)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Scripting.py", line 176, in run_command
ctx.execute()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Configure.py", line 86, in execute
super(ConfigurationContext,self).execute()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Context.py", line 92, in execute
self.recurse([os.path.dirname(g_module.root_path)])
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Context.py", line 133, in recurse
user_function(self)
File "/mnt/c/Users/pigge/OneDrive/Documents/pebble-projects/MotoMakerFace/wscript", line 23, in configure
ctx.load('pebble_sdk')
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Configure.py", line 158, in load
func(self)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/extras/pebble_sdk.py", line 117, in configure
configure_platform(conf,platform)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/extras/sdk_helpers.py", line 81, in configure_platform
ctx.load('pebble_sdk_gcc')
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Configure.py", line 158, in load
func(self)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/extras/pebble_sdk_gcc.py", line 16, in configure
conf.load('gcc')
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Configure.py", line 158, in load
func(self)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Tools/gcc.py", line 104, in configure
conf.check_gcc_o_space()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Configure.py", line 177, in fun
return f(*k,**kw)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Tools/c_config.py", line 802, in check_gcc_o_space
self.check(msg='Checking if the -o link must be split from arguments',fragment=SNIP_EMPTY_PROGRAM,features=features)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Configure.py", line 177, in fun
return f(*k,**kw)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Tools/c_config.py", line 386, in check
ret=self.run_build(*k,**kw)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Configure.py", line 177, in fun
return f(*k,**kw)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Configure.py", line 337, in run_build
bld.compile()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Build.py", line 167, in compile
self.producer.start()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Runner.py", line 271, in start
self.refill_task_list()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Runner.py", line 150, in refill_task_list
tasks=next(self.biter)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Build.py", line 416, in get_build_iterator
self.post_group()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Build.py", line 362, in post_group
tgpost(tg)
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/Build.py", line 359, in tgpost
f()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/TaskGen.py", line 123, in post
v()
File "/home/lavender/.pebble-sdk/SDKs/current/sdk-core/pebble/.waf3-2.1.4-e7919c666152db2545b931e52107c4b8/waflib/extras/pebble_sdk_common.py", line 85, in setup_pebble_c
append_to_attr(task_gen,'includes',[lib_include_node.abspath(),lib_include_node.find_node(str(lib['name'])).find_node(platform).abspath()])
AttributeError: 'NoneType' object has no attribute 'abspath'
Build failed.
Should this work as-is?
Ah, I might have built this on my local machine where I don’t have an sdk with flint support! That’s an easy fix though, let me push an update real quick!
1.0.6 wasn’t build on my computer, so it might work a bit better than 1.0.5 did! It’s already published if you want to try it
Dropped this into my watchface Thin, no issues so far! Thanks for taking the reigns on this one
Works for me, thanks.
If we can do feature requests here ![]()
-
add a property
“persistPerPebble“ : trueSo we can differentiate what would be stored based as general config (for example Celcius vs Fahrenheit) and what would be stored per watch (different color themes for different watches)
-
add
“capabilities“to the select optionsI currently need to define 2 selects for the same
messageKeyfor different types of watches, but sometimes only a couple of options differ. This always feels like a hacky workaround.
Not really a request to make but a comment about something I think would be a specific optimization I would like to look to make if it’s of interest if anyone else except my one use case.
Right now one of my apps extensively uses checkboxes and they 1 take up a lot of message keys (there are 100+ and growing) and 2 are annoying to deal with. I’ve already abstracted away some of it to make it easier for me but it’d be nice if I could have a checkbox group return as a single message key and just a value of packed bytes.
It’d take me from dealing with 100+ separate message keys back from Clay to a couple encoded values like QAEACQAgABg= to parse out. I might do it anyway after vacation but I’d care more if anyone happens to think it’d improve something for them too (or if someone else does it that’s a free win for me too!)
Oh I love the persist per watch, but it’s going to be difficult considering that all of the settings get stored in a single local storage key. Capabilities should be a bit easier for select options.
I will have to investigate this after new years. Thank you for the suggestions!
You could do this now by setting autoHandleEvents: false and constructing the message yourself.
I’ve finally taken some time to try this out. I’m using @rebble/clay at 1.0.6, SDK 4.9.77 on macOS with my default browser set to Safari.
Seems to work on my PT hardware, but in the emulator it throws and exception after a few seconds without opening the web browser.
➜ pebble emu-app-config
Traceback (most recent call last):
File "/Users/jr/.local/bin/pebble", line 10, in <module>
sys.exit(run_tool())
~~~~~~~~^^
File "/Users/jr/.local/share/uv/tools/pebble-tool/lib/python3.13/site-packages/pebble_tool/__init__.py", line 57, in run_tool
args.func(args)
~~~~~~~~~^^^^^^
File "/Users/jr/.local/share/uv/tools/pebble-tool/lib/python3.13/site-packages/pebble_tool/commands/base.py", line 47, in <lambda>
parser.set_defaults(func=lambda x: cls()(x))
~~~~~^^^
File "/Users/jr/.local/share/uv/tools/pebble-tool/lib/python3.13/site-packages/pebble_tool/commands/emucontrol.py", line 109, in __call__
response = self.pebble.read_transport_message(MessageTargetPhone, WebSocketPhonesimConfigResponse)
File "/Users/jr/.local/share/uv/tools/pebble-tool/lib/python3.13/site-packages/libpebble2/communication/__init__.py", line 253, in read_transport_message
return self.event_handler.wait_for_event((_EventType.Transport, origin, message_type), timeout=timeout)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jr/.local/share/uv/tools/pebble-tool/lib/python3.13/site-packages/libpebble2/events/threaded.py", line 37, in wait_for_event
return _BlockingEventWait(self, event).wait(timeout=timeout)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/Users/jr/.local/share/uv/tools/pebble-tool/lib/python3.13/site-packages/libpebble2/events/threaded.py", line 61, in wait
raise TimeoutError()
libpebble2.exceptions.TimeoutError
Huh, it kinda sounds like it crashed in the emulator before you even run emu-app-config, do you get any other logs when you install the watchapp?
The app starts normally and prints its normal log output on startup. It continues to run and update the display. When I issue the emu-app-config command from a separate terminal, no additional messages appear in the main install ... --logs output. So it seems like the problem occurs when handling the showConfiguration message in PKJS. I haven’t yet taken the time to try to instrument that side with extra logging to narrow it down.
Couldn’t help having a go at it myself. I have a draft PR. But I wasn’t able to check the localStorage in the dev environment. I still need to test it in an actual app/watchface
That looks pretty good! I will have a look at testing it tomorrow
Awesome! @hellcp have you had chance to review GitHub · Where software is built and PRs?
I looked through it at one point, but I would appreciate it if you find anything there that should be submitted to the fork and submit it. I have been investigating the branch that added a test app too!
I’ve been laying sick in bed so I’m not focusing too much on Rebble stuff today :C
I certainly think that I could implement it locally. I just think the separate checkbox values coming back for a single group is fairly badTM no matter what though so it probably should just be the general behavior (with backwards compat surely)
The issue is if you have a growing or dynamic list of items in the checkbox group you have to reserve message keys for them going forward based on the initial group key since they’re auto assigned. For example I reserved 200 message keys for checkboxes but if I have 201 (I never will), I’ll need to shift all of the keys. This caused me to maintain a separate map of the keys based on the names so that if I do move keys around Clay can still find the right spots to inject values from old builds
Or I’m using Clay wrong and none of that is needed. But if CheckboxGroups had an option of a single value I don’t think anyone would want to use the separate key values anymore from a maintenance perspective.
Sorry, I didn’t mean to imply that your request wasn’t a good idea. Just wanted to share some info that might help you in the meantime. I rushed my message and didn’t explain that very well.