Skip to content

Add Ember Cup BLE as a temperature device (TemperatureType.EMBER) - #1134

Open
danielfcurrie-alt wants to merge 2 commits into
graphefruit:developfrom
danielfcurrie-alt:ember-temperature-device
Open

Add Ember Cup BLE as a temperature device (TemperatureType.EMBER)#1134
danielfcurrie-alt wants to merge 2 commits into
graphefruit:developfrom
danielfcurrie-alt:ember-temperature-device

Conversation

@danielfcurrie-alt

@danielfcurrie-alt danielfcurrie-alt commented Jun 15, 2026

Copy link
Copy Markdown

Beanconqueror — Ember Temperature Device + Target Brew Weight Webhook

Two independent features on one branch. Happy to split into separate PRs if preferred.

Overview

  1. Ember temperature integration — Native TemperatureDevice support for Ember devices (Mug 2, Cup 2, Travel Mug 2, etc.)
  2. Target brew weight webhook — Configurable HTTP GET fired when the brew reaches a target weight, enabling automatic machine stop via smart plugs, relays, or home automation systems.

1. Ember Temperature Device (TemperatureType.EMBER)

Adds EmberThermometer (src/classes/devices/emberThermometer.ts) as a new TemperatureDevice subclass, following the exact same pattern as BasicGrillThermometer and MeaterThermometer.

Protocol

All characteristics are under one custom 128-bit service (fc543622-236c-4c94-8fa9-944a3e5353fa):

Characteristic UUID Purpose
CURRENT_TEMPERATURE fc540002-236c-4c94-8fa9-944a3e5353fa Drink temp — little-endian int16 / 100 = °C
PUSH_EVENT fc540012-236c-4c94-8fa9-944a3e5353fa 1-byte event code — 5 = DRINK_TEMPERATURE_CHANGED
BATTERY fc540007-236c-4c94-8fa9-944a3e5353fa byte[0] = battery % · byte[1] = on charging base

Subscribes to PUSH_EVENT notifications and reads temperature only on event 5. getBattery() is overridden because Ember does not expose the standard GATT Battery Service (180F/2A19).

Sources & Validation

  • UUID map and event enum verified against sopelj/python-ember-mug (actively maintained) and orlopau/ember-mug
  • Flow validated end-to-end via a bleak Python prototype before porting to cordova-plugin-ble-central

Testing (Android — real hardware)

  • ✅ Works with real Ember Cup 2
  • test() matches via device.name.toLowerCase().includes('ember') — covers all Ember models by name
  • ✅ Connects via existing ble.autoConnect flow
  • ✅ Live temperature renders correctly in brew graph during espresso shot
  • ✅ Battery % and charging state shown on connect

Open items:

  • iOS untested
  • Other Ember models (Mug 2, Travel Mug 2) match by name check but are unverified on real hardware
  • Battery push events (1/2/3) are received but not acted on — battery is polled once at connect time for simplicity

2. Target Brew Weight Webhook

Fires a configurable HTTP GET request when the brew reaches a target weight.

Settings UI

New card in Settings (after the Visualizer section):

  • Default target weight (g) — pre-fills brew_beverage_quantity when the brew modal opens
  • Predictive stop toggle — uses the existing calculateBrewByWeight() / calculateNextResidualLagTime() lag-learning algorithm
  • Webhook URL + authentication (None / Bearer / Basic / Custom Header)
  • Test button — fires the webhook immediately to confirm reachability
  • ⚠️ Warning shown when credentials are configured over plain http://

Implementation Highlights

  • buildWebhookHeaders() extracted to src/classes/settings/brewByWeightWebhook.ts so the test button and live trigger share the same logic
  • webhookFired flag is independent of machineStopScriptWasTriggered to prevent re-arming after scale reconnects mid-shot
  • Target weight is captured once at brew start (live brew_beverage_quantity cannot be used as a stable threshold)
  • Predictive mode only calls lag calculation when no prep device is connected

Request Format

Currently issues a simple HTTP GET to the configured URL. No query parameters or body are sent by default.
Note: Some automation platforms prefer POST + JSON body. This is a known v1 limitation.

Testing (Android — real hardware)

Verified with Breville Barista Express + SoloBarista scale + Shelly smart plug:

  • Direct mode: fires reliably at target ±0.1 g
  • Predictive mode: lag learning visible in logs ([Webhook BBW] Auto-adjusting lag from X to Y)
  • ✅ Error logging on webhook failure is implemented (visible in Settings → Info → Log)

Future: Add retry on webhook failure (error logging already implemented).


Platform Support

Feature Android iOS
Ember Temperature Device ✅ Verified ⚠️ Untested
Brew-by-Weight Webhook ✅ Verified ✅ Should work (no native code)

@CLAassistant

CLAassistant commented Jun 15, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@danielfcurrie-alt
danielfcurrie-alt force-pushed the ember-temperature-device branch 3 times, most recently from 6aa15c9 to f0acb57 Compare June 16, 2026 12:42
Subscribes to PUSH_EVENT (fc540012) and reads CURRENT_TEMPERATURE (fc540002)
on event 5 (DRINK_TEMPERATURE_CHANGED). Overrides getBattery() to read from
Ember's custom characteristic fc540007 (byte[0]=percent, byte[1]=charging).

Verified on Android against a real Ember Cup 2 - shows up correctly in the
bluetooth device scan, connects via the existing ble.autoConnect flow, and
live temperature data renders in the brew graph during an espresso shot.
Fires a configurable HTTP GET request when the brew reaches a target weight,
enabling a smart plug or relay to stop the machine automatically.

Features:
- Configurable URL with auth options (Bearer, Basic, Custom Header)
- Default target weight pre-fills brew_beverage_quantity at brew start
- Direct mode: fires exactly at target weight
- Predictive mode: uses graphefruit's existing lag-learning algorithm to
  converge toward the correct yield across shots
- webhookTargetWeight captured once at brew start to avoid live scale
  data overwriting brew_beverage_quantity mid-shot
- buildWebhookHeaders() shared between settings test button and live trigger

Verified on Android with Breville + Eureka Precisa scale + Shelly smart plug.
Direct mode fires at target +-0.1g.
@danielfcurrie-alt
danielfcurrie-alt force-pushed the ember-temperature-device branch from f0acb57 to b18ffe3 Compare June 16, 2026 12:47
@graphefruit

Copy link
Copy Markdown
Owner

Hey there,
thank you for the PR!
I'm going to push next week a bigger change on DEV, please merge this then before and maybe update the PR if needed.
Do you have an iOS Device to test or friends, I can build you a DEV version, adding a device without having the check if iOS and Android is working is not my intention.

Also please: Add a github issue, with the thermometer and a link which one is supported so this can be added on the official website.

Best
Lars

@danielfcurrie-alt

danielfcurrie-alt commented Jun 19, 2026 via email

Copy link
Copy Markdown
Author

@graphefruit

Copy link
Copy Markdown
Owner

Can you pass me an e-mail: info@beanconqueror.com, so we can get in direct contact for the DEV-Build on iOS (or on Discord: Beanconqueror)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants