Skip to content

Commit

Permalink
Dishwasher Mode added
Browse files Browse the repository at this point in the history
see issue #333
  • Loading branch information
rg-engineering committed Feb 27, 2025
1 parent c94e12c commit 8bb3708
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 18 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ An description about general usage of energy requests see [SMA docu](https://git
## Requirements


## Dishwasher Mode

The adapter can be used to control a dishwasher. The dishwasher is switched on when there is enough solar energy.
Details of implementation can be found in issue #333.

![Flowchart](https://github.com/rg-engineering/ioBroker.semp/blob/master/docu/settings/semp_dishwasher_sequence.png)



## known issues
* please create issues at [github](https://github.com/rg-engineering/ioBroker.semp/issues) if you find bugs or whish new features

Expand Down
Binary file added docu/settings/semp_dishwasher_sequence.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
161 changes: 149 additions & 12 deletions lib/semp/Device.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,18 @@ class Device {
startCharge: "charge starting",
charging: "charging",
fastCharging: "fast charging",
stopCharge: "charge stopping"
stopCharge: "charge stopping",
//dishwasher
off: "off",
TimeframeOn: "Timeframe On",
FinishedWaiting4TF: "FinishedWaiting4TF",
TFendedWaiting4Device: "TFendedWaiting4Device",
TFended: "TFended",
DeviceFinished: "DeviceFinished",
DeviceInStandby:"DeviceInStandby"



};

this.Gateway = gateway;
Expand All @@ -146,7 +157,8 @@ class Device {
MinEnergy: 0.1 * this.device.BatteryCapacity,
MinPower: this.device.MinPower,
MaxPower: this.device.MaxPower,
WallboxChargeTime: this.device.WallboxChargeTime
WallboxChargeTime: this.device.WallboxChargeTime,
DishWasherMode: (this.device.Type == "DishWasher") ? true : false
};

this.planningrequest = null;
Expand Down Expand Up @@ -431,6 +443,15 @@ class Device {

}



if (device.Type == "DishWasher") {
this.dishwasherstate = this.states.off;
this.DishwasherSwitchState = "Off";
this.DishWasherRecommendation = false;
this.DishwasherStatusTimerID = setInterval(this.DishWasherSequence.bind(this), 10*1000);
}

this.deviceStatus = {
DeviceId: device.ID,
EMSignalsAccepted: true,
Expand Down Expand Up @@ -479,6 +500,11 @@ class Device {
this.CancelRequestTimerID = null;
}

if (this.DishwasherStatusTimerID) {
clearTimeout(this.DishwasherStatusTimerID);
this.DishwasherStatusTimerID = null;
}

for (let i = 0; i < this.UrlTimerId.length; i++) {
clearInterval(this.UrlTimerId[i]);
this.UrlTimerId[i] = null;
Expand Down Expand Up @@ -512,6 +538,12 @@ class Device {

await this.Switch(false);
}
async SwitchOn() {

this.Gateway.parentAdapter.log.debug(this.device.Name + " turn device on");

await this.Switch(true);
}

setLastPower(watts, minPower, maxPower) {

Expand Down Expand Up @@ -548,6 +580,7 @@ class Device {
//going to on
if (this.deviceStatus.Status == "On" || this.StatusDetectionOnTimerID != null) {
//nothing to do, already true or timer started
this.Gateway.parentAdapter.log.debug(this.device.Name + " already on, no timer start");
}
else {
this.StatusDetectionOnTimerID = setTimeout(this.SetStatusOn.bind(this), this.device.StatusDetectionLimitTimeOn * 60 * 1000);
Expand Down Expand Up @@ -633,13 +666,6 @@ class Device {
}

setOnOff(state) {
//could be On, Off, Offline
this.Gateway.parentAdapter.log.debug(this.device.Name + " setState " + state);
this.deviceStatus.Status = state;

if (this.planningrequest != null) {
this.planningrequest.SetDeviceStatus(state);
}

if (state == "On") {
//cancel timer if running
Expand All @@ -648,6 +674,26 @@ class Device {
this.CancelRequestTimerID = null;
}
}

if (this.device.Type == "DishWasher") {

//just store the state
this.DishwasherSwitchState = state;

}
else {


//could be On, Off, Offline
this.Gateway.parentAdapter.log.debug(this.device.Name + " setState " + state);
this.deviceStatus.Status = state;

if (this.planningrequest != null) {
this.planningrequest.SetDeviceStatus(state);
}


}
this.SetState();

if (this.device.MeasurementMethod == "Estimation") {
Expand All @@ -666,6 +712,87 @@ class Device {

}

DishWasherSequence() {
//squence see draw.io diagram

let lastDishwasherState = this.dishwasherstate;

this.deviceStatus.Status = "Off";

if (this.dishwasherstate == this.states.off) {

//check if timeframe is active
if (this.planningrequest != null && this.planningrequest.getAnyTimefraneActive()) {
this.dishwasherstate = this.states.TimeframeOn;
}
}
else if (this.dishwasherstate == this.states.TimeframeOn) {
//now waitung until user switches device on
if (this.DishwasherSwitchState == "On") {
this.dishwasherstate = this.states.waiting4On;

//switch off the device completely
this.SwitchOff();


//todo erst mal auf Off warten?
}

}
else if (this.dishwasherstate == this.states.waiting4On) {
//now waitung for On-recommndation
if (this.DishWasherRecommendation) {
this.dishwasherstate = this.states.on;
this.Gateway.parentAdapter.log.debug(this.device.Name + " set new recommendation state to on" );

this.Switch(true);
this.dishwasherstate = this.states.on;
}
if (this.planningrequest == null || this.planningrequest.getAnyTimefraneActive() == false) {
this.dishwasherstate = this.states.TFended;
}

}
else if (this.dishwasherstate == this.states.on) {
this.deviceStatus.Status = "On";

if (this.planningrequest == null || this.planningrequest.getAnyTimefraneActive()==false) {
this.dishwasherstate = this.states.TFendedWaiting4Device;
}
if (this.DishwasherSwitchState == "Off") {
this.dishwasherstate = this.states.FinishedWaiting4TF;
}
}
else if (this.dishwasherstate == this.states.FinishedWaiting4TF) {
if (this.planningrequest == null || this.planningrequest.getAnyTimefraneActive() == false) {
this.dishwasherstate = this.states.TFended;
}
}
else if (this.dishwasherstate == this.states.TFendedWaiting4Device) {
this.deviceStatus.Status = "On";
if (this.DishwasherSwitchState == "Off") {
this.dishwasherstate = this.states.DeviceFinished;
}
}
else if (this.dishwasherstate == this.states.TFended) {
this.dishwasherstate = this.states.DeviceInStandby;
}
else if (this.dishwasherstate == this.states.DeviceFinished) {
this.dishwasherstate = this.states.DeviceInStandby;
}
else if (this.dishwasherstate == this.states.DeviceInStandby) {
//check if timeframe is active
if (this.planningrequest != null && this.planningrequest.getAnyTimefraneActive()) {
this.dishwasherstate = this.states.TimeframeOn;
}
}
if (lastDishwasherState != this.dishwasherstate) {
//log only if state changed
this.Gateway.parentAdapter.log.debug(this.device.Name + " new dishwasher state " + this.dishwasherstate);
}
}


async sendEMRecommendation(em2dev) {

if (this.device.Type == "EVCharger" && this.isFastCharging) {
Expand Down Expand Up @@ -843,9 +970,19 @@ class Device {

if (this.device.HasOIDSwitch) {

this.Gateway.parentAdapter.log.debug(this.device.Name + " set new recommendation state to " + value);
if (this.device.Type == "DishWasher") {
this.DishWasherRecommendation = value;
}
else {


this.Gateway.parentAdapter.log.debug(this.device.Name + " set new recommendation state to " + value);

await this.Switch(value);
}



await this.Switch(value);
}
if (this.device.Type == "EVCharger") {
if (value) {
Expand Down Expand Up @@ -1278,7 +1415,7 @@ class Device {
this.Gateway.parentAdapter.log.debug(this.device.Name + " in SetState, set new state " + state);
}
else {
this.Gateway.parentAdapter.log.debug(this.device.Name + " in SetState, no new state to set");
this.Gateway.parentAdapter.log.debug(this.device.Name + " in SetState, no new state to set, is " + state);
}
}

Expand Down
18 changes: 17 additions & 1 deletion lib/semp/Planningrequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ class Planningrequest {
const settings = {
EnergyRequestPeriod: this.settings.EnergyRequestPeriods[r],
DeviceName: this.settings.DeviceName,
SwitchOffAtEndOfTimer: this.settings.SwitchOffAtEndOfTimer
//SwitchOffAtEndOfTimer: this.settings.SwitchOffAtEndOfTimer
//xxx
DishWasherMode: this.settings.DishWasherMode
};

this.parentAdapter.log.debug("planningrequest " + JSON.stringify(this.settings) + " " + JSON.stringify(settings));
Expand Down Expand Up @@ -127,6 +129,20 @@ class Planningrequest {
return PlanningrequestData;
}

getAnyTimefraneActive() {

let bRet = false;
for (let t = 0; t < this.timeframes.length; t++) {
if (this.timeframes[t].GetIsActive()) {
bRet = true;
}

}

return bRet;
}


Check2Switch() {

let SwitchOff = false;
Expand Down
24 changes: 19 additions & 5 deletions lib/semp/Timeframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Timeframe {

this.settings = settings.EnergyRequestPeriod;
this.deviceName = settings.DeviceName;
this.DishWasherMode = settings.DishWasherMode;

this.isActive = false;
this.parentAdapter = parentAdapter;
Expand Down Expand Up @@ -196,17 +197,17 @@ class Timeframe {

const current = await this.parentAdapter.getStateAsync(key);

this.parentAdapter.log.debug(key + ": timeframe " + JSON.stringify(current));
//this.parentAdapter.log.debug(key + ": timeframe " + JSON.stringify(current));

if (current != null) {

if (current.val == true || current.val == "true") {
this.enabled = true;
this.parentAdapter.log.debug( "timeframe enabled " );
//this.parentAdapter.log.debug( "timeframe enabled " );
}
else {
this.enabled = false;
this.parentAdapter.log.debug( "timeframe disabled ");
//this.parentAdapter.log.debug( "timeframe disabled ");
}
}
}
Expand Down Expand Up @@ -312,8 +313,17 @@ class Timeframe {


if (this.EarliestStart == 0 && this.LatestEnd == 0) {
SwitchOff = true;
this.parentAdapter.log.debug(this.deviceName + " turn device off at end of LatestEnd");


//xxx hier im Spülmaschinen-Modus nicht ausschalten
if (this.DishWasherMode) {
this.parentAdapter.log.debug(this.deviceName + " not to turn device off at end of LatestEnd, dishwasher");
}
else {
SwitchOff = true;
this.parentAdapter.log.debug(this.deviceName + " turn device off at end of LatestEnd");

}
this.isActive = false;
this.Start();
}
Expand Down Expand Up @@ -539,6 +549,10 @@ class Timeframe {
this.parentAdapter.setState(key, { ack: true, val: val });
}


GetIsActive() {
return this.isActive;
}
}


Expand Down

0 comments on commit 8bb3708

Please sign in to comment.