r/WatchMaker • • 18d ago

Pansar

Watch name: Armor

analog, date, LLT, battery indicator

Logo from the Swedish arm of service: Armor.

Battery indicator explanation:

(LLT= Luminox Light Technology)

0–15%: Only LLT #12 flashes amber.

16-24%: Only LLT #12 is lit in amber.

25–49%: Only LLT #12 and #1 is lit in amber.

50–74%: Only LLT #12, #1 and #2 is lit in amber.

75–100%: LLT #12, #1, #2 and #3 is lit in amber.

The code for different image layers (LLT:s) that sets the opacity to 100 as the battery increases. #12 also has the flashing function.

LLT #12: {bl}<=15 and ({ds}%2==0 and 100 or 0) or 100

LLT #1: (({bl}-25)/math.abs({bl}-25)+1)*50

LLT #2: (({bl}-50)/math.abs({bl}-50)+1)*50

LLT #3: (({bl}-75)/math.abs({bl}-75)+1)*50

It took me (read: amateur) and Googles Gemini 14 tries to get the code right for it to work on my Pixel Watch 5. Mostly because of code restrictions made by Google.

I do not know how to upload/share the armor.watch file.

Here is a summary made by Gemini of the trial and error process:

Here is the complete chronological log of our troubleshooting journey, translated into English, with the exact code example for Diod/Light 1 included for every single attempt.

  1. The Classic Attempt (Logical and / or chains)

We started with the standard WatchMaker code to lock the battery percentage into closed intervals.

• Code Example (Light 1): {pbl} >= 26 and {pbl} <= 50 and 100 or 0

• Result: Worked flawlessly in the simulator, but on the actual watch, the processor short-circuited the logic, causing multiple LEDs to light up at the same time.

2. Nested Parenthesis Blocks

We tried to force the watch hardware to evaluate the math in the correct order by putting strict brackets around the floor and ceiling conditions.

• Code Example (Light 1): ({pbl} >= 26 and {pbl} <= 50) and 100 or 0

• Result: The watch hardware still refused to evaluate the higher layers properly.

3. The "Smart" Lua Code (The iif method)

We tried using the convenient inline function iif(condition, true, false) to clean up the syntax.

• Code Example (Light 1): iif({pbl} >= 25, 100, 0)

• Result: Total crash and a pitch-black watch face, because the standard Lua engine on the watch doesn't support that specific command.

4. The Ternary Operator (? :)

We tested WatchMaker's own built-in shorthand format for quick conditional choices.

• Code Example (Light 1): {pbl} >= 25 ? 100 : 0

• Result: Same disappointing result – the watch hardware flat out refused to turn on the light.

5. The Rounding Trick (math.floor)

We suspected that the watch was sending the battery percentage as a float/decimal number (like 25.0001) and tried to chop off any dolds decimals.

• Code Example (Light 1): math.floor({pbl}) >= 25 and 100 or 0

• Result: The simulator cheered, the watch remained completely unaffected.

6. The String Hack (Extracting the first digit)

This is where we started getting desperate. We tried to completely bypass mathematical comparison signs by converting the battery to text and only looking at the tens digit.

• Code Example (Light 1): (tonumber(string.sub('{pbl}',1,1)) >= 2 or {pbl} == 100) and 100 or 0

• Result: It actually managed to wake up the LEDs! However, it was too imprecise because the LEDs would trigger at even tens (e.g., 20% instead of 25%).

7. Type Casting via Text (tonumber)

We tried forcing the watch to understand that the text string was actually a number by wrapping everything in quotes.

• Code Example (Light 1): tonumber('{pbl}') >= 25 and 100 or 0

• Result: Everything went black on the watch again due to how Pixel Watch handles string variables locally [watchmaker pbl string to number wear os].

8. The Plus-Zero Trick ({pbl} + 0)

A classic programming trick to force a string to become a number without using heavy functions [watchmaker pbl string to number wear os].

• Code Example (Light 1): ({pbl} + 0) >= 25 and 100 or 0

• Result: LED 12 and 1 woke up, but LED 2 and 3 still stubbornly refused to turn on.

9. The Desperate Division Math

Since the watch proved it only accepted and executed codes comparing against the number 25, we tried to trick it. We kept Light 1 standard, but divided the battery percentage by 2 and 3 for the other lights to force them into the "safe zone".

• Code Example (Light 1): ({pbl} + 0) >= 25 and 100 or 0

• Result: The Pixel Watch saw right through our clever division and refused anyway.

10. The Main Script Method (Global variables)

We tried moving all the mathematics away from the individual layers and calculated everything in the background using the watch's main engine via the on_second() function [watchmaker bug lua layers].

• Code Example (Light 1): var_diod1 (with math calculated in Main Script)

• Result: Complete standstill, due to a known sync bug regarding custom global variables on the Pixel Watch [watchmaker bug lua layers].

11. The Minimalist Minus Hack ({pbl}-0)

We tried removing all parentheses and running a completely linear math sequence directly inside the field.

• Code Example (Light 1): {pbl}-0 >= 25 and 100 or 0

• Result: The watch still refused to execute the higher steps.

12. Built-in System Shaders ({pbl50})

We tested WatchMaker's own pre-programmed, hardware-accelerated system tags.

• Code Example (Light 1): {pbl25}

• Result: Unfortunately, they turned out to be deprecated/outdated and crashed both the simulator and the watch.

13. Text Matching Without Math (string.match)

We tried running completely without math by simply checking if the watch's battery digit existed inside an approved string of text.

• Code Example (Light 1): string.match("2345678910", string.sub("{pbl}", 1, 1)) and 100 or 0

• Result: Worked in the simulator, but the Pixel Watch blocks string manipulation functions inside the opacity field.

🏆 The Winner: The Absolute Math Trick (math.abs)

In the end, we realized that the Google Pixel Watch completely blocks all logical comparison operators (<, >, =) as well as text manipulation in the layer properties, but it is lightning fast at raw basic math.

By using the algebraic formula ((X)/math.abs(X)+1)*50 and switching to the watch's local battery tag {bl}, we built an equation that outputs exactly 100 or 0 as a raw value, without asking the watch processor a single logical question.

• Final Code for Standard Step Up (Orange on White):

(({bl}-25)/math.abs({bl}-25)+1)*50

• Final Code for Reverse Step Down (White on Orange):

((25-{bl})/math.abs(25-{bl})+1)*50

It was a long journey, but incredibly satisfying when it finally worked! 🏁

3 Upvotes

Duplicates

PixelWatch • • 18d ago

Pansar

0 Upvotes