From 46dd331dbeae01dbc09f28d2f26c9d7b325d024f Mon Sep 17 00:00:00 2001 From: AtomHeart-Lang Date: Sun, 24 May 2026 16:16:49 +0800 Subject: [PATCH] Add AtomHeart Eclair scale support - Add ECLAIR scale type with BLE UUIDs (WRITE_CHAR_ECLAIR, READ_CHAR_ECLAIR) - Add Eclair command arrays: TARE, START_TIMER, STOP_TIMER, RESET_TIMER - Add calculateXOR() and readInt32LittleEndian() helpers - Add Eclair detection in init() via device name prefix and characteristic discovery - Skip IDENTIFY/NOTIFICATION_REQUEST for Eclair (not needed) - Add Eclair weight packet parsing ('W' header, int32 LE, XOR validation) - Skip heartbeat for Eclair (not required) - Add Eclair to scale compatibility table and checklists - Bump version to 3.4.0 --- AcaiaArduinoBLE.cpp | 113 ++++++++++---- AcaiaArduinoBLE.h | 13 +- README.md | 369 ++++++++++++++++++++++---------------------- library.properties | 22 +-- 4 files changed, 286 insertions(+), 231 deletions(-) diff --git a/AcaiaArduinoBLE.cpp b/AcaiaArduinoBLE.cpp index 2bf3112..8a539b1 100644 --- a/AcaiaArduinoBLE.cpp +++ b/AcaiaArduinoBLE.cpp @@ -1,5 +1,5 @@ /* - AcaiaArduinoBLE.cpp - Library for connecting to + AcaiaArduinoBLE.cpp - Library for connecting to an Acaia Scale using the ArduinoBLE library. Created by Tate Mazer, December 13, 2023. Released into the public domain. @@ -21,11 +21,32 @@ byte TARE_GENERIC[6] = { 0x03, 0x0a, 0x01, 0x00, 0x00, 0x08 }; byte START_TIMER_GENERIC[6] = { 0x03, 0x0a, 0x04, 0x00, 0x00, 0x0a }; byte STOP_TIMER_GENERIC[6] = { 0x03, 0x0a, 0x05, 0x00, 0x00, 0x0d }; byte RESET_TIMER_GENERIC[6] = { 0x03, 0x0a, 0x06, 0x00, 0x00, 0x0c }; +byte TARE_ECLAIR[3] = { 0x54, 0x01, 0x01 }; +byte START_TIMER_ECLAIR[3] = { 0x53, 0x01, 0x01 }; +byte STOP_TIMER_ECLAIR[3] = { 0x45, 0x01, 0x01 }; +byte RESET_TIMER_ECLAIR[3] = { 0x52, 0x01, 0x01 }; /* Generic commands from https://github.com/graphefruit/Beanconqueror/blob/master/src/classes/devices/felicita/constants.ts */ +uint8_t calculateXOR(const byte data[], int length){ + uint8_t result = 0; + for(int i = 0; i < length; i++){ + result ^= data[i]; + } + return result; +} + +int32_t readInt32LittleEndian(const byte data[]){ + return (int32_t)( + ((uint32_t)data[0]) | + ((uint32_t)data[1] << 8) | + ((uint32_t)data[2] << 16) | + ((uint32_t)data[3] << 24) + ); +} + AcaiaArduinoBLE::AcaiaArduinoBLE(bool debug){ _debug = debug; _currentWeight = 0; @@ -114,8 +135,13 @@ bool AcaiaArduinoBLE::init(String mac){ } else if(peripheral.characteristic(READ_CHAR_GENERIC).canSubscribe()){ Serial.println("Generic Scale Detected"); _type = GENERIC; - _write = peripheral.characteristic(WRITE_CHAR_GENERIC); - _read = peripheral.characteristic(READ_CHAR_GENERIC); + _write = peripheral.characteristic(WRITE_CHAR_GENERIC); + _read = peripheral.characteristic(READ_CHAR_GENERIC); + } else if(peripheral.characteristic(READ_CHAR_ECLAIR).canSubscribe()){ + Serial.println("Eclair Scale Detected"); + _type = ECLAIR; + _write = peripheral.characteristic(WRITE_CHAR_ECLAIR); + _read = peripheral.characteristic(READ_CHAR_ECLAIR); } else{ Serial.println("unable to determine scale type"); @@ -131,18 +157,20 @@ bool AcaiaArduinoBLE::init(String mac){ }else { Serial.println("subscribed!"); } - - if(_write.writeValue(IDENTIFY, 20)){ - Serial.println("identify write successful"); - }else{ - Serial.println("identify write failed"); - return false; - } - if(_write.writeValue(NOTIFICATION_REQUEST,14)){ - Serial.println("notification request write successful"); - }else{ - Serial.println("notification request write failed"); - return false; + + if(_type != ECLAIR){ + if(_write.writeValue(IDENTIFY, 20)){ + Serial.println("identify write successful"); + }else{ + Serial.println("identify write failed"); + return false; + } + if(_write.writeValue(NOTIFICATION_REQUEST,14)){ + Serial.println("notification request write successful"); + }else{ + Serial.println("notification request write failed"); + return false; + } } _connected = true; _packetPeriod = 0; @@ -151,11 +179,14 @@ bool AcaiaArduinoBLE::init(String mac){ }while(millis() - start < 10000); Serial.println("failed to find scale"); - return false; + return false; } bool AcaiaArduinoBLE::tare(){ - if(_write.writeValue((_type == GENERIC ? TARE_GENERIC : TARE_ACAIA), 6)){ + byte *command = (_type == ECLAIR) ? TARE_ECLAIR : (_type == GENERIC ? TARE_GENERIC : TARE_ACAIA); + int length = (_type == ECLAIR) ? 3 : 6; + + if(_write.writeValue(command, length)){ Serial.println("tare write successful"); return true; }else{ @@ -166,9 +197,11 @@ bool AcaiaArduinoBLE::tare(){ } bool AcaiaArduinoBLE::startTimer(){ - if(_write.writeValue((_type == GENERIC ? START_TIMER_GENERIC : START_TIMER), - (_type == GENERIC ? 6 : 7))){ - Serial.println("start timer write successful"); + byte *command = (_type == ECLAIR) ? START_TIMER_ECLAIR : (_type == GENERIC ? START_TIMER_GENERIC : START_TIMER); + int length = (_type == ECLAIR) ? 3 : (_type == GENERIC ? 6 : 7); + + if(_write.writeValue(command, length)){ + Serial.println("start timer write successful"); return true; }else{ _connected = false; @@ -178,8 +211,10 @@ bool AcaiaArduinoBLE::startTimer(){ } bool AcaiaArduinoBLE::stopTimer(){ - if(_write.writeValue((_type == GENERIC ? STOP_TIMER_GENERIC : STOP_TIMER), - (_type == GENERIC ? 6 : 7 ))){ + byte *command = (_type == ECLAIR) ? STOP_TIMER_ECLAIR : (_type == GENERIC ? STOP_TIMER_GENERIC : STOP_TIMER); + int length = (_type == ECLAIR) ? 3 : (_type == GENERIC ? 6 : 7); + + if(_write.writeValue(command, length)){ Serial.println("stop timer write successful"); return true; }else{ @@ -190,8 +225,10 @@ bool AcaiaArduinoBLE::stopTimer(){ } bool AcaiaArduinoBLE::resetTimer(){ - if(_write.writeValue((_type == GENERIC ? RESET_TIMER_GENERIC : RESET_TIMER), - (_type == GENERIC ? 6 : 7 ))){ + byte *command = (_type == ECLAIR) ? RESET_TIMER_ECLAIR : (_type == GENERIC ? RESET_TIMER_GENERIC : RESET_TIMER); + int length = (_type == ECLAIR) ? 3 : (_type == GENERIC ? 6 : 7); + + if(_write.writeValue(command, length)){ Serial.println("reset timer write successful"); return true; }else{ @@ -202,6 +239,10 @@ bool AcaiaArduinoBLE::resetTimer(){ } bool AcaiaArduinoBLE::heartbeat(){ + if(_type == ECLAIR){ + return true; + } + if(_write.writeValue(HEARTBEAT, 7)){ _lastHeartBeat = millis(); return true; @@ -239,7 +280,7 @@ bool AcaiaArduinoBLE::newWeightAvailable(){ int l = _read.valueLength(); // Get packet - if(10 >= l || //10 byte packets for pre-2021 lunar + if(10 >= l || //10 byte packets for pre-2021 lunar and Eclair (13 >= l && OLD != _type) || //13 byte packets for pyxis and older lunar 2021 fw (14 == l && OLD == _type) || //14 byte packets for lunar 2021 AL008 (17 == l && NEW == _type) || //17 byte packets for newer lunar 2021 fw @@ -259,10 +300,10 @@ bool AcaiaArduinoBLE::newWeightAvailable(){ // Parse New style data packet if (NEW == _type && (13 == l || 17 == l) && input[4] == 0x05) { - //Grab weight bytes (5 and 6) + //Grab weight bytes (5 and 6) // apply scaling based on the unit byte (9) // get sign byte (10) - _currentWeight = (((input[6] & 0xff) << 8) + (input[5] & 0xff)) + _currentWeight = (((input[6] & 0xff) << 8) + (input[5] & 0xff)) / pow(10,input[9]) * ((input[10] & 0x02) ? -1 : 1); newWeightPacket = true; @@ -272,8 +313,8 @@ bool AcaiaArduinoBLE::newWeightAvailable(){ //Grab weight bytes (2 and 3), // apply scaling based on the unit byte (6) // get sign byte (7) - _currentWeight = (((input[3] & 0xff) << 8) + (input[2] & 0xff)) - / pow(10, input[6]) + _currentWeight = (((input[3] & 0xff) << 8) + (input[2] & 0xff)) + / pow(10, input[6]) * ((input[7] & 0x02) ? -1 : 1); newWeightPacket = true; @@ -281,12 +322,19 @@ bool AcaiaArduinoBLE::newWeightAvailable(){ //Grab weight bytes (3-8), // get sign byte (2) _currentWeight = (( input[7] << 16) | (input[8] << 8) | input[9]); - + if (input[6] == 45) { // Check if the value is negative _currentWeight = -_currentWeight; - } + } _currentWeight = _currentWeight / 100; newWeightPacket = true; + }else if( ECLAIR == _type && l == 10 && input[0] == 'W'){ + if(calculateXOR(input + 1, 8) == input[9]){ + _currentWeight = readInt32LittleEndian(input + 1) / 1000.0; + newWeightPacket = true; + }else if(_debug){ + Serial.println("Eclair packet XOR failed"); + } } if(newWeightPacket){ if(_lastPacket){ @@ -309,7 +357,8 @@ bool AcaiaArduinoBLE::isScaleName(String name){ || nameShort == "LUNAR" || nameShort == "PEARL" || nameShort == "PROCH" - || nameShort == "BOOKO"; + || nameShort == "BOOKO" + || nameShort == "ECLAI"; } void AcaiaArduinoBLE::exploreService(BLEService service) { diff --git a/AcaiaArduinoBLE.h b/AcaiaArduinoBLE.h index 91b98ef..e7bb6fd 100644 --- a/AcaiaArduinoBLE.h +++ b/AcaiaArduinoBLE.h @@ -1,10 +1,10 @@ /* - AcaiaArduinoBLE.h - Library for connecting to + AcaiaArduinoBLE.h - Library for connecting to an Acaia Scale using the ArduinoBLE library. Created by Tate Mazer, December 13, 2023. Released into the public domain. - Pio Baettig: Adding Felicita Arc support + Pio Baettig: Adding Felicita Arc support Known Bugs: * Only supports Grams @@ -12,13 +12,15 @@ #ifndef AcaiaArduinoBLE_h #define AcaiaArduinoBLE_h -#define LIBRARY_VERSION "3.3.0" +#define LIBRARY_VERSION "3.4.0" #define WRITE_CHAR_OLD_VERSION "2a80" #define READ_CHAR_OLD_VERSION "2a80" #define WRITE_CHAR_NEW_VERSION "49535343-8841-43f4-a8d4-ecbe34729bb3" #define READ_CHAR_NEW_VERSION "49535343-1e4d-4bd9-ba61-23c647249616" #define WRITE_CHAR_GENERIC "ff12" #define READ_CHAR_GENERIC "ff11" +#define WRITE_CHAR_ECLAIR "4F9A45BA-8E1B-4E07-E157-0814D393B968" +#define READ_CHAR_ECLAIR "AD736C5F-BBC9-1F96-D304-CB5D5F41E160" #define HEARTBEAT_PERIOD_MS 2750 #define MAX_PACKET_PERIOD_MS 5000 @@ -28,7 +30,8 @@ enum scale_type{ OLD, // Lunar (pre-2021) NEW, // Lunar (2021), Pyxis - GENERIC // Felicita Arc, etc + GENERIC, // Felicita Arc, Bookoo, etc + ECLAIR }; class AcaiaArduinoBLE{ @@ -59,7 +62,7 @@ class AcaiaArduinoBLE{ long _lastHeartBeat; bool _connected; scale_type _type; - bool _debug; + bool _debug; long _packetPeriod; long _lastPacket; }; diff --git a/README.md b/README.md index 320db39..bd905dd 100644 --- a/README.md +++ b/README.md @@ -1,183 +1,186 @@ -# AcaiaArduinoBLE -Acaia / Bookoo Scale Gateway using the ArduinoBLE library for devices such as the esp32, arduino nano esp32, and arduino nano iot 33. -This is an Arduino Library which can be found in the Arduino IDE Library Manager. - -## Scale Compatibility - -| Mfr | Model | Submodel | Firmware | Connection Performance | Auto-Tare | Auto-Start/Stop Timer | Auto-Reset Timer | -| ------ | ------- | ------- |------- |------ | ------ |------ |------ | -| Acaia | Lunar | USB-Micro
(Pre-2021) | v2.6.019 | Great | Yes | Yes | Untested -| Acaia | Lunar | USB-C
(2021 version) | v1.0.016 | Hit or Miss | Yes | Yes | Yes -| Acaia | Pearl S | USB-Micro | v1.0.056 | Ok | Yes | Yes | Yes -| Acaia | Pearl S | USB-C | ---- | Ok | Yes | Yes | Yes -| Acaia | Pyxis | ---- | v1.0.022 | Good | Not Recommended (too sensitive) | Yes | Yes -| Bookoo | Themis Mini | ---- | v1.0.5 | Great | Yes | Yes | Yes -| Bookoo | Themis Ultra | ---- | ---- | Great | Yes | Yes | Yes - - -## Requirements -This library is intended to be used with any arduino device which is compatible with the [ArduinoBLE](https://www.arduino.cc/reference/en/libraries/arduinoble/) library. - -As of version V2.0.0, non-volatile storage for the setpoint and offset is only available for ESP32-based devices. - -## Printed Circuit Board -![shotStopperV3 screenshot](https://github.com/user-attachments/assets/a09fe8fb-3705-44c0-88a2-07c61d67b8f6) - -The included "shotStopper" example code uses the ShotStopper PCB to make it simple to control your espresso machine using the scale. - -A kit can also be ordered by visiting [tatemazer.com](https://tatemazer.com/store) - -If you choose to build your own from scratch, v2.0 is recommended as it requires only through-hole components - -Join the discord for updates and support: https://discord.gg/NMXb5VYtre - -[![Video showing developmnent of the shotStopper](https://img.youtube.com/vi/434hrQDGtxo/0.jpg)](https://youtu.be/434hrQDGtxo) - -## Espresso Machine Compatibility - -| Model | Powered by Machine (5V) | Brew State Detection Method | Officially Documented | -| ----- | ----------------------- | --------------------------- | ---------------- | -| GS3 | No, requires included power supply | Solenoid Valve (Reed Switch) | Yes | -| Linea Micra | Yes | Brew Switch | Yes | -| Linea Mini* | Older, non-IoT machines may require a power supply | Brew Switch | Yes | -| Linea Mini R | Yes | Brew Switch | Yes | -| Silvia Pro (X) | Yes | Brew Button | Yes | -| Stone Espresso | Yes | Solenoid Valve (Reed Switch) | Yes | -| Ascaso Steel Duo PID | Untested | Brew Button | No -| Profitec Move | Yes | Brew Button | No | - -*Ace Dotshot is compatible with the shotStopper. Also note, shot duration is automated at the scale with the shotStopper, making the dotShot redundant. - -## ShotStopper Example Code Configuration - -The following variables at the top of the shotStopper.ino file can be configured by the user: - -`MOMENTARY` -* true for momentary switches such as GS3 AV, Rancilio Silvia Pro, etc. -* false for latching switches such as Linea Mini/Micra, stone, etc. - -`REEDSWITCH` -* true if a reed switch on the brew solenoid is being used to determine the brew state. This is typically not necessary so set to FALSE by default. This feature is only available for non-momentary-switches. - -`AUTOTARE` -* true by default. The scale will automatically tare when the shot is started, and, if MOMENTARY is false, will perform another tare at 3 seconds to notify the user that the switch is latched and should be returned to the home position. -* if set to false, the shotStopper will never send a tare command. It is the user's responsibility to tare before each shot. This may be helpful if the scale is not stable when the shot begins, and thus the scale is unable to tare reliably. - -`TIMER_ONLY` -* false by default. disables brew-by-weight functionality and enables only automatic timer and tare - -## Demo - -You can find a demo on Youtube: - -[![Video showing an shotStopper pulling a shot on a silvia pro](https://img.youtube.com/vi/oP3Cmke6daE/0.jpg)](https://www.youtube.com/shorts/oP3Cmke6daE) - -## Project Status - -Firmware: - -☑ Connect Acaia Pyxis to ESP32 - -☑ Tare Command - -☑ Receive Weight Data - -☑ shotStopper Espresso Machine Brew-By-Weight Firmware - -☑ Compatibility with Lunar (Pre-2021) - -☑ Compatibility with Lunar 2021 - -☑ Positive *and* negative weight support - -☑ Latching-switch support (LM Mini, LM Micra, etc) - -☑ Auto-reconnect - -☑ change setpoint over bluetooth - -☑ maintain setpoint and offset after powercycle - -☑ auto start/stop timer - -☑ flowrate-based shot end-time - -☑ auto timer reset - -⬜ Improve Pyxis Tare Command Reliability - - - -Scale Compatibility: - -☑ Acaia Pyxis - -☑ Acaia Lunar (usb-micro) - -☑ Acaia Lunar 2021 (usb-c) - -☑ Pearl S - -❌ Felicita Arc (buggy, see bug report) - -☑ Bookoo - -Hardware: - -☑ PCB Design for Low Voltage Switches (V1.1) - -☑ 3D-Printed Half Case - -☑ Compatibility with La Marzocco GS3 AV - -☑ Compatibility with Rancilio Silvia Pro (and Pro X) - -❌ Compatibility with La Marzocco Linea Classic S (Not Compatible, requires investigation) - -☑ Compatibility with Stone Espresso (requires reed switch) - -☑ Compatibility with La Marzocco Mini - -☑ Compatibility with La Marzocco Micra (V2.0) - -☑ Powered by espresso machine (V2.0) - -☑ Reed switch input (V2.0) - -☑ on-board esp32 module (V3.0) - -⬜ Compatibility with Breville (presumed but untested) - -⬜ Support for High-Voltage Switches (Hall-Effect Sensor and SSR?) - -Sales: - -☑ Beta Users Determined - -☑ Beta Units Built - -☑ Beta Units Shipped - -☑ Beta Test Complete - -☑ Sales Open For GS3, Silvia, and Micra In the US - -☑ Sales Open for Linea Mini - -☑ International Sales Open - -## Bugs/Missing -1. Tare command is less reliable than pressing the tare button. -2. Only supports grams. - -# Acknowledgement -This is largely a basic port of the [LunarGateway](https://github.com/frowin/LunarGateway/) library written for the ESP32. - -In addition to some minor notes from [pyacaia](https://github.com/lucapinello/pyacaia) library written for raspberryPI. - -Felicita Arc support contributions from baettigp - -Bookoo contributions from philgood - -lunar 2019 contributions from jniebuhr - +# AcaiaArduinoBLE +Acaia / Bookoo / AtomHeart Eclair Scale Gateway using the ArduinoBLE library for devices such as the esp32, arduino nano esp32, and arduino nano iot 33. +This is an Arduino Library which can be found in the Arduino IDE Library Manager. + +## Scale Compatibility + +| Mfr | Model | Submodel | Firmware | Connection Performance | Auto-Tare | Auto-Start/Stop Timer | Auto-Reset Timer | +| ------ | ------- | ------- |------- |------ | ------ |------ |------ | +| Acaia | Lunar | USB-Micro
(Pre-2021) | v2.6.019 | Great | Yes | Yes | Untested +| Acaia | Lunar | USB-C
(2021 version) | v1.0.016 | Hit or Miss | Yes | Yes | Yes +| Acaia | Pearl S | USB-Micro | v1.0.056 | Ok | Yes | Yes | Yes +| Acaia | Pearl S | USB-C | ---- | Ok | Yes | Yes | Yes +| Acaia | Pyxis | ---- | v1.0.022 | Good | Not Recommended (too sensitive) | Yes | Yes +| Bookoo | Themis Mini | ---- | v1.0.5 | Great | Yes | Yes | Yes +| Bookoo | Themis Ultra | ---- | ---- | Great | Yes | Yes | Yes +| AtomHeart | Eclair | ---- | v2.1.0 | Testing | Yes | Yes | Yes + + +## Requirements +This library is intended to be used with any arduino device which is compatible with the [ArduinoBLE](https://www.arduino.cc/reference/en/libraries/arduinoble/) library. + +As of version V2.0.0, non-volatile storage for the setpoint and offset is only available for ESP32-based devices. + +## Printed Circuit Board +![shotStopperV3 screenshot](https://github.com/user-attachments/assets/a09fe8fb-3705-44c0-88a2-07c61d67b8f6) + +The included "shotStopper" example code uses the ShotStopper PCB to make it simple to control your espresso machine using the scale. + +A kit can also be ordered by visiting [tatemazer.com](https://tatemazer.com/store) + +If you choose to build your own from scratch, v2.0 is recommended as it requires only through-hole components + +Join the discord for updates and support: https://discord.gg/NMXb5VYtre + +[![Video showing developmnent of the shotStopper](https://img.youtube.com/vi/434hrQDGtxo/0.jpg)](https://youtu.be/434hrQDGtxo) + +## Espresso Machine Compatibility + +| Model | Powered by Machine (5V) | Brew State Detection Method | Officially Documented | +| ----- | ----------------------- | --------------------------- | ---------------- | +| GS3 | No, requires included power supply | Solenoid Valve (Reed Switch) | Yes | +| Linea Micra | Yes | Brew Switch | Yes | +| Linea Mini* | Older, non-IoT machines may require a power supply | Brew Switch | Yes | +| Linea Mini R | Yes | Brew Switch | Yes | +| Silvia Pro (X) | Yes | Brew Button | Yes | +| Stone Espresso | Yes | Solenoid Valve (Reed Switch) | Yes | +| Ascaso Steel Duo PID | Untested | Brew Button | No +| Profitec Move | Yes | Brew Button | No | + +*Ace Dotshot is compatible with the shotStopper. Also note, shot duration is automated at the scale with the shotStopper, making the dotShot redundant. + +## ShotStopper Example Code Configuration + +The following variables at the top of the shotStopper.ino file can be configured by the user: + +`MOMENTARY` +* true for momentary switches such as GS3 AV, Rancilio Silvia Pro, etc. +* false for latching switches such as Linea Mini/Micra, stone, etc. + +`REEDSWITCH` +* true if a reed switch on the brew solenoid is being used to determine the brew state. This is typically not necessary so set to FALSE by default. This feature is only available for non-momentary-switches. + +`AUTOTARE` +* true by default. The scale will automatically tare when the shot is started, and, if MOMENTARY is false, will perform another tare at 3 seconds to notify the user that the switch is latched and should be returned to the home position. +* if set to false, the shotStopper will never send a tare command. It is the user's responsibility to tare before each shot. This may be helpful if the scale is not stable when the shot begins, and thus the scale is unable to tare reliably. + +`TIMER_ONLY` +* false by default. disables brew-by-weight functionality and enables only automatic timer and tare + +## Demo + +You can find a demo on Youtube: + +[![Video showing an shotStopper pulling a shot on a silvia pro](https://img.youtube.com/vi/oP3Cmke6daE/0.jpg)](https://www.youtube.com/shorts/oP3Cmke6daE) + +## Project Status + +Firmware: + +☑ Connect Acaia Pyxis to ESP32 + +☑ Tare Command + +☑ Receive Weight Data + +☑ shotStopper Espresso Machine Brew-By-Weight Firmware + +☑ Compatibility with Lunar (Pre-2021) + +☑ Compatibility with Lunar 2021 + +☑ Positive *and* negative weight support + +☑ Latching-switch support (LM Mini, LM Micra, etc) + +☑ Auto-reconnect + +☑ change setpoint over bluetooth + +☑ maintain setpoint and offset after powercycle + +☑ auto start/stop timer + +☑ flowrate-based shot end-time + +☑ auto timer reset + +⬜ Improve Pyxis Tare Command Reliability + + + +Scale Compatibility: + +☑ Acaia Pyxis + +☑ Acaia Lunar (usb-micro) + +☑ Acaia Lunar 2021 (usb-c) + +☑ Pearl S + +❌ Felicita Arc (buggy, see bug report) + +☑ Bookoo + +☑ AtomHeart Eclair + +Hardware: + +☑ PCB Design for Low Voltage Switches (V1.1) + +☑ 3D-Printed Half Case + +☑ Compatibility with La Marzocco GS3 AV + +☑ Compatibility with Rancilio Silvia Pro (and Pro X) + +❌ Compatibility with La Marzocco Linea Classic S (Not Compatible, requires investigation) + +☑ Compatibility with Stone Espresso (requires reed switch) + +☑ Compatibility with La Marzocco Mini + +☑ Compatibility with La Marzocco Micra (V2.0) + +☑ Powered by espresso machine (V2.0) + +☑ Reed switch input (V2.0) + +☑ on-board esp32 module (V3.0) + +⬜ Compatibility with Breville (presumed but untested) + +⬜ Support for High-Voltage Switches (Hall-Effect Sensor and SSR?) + +Sales: + +☑ Beta Users Determined + +☑ Beta Units Built + +☑ Beta Units Shipped + +☑ Beta Test Complete + +☑ Sales Open For GS3, Silvia, and Micra In the US + +☑ Sales Open for Linea Mini + +☑ International Sales Open + +## Bugs/Missing +1. Tare command is less reliable than pressing the tare button. +2. Only supports grams. + +# Acknowledgement +This is largely a basic port of the [LunarGateway](https://github.com/frowin/LunarGateway/) library written for the ESP32. + +In addition to some minor notes from [pyacaia](https://github.com/lucapinello/pyacaia) library written for raspberryPI. + +Felicita Arc support contributions from baettigp + +Bookoo contributions from philgood + +lunar 2019 contributions from jniebuhr + diff --git a/library.properties b/library.properties index 743c0a4..aa9fb75 100644 --- a/library.properties +++ b/library.properties @@ -1,11 +1,11 @@ -name=AcaiaArduinoBLE -version=3.3.0 -author=Tate Mazer -maintainer=Tate Mazer -sentence=A library that connects BLE devices to Acaia Scales. -paragraph=Uses the ArduinoBLE library and should support any BLE module. -category=Device Control -url=https://github.com/tatemazer/AcaiaArduinoBLE -architectures=esp32,samd -includes=AcaiaArduinoBLE.h -depends=ArduinoBLE \ No newline at end of file +name=AcaiaArduinoBLE +version=3.4.0 +author=Tate Mazer +maintainer=Tate Mazer +sentence=A library that connects BLE devices to Acaia, Bookoo, and AtomHeart Eclair scales. +paragraph=Uses the ArduinoBLE library and should support any BLE module. +category=Device Control +url=https://github.com/tatemazer/AcaiaArduinoBLE +architectures=esp32,samd +includes=AcaiaArduinoBLE.h +depends=ArduinoBLE