Skip to content

Commit

Permalink
Send current weight to MQTT
Browse files Browse the repository at this point in the history
Remove extra comma

Improve calbration progress messges

Don't tare the scale while the calibration load is very likely still on it

Add tare and calibrate buttons to MQTT

Fix wrong section IDs in web page

Only include scale handlers in webserver if scale is enabled

Remove scale related code from time-based brewing mode

Exclude scale related code when scale is not enabled in userconfig

Minor formatting fixes
  • Loading branch information
einarhauks authored and FabianSperrle committed Jan 19, 2024
1 parent 88c8e6d commit e8d7458
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 40 deletions.
2 changes: 1 addition & 1 deletion data/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const vueApp = Vue.createApp({
1: 'Temperature and Preinfusion',
2: 'Brew Detection and Brew PID Parameters',
3: 'Power Settings',
3: 'Scale Parameters'
4: 'Scale Parameters'
}
return sectionNames[sectionId]
}
Expand Down
2 changes: 2 additions & 0 deletions src/EmbeddedWebserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ void serverSetup() {
request->redirect("/");
});

#if (ONLYPIDSCALE == 1 || BREWMODE == 2)
server.on("/toggleTare", HTTP_POST, [](AsyncWebServerRequest *request) {
int tare = flipUintValue(tareON);

Expand All @@ -285,6 +286,7 @@ void serverSetup() {

request->redirect("/");
});
#endif

server.on("/parameters", HTTP_GET | HTTP_POST, [](AsyncWebServerRequest *request) {
// Determine the size of the document to allocate based on the number
Expand Down
118 changes: 89 additions & 29 deletions src/MQTT.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,56 @@ DiscoveryObject GenerateSwitchDevice(String name, String displayName, String pay
return switch_device;
}

/**
* @brief Generate a button device for Home Assistant MQTT discovery
*
* This function generates a button device configuration for Home Assistant MQTT discovery. It creates a `DiscoveryObject` containing the necessary information for Home Assistant to discover and control the button device.
*
* @param name The name of the button (used in MQTT topics)
* @param displayName The display name of the button (shown in Home Assistant)
* @param payload_press The payload value to turn the button is pressed (default: "1")
* @return A `DiscoveryObject` containing the switch device configuration
*/
DiscoveryObject GenerateButtonDevice(String name, String displayName, String payload_press = "1") {
String mqtt_topic = String(mqtt_topic_prefix) + String(hostname);
DiscoveryObject button_device;
String unique_id = "clevercoffee-" + String(hostname);
String buttonDiscoveryTopic = String(MQTT_HASSIO_DISCOVERY_PREFIX) + "/button/";

String button_command_topic = mqtt_topic + "/"+ name +"/set";
String button_state_topic = mqtt_topic + "/"+ name;

button_device.discovery_topic = buttonDiscoveryTopic + unique_id + "-"+ name +"" +"/config";

DynamicJsonDocument DeviceMapDoc(1024);
char DeviceMapBuffer[256];
DeviceMapDoc["identifiers"] = String(hostname);
DeviceMapDoc["manufacturer"] = "CleverCoffee";
DeviceMapDoc["model"] = getMachineName(machine);
DeviceMapDoc["name"] = String(hostname);

DynamicJsonDocument buttonConfigDoc(512);
buttonConfigDoc["name"] = displayName;
buttonConfigDoc["command_topic"] = button_command_topic;
buttonConfigDoc["state_topic"] = button_state_topic;
buttonConfigDoc["unique_id"] = unique_id + "-"+name;
buttonConfigDoc["payload_press"] = payload_press;
buttonConfigDoc["payload_available"] = "online";
buttonConfigDoc["payload_not_available"] = "offline";
buttonConfigDoc["availability_topic"] = mqtt_topic+"/status";

JsonObject buttonDeviceField = buttonConfigDoc.createNestedObject("device");
for (JsonPair keyValue : DeviceMapDoc.as<JsonObject>()) {
buttonDeviceField[keyValue.key()] = keyValue.value();
}

String buttonConfigDocBuffer;
serializeJson(buttonConfigDoc, buttonConfigDocBuffer);
debugPrintln("Generated button device");
button_device.payload_json = buttonConfigDocBuffer;
return button_device;
}

/**
* @brief Generate a sensor device for Home Assistant MQTT discovery
*
Expand Down Expand Up @@ -465,43 +515,53 @@ int sendHASSIODiscoveryMsg() {
DiscoveryObject actual_temperature = GenerateSensorDevice("temperature", "Boiler Temperature");
DiscoveryObject heaterPower = GenerateSensorDevice("heaterPower", "Heater Power", "%", "power_factor");
DiscoveryObject machineStateDevice = GenerateSensorDevice("machineState", "Machine State", "null", "enum");
DiscoveryObject currentWeight = GenerateSensorDevice("currentWeight", "Weight", "g", "weight");

// Switch Devices
DiscoveryObject pidOn = GenerateSwitchDevice("pidON", "Use PID");
DiscoveryObject steamON = GenerateSwitchDevice("steamON", "Steam");
DiscoveryObject backflushOn = GenerateSwitchDevice("backflushOn", "Backflush");
DiscoveryObject startUsePonM = GenerateSwitchDevice("startUsePonM", "Use PonM");

// Define an array to store the DiscoveryObject instances
DiscoveryObject discoveryObjects[] = {
// Button Devices
DiscoveryObject scaleCalibrateButton = GenerateButtonDevice("calibrationON", "Calibrate Scale");
DiscoveryObject scaleTareButton = GenerateButtonDevice("tareON", "Tare Scale");


std::vector<DiscoveryObject> discoveryObjects = {
brewSetpoint,
steamSetPoint,
brewTempOffset,
brewPidDelay,
startKp,
startTn,
steamKp,
aggKp,
aggTn,
aggTv,
aggIMax,
actual_temperature,
heaterPower,
machineStateDevice,
brewtime,
pidOn,
steamON,
backflushOn,
startUsePonM
};

const int numDiscoveryObjects = sizeof(discoveryObjects) / sizeof(discoveryObjects[0]);

// Send the Objects to Hassio
if (mqtt.connected()) {
for (int i = 0; i < numDiscoveryObjects; i++) {
const DiscoveryObject& discoveryObj = discoveryObjects[i];
int publishResult = PublishLargeMessage(discoveryObj.discovery_topic.c_str(), discoveryObj.payload_json.c_str());
steamSetPoint,
brewTempOffset,
brewPidDelay,
startKp,
startTn,
steamKp,
aggKp,
aggTn,
aggTv,
aggIMax,
actual_temperature,
heaterPower,
machineStateDevice,
brewtime,
pidOn,
steamON,
backflushOn,
startUsePonM,
};

#if (BREWMODE == 2 || ONLYPIDSCALE == 1)
discoveryObjects.push_back(currentWeight);
discoveryObjects.push_back(scaleCalibrateButton);
discoveryObjects.push_back(scaleTareButton);
#endif


// Send the Objects to Hassio
if (mqtt.connected()) {
for (int i = 0; i < discoveryObjects.size(); i++) {
const DiscoveryObject& discoveryObj = discoveryObjects[i];
int publishResult = PublishLargeMessage(discoveryObj.discovery_topic.c_str(), discoveryObj.payload_json.c_str());

if (publishResult != 0) {
debugPrintf("[MQTT] Failed to publish discovery message. Error code: %d\n", publishResult);
Expand Down
2 changes: 1 addition & 1 deletion src/Storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ static const sto_data_t itemDefaults PROGMEM = {
STEAMKP, // STO_ITEM_PID_KP_STEAM
STEAMSETPOINT, // STO_ITEM_STEAM_SETPOINT
STANDBY_MODE_ON, // STO_ITEM_STANDBY_MODE_ON
STANDBY_MODE_TIME, // STO_ITEM_STANDBY_MODE_TIME
STANDBY_MODE_TIME // STO_ITEM_STANDBY_MODE_TIME
};

/**
Expand Down
8 changes: 1 addition & 7 deletions src/brewvoid.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,11 @@ void brew() {
if (OnlyPID == 0) {
unsigned long currentMillisTemp = millis();
checkbrewswitch();
double brewDelay = 0;

if (brewSwitch == LOW && brewCounter > kBrewIdle) {
// abort function for state machine from every state
debugPrintln("Brew stopped manually");
brewCounter = kWaitBrewOff;
brewDelay = scaleDelayValue;
}

if (brewCounter > kBrewIdle && brewCounter < kWaitBrewOff) {
Expand Down Expand Up @@ -334,10 +332,7 @@ void brew() {
digitalWrite(PIN_VALVE, relayOff);
digitalWrite(PIN_PUMP, relayOff);
brewCounter = kWaitBrewOff;
brewDelay = timeBrewed + scaleDelayValue;
if (timeBrewed > brewDelay) {
timeBrewed = 0;
}
timeBrewed = 0;

break;

Expand Down Expand Up @@ -444,7 +439,6 @@ void brew() {
break;

case 41: // waiting time brew
lastbrewTime = timeBrewed;
if (timeBrewed > totalBrewTime || (weightBrew > (weightSetpoint - scaleDelayValue))) {
brewCounter = kBrewFinished;
}
Expand Down
8 changes: 8 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1967,6 +1967,7 @@ void setup() {
.ptr = (void *)&standbyModeTime
};

#if (ONLYPIDSCALE == 1 || BREWMODE == 2)
editableVars["TARE_ON"] = {
.displayName = F("Tare"),
.hasHelpText = false,
Expand Down Expand Up @@ -2018,6 +2019,7 @@ void setup() {
.maxValue = 100000,
.ptr = (void *)&scaleCalibration
};
#endif

editableVars["VERSION"] = {
.displayName = F("Version"),
Expand Down Expand Up @@ -2085,6 +2087,10 @@ void setup() {
mqttSensors["currentKi"] = []{ return bPID.GetKi(); };
mqttSensors["currentKd"] = []{ return bPID.GetKd(); };
mqttSensors["machineState"] = []{ return machineState; };
#if (BREWMODE == 2 || ONLYPIDSCALE == 1)
mqttSensors["currentWeight"] = []{ return weight; };
#endif


Serial.begin(115200);

Expand Down Expand Up @@ -2543,13 +2549,15 @@ void setBackflush(int backflush) {
backflushOn = backflush;
}

#if (ONLYPIDSCALE == 1 || BREWMODE == 2)
void setCalibration(int calibration) {
calibrationON = calibration;
}

void setTare(int tare) {
tareON = tare;
}
#endif

void setSteamMode(int steamMode) {
steamON = steamMode;
Expand Down
12 changes: 10 additions & 2 deletions src/scalevoid.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ void calibrate() {
u8g2.drawStr(0, 22, "Calibration coming up");
u8g2.drawStr(0, 32, "Empty the scale");
u8g2.sendBuffer();
debugPrintf("Taking scale zero point\n");
LoadCell.update();
LoadCell.tare();
delay(2000);
debugPrintf("Put load on scale\n");
u8g2.clearBuffer();
u8g2.drawStr(2, 2, "Calibration in progress.");
u8g2.drawStr(2, 12, "Place known weight");
Expand All @@ -26,13 +28,19 @@ void calibrate() {
u8g2.drawStr(2, 42, number2string(scaleKnownWeight));
u8g2.sendBuffer();
delay(10000);
debugPrintf("Taking scale load point\n");
LoadCell.refreshDataSet();
scaleCalibration = LoadCell.getNewCalibration(scaleKnownWeight);
LoadCell.setCalFactor(scaleCalibration);
debugPrintf("New calibration: %f\n", scaleCalibration);
u8g2.sendBuffer();
writeSysParamsToStorage();
delay(2000);
LoadCell.tare();
u8g2.clearBuffer();
u8g2.drawStr(2, 2, "Calibration done!");
u8g2.drawStr(2, 12, "New calibration:");
u8g2.drawStr(2, 22, number2string(scaleCalibration));
u8g2.sendBuffer();
delay(5000);

}

Expand Down

0 comments on commit e8d7458

Please sign in to comment.