Skip to content

Releases: NicholasBly/GermGuardianBLE

v2.0

Choose a tag to compare

@NicholasBly NicholasBly released this 27 Sep 01:53
941067a

v2.0

Unrelated side notes: I've successfully ported the Guardian app control over to web bluetooth (Bluefy for iOS, or Chrome/Brave on Android). The only issue is figuring out how to get the pairing/local key using the web version. You'll need to know what your local key is by using this app, connecting to the purifier, and copying it from the settings.

I utilized Claude Opus 5 to help decipher the bluetooth packets using an nRF USB dongle into my PC with Wireshark to intercept the data transmission from my iPhone to the purifier to make web bluetooth work. Download here: #1

Fixed

  • White launch flash: launch screen background, splash logo bg, native web-view background, and home-screen base layer were all hard-coded white - now black regardless of theme.
  • Startup no longer waits on Guardian's dead cloud server (_recoverDevicesData) before using the saved local pairing key.
  • Background/foreground handling rewritten: old pagehide/resume listeners never fired in WKWebView, so returning to the app didn't refresh status until the next poll (up to 10s later). Now pauses polling in the background and refreshes immediately on return (with a full link reset after >25s away).
  • Commands sent while the device was mid-read no longer get silently dropped as "busy" - they queue and retry.
  • Switching between two paired devices no longer double-stops the wrong device or permanently kills polling.
  • Failed commands now revert the UI to the device's real state instead of leaving stale optimistic values.
  • Control buttons work immediately instead of only after the first status read completes (up to 8s delay).

Changed

  • Script loading: jquery/hubea/aspe/guardian load via <script defer> in parallel at parse time, not sequentially after window.load.
  • Server-type probing reduced from a 4-type (l,p,d,s) x 15s loop to a single 10s try on l (local/offline), since the cloud types are dead.
  • Device search retry backoff: 500ms → 1s → 2s (was a flat 2s), with a 6s watchdog per attempt so a stuck native callback doesn't hang the search.
  • Connection retry delay: 2s → 1s.
  • Debug log rewritten as a capped ring buffer (500 lines kept, 200 rendered) with batched DOM flushes; previously unbounded and forced a layout per line.
  • Image src updates (air quality, speed, theme icons) now skip the DOM write when the value hasn't changed.

Removed

  • Unused bundled assets: css/, fonts/, locales/, js/crypto-js/, 7 unused JS files, iPad-only app icons, stale _CodeSignature/SC_Info.
  • iPad support (UIDeviceFamily → iPhone-only) and unused background modes (fetch, remote-notification), keeping only bluetooth-central.

App package size: 3.98 MB → 3.44 MB (installed), IPA 1.53 MB → 1.25 MB.

v1.7

Choose a tag to compare

@NicholasBly NicholasBly released this 22 Feb 04:34
f98c8f4

v1.7

New Features

  • Added HEPA life and UV Bulb life to the main control page shown as percentages

Optimizations

  • Loading time optimizations
  • JavaScript code optimizations
  • Sending command speed optimizations

Fixes

  • Fixed incorrect connection gateway via deviceID, sometimes causing connection to fail with no working controls
  • Converted pixel sizing rules to rem for better scalability

v1.6

Choose a tag to compare

@NicholasBly NicholasBly released this 04 Nov 22:32
8c5bfef

Skip over getInstallId as it will always time out. Saves 5+ seconds of loading time.

Optimized HTML/CSS

v1.5 - iOS 26.1 Support

Choose a tag to compare

@NicholasBly NicholasBly released this 01 Nov 00:56

Support for iOS 26.1 RC - major changes by Apple broke previous versions.

  • Added javascript logs to main log for more information

  • Patched lots of javascript functions as a work around

  • Patched walkthrough storyboard file to load main storyboard file
    -> Info.plist no longer loads the html file due to Apple's 26.1 changes

  • Rewrote main connection logic
    -> Prioritize local server first, load all scripts from parent directory first = faster load times

  • Added "Copy Log" button underneath console log

  • Added Polling Rate modifier 3 - 10 seconds (10 seconds is default)

  • Added Device LocalKey Show & Copy button

  • Added app sleep + resume functionality to fix background battery drain (present in original app)
    -> App will disconnect from purifier when app is no longer in focus, stopping it from constantly polling it in the background
    -> App might become unstable after resuming. Commands might not send immediately, try restarting the app

v1.4a

Choose a tag to compare

@NicholasBly NicholasBly released this 28 Oct 18:53
fc97598
IMG_5346

Redesigned UI to closely match the original

Functional UI features from original (green/orange/red purifier icon + visual speed bars)

Added dark mode and amoled mode + applicable icons

Moved console log to settings page and loading screen only

CSS adjustments

Removed more unused assets to shrink file size -> ~1.5MB

Planned features for v1.5a / full release:

Javascript optimizations and faster polling for better responsiveness and loading times

v1.3a

Choose a tag to compare

@NicholasBly NicholasBly released this 25 Oct 18:04
d30c5d9
  • Added device selector to settings tab (shows if more than one GermGuardian air purifier is detected)

  • Slimmed down .ipa: ~7.5MB -> ~2.5MB

v1.2a

Choose a tag to compare

@NicholasBly NicholasBly released this 25 Oct 00:32
c8f2569

Added Control + Settings Tab

Settings tab now shows HEPA filter and UV-C bulb life

Moved "Dark Mode" and "Show Console Log" to Settings tab

Disabled red warning icon present in top right corner when location is not set to always

Icon file was renamed in order to hide it

Location of file is Payload -> oem4guardiantech.app -> oem4guardiantech-Resources.bundle -> icon_alert.png (now icon_alert_disabled.png)

v1.1a

Choose a tag to compare

@NicholasBly NicholasBly released this 25 Oct 00:07
2da2409

Bug Fixes:

  • Fixed app connecting to the wrong device sometimes.

Explanation:

Stricter Filtering: findDevice and findDeviceDirectly both now explicitly filter the list of detected devices to include only those whose productCode exists and is present in the GUARDIAN_PRODUCT_CODES list.

v1.0a - Initial Release

Choose a tag to compare

@NicholasBly NicholasBly released this 24 Oct 19:36
25c8f69

To do:

  • UI needs some cleanup for a stable release.

  • After saving local pairing key, the app might hang trying to pair with different device id when reopened. Relaunching the app will fix it as a workaround.

  • Create settings page to list air purifier details: power on hours for filter and UV C bulb (visible in console), notification/badge when filter life is EOL.