Just today I’m testing using a temp sensor on the side of the dryer near where the vent hose connects. I’m using the HA Trend sensor to watch as the temp rapidly rises and lowers. Currently I’m watching for a 4 degree rise within 5 minutes and then a drop within that time. I’m getting good results in seeing when the dryer is in use and not, usually within about 2 minutes of a start and stop cycle.
I’ve run my Aqara sensor setup a few more times (at high heat) and it works reliably so far.
I report “power on” when the temperature rises 5°f in less that 5 minutes, and “power off” when the temperature drops just 2°f (no time period, as the state must be “power on” before I report “power off”). I may want to increase the scant 2°f power down drop, but my dryer so far seems to maintain a drying temperature very consistently.
I plugged the above logic into a node-red “appliance load ready” notification flow that I wrote earlier for my washer and dishwasher, and, so far, the new dryer notification is working well, and is much more responsive then I would have expected.
It’s still working well. The generic “appliance” flow that I wrote earlier is somewhat complicated as it reports “idle”, “running” and “load ready” states using the power characteristics I obvserved in my own appliances and using open door sensors. The dryer actually turns out to be more responsive than monitoring the electrical power in my other dumb devices, and I can get fairly reliable electrical power usage from the dryer because I know that it uses a fixed wattage whenever it is on (if on high heat).
I’ll try to upload the whole thing to my GitHub account, but in the meantime here is the javascript in the node I use to detect and report the dryer state based on temperature changes.
// We are looking for a difference in temperature over
// time (a short time). Temperature values are in fahrenheit.
// state is one of:
// null - dryer idle
// "tracking" - Temperatire is rising, tracking to see if
// we will meet the "running" criteria
// "running" - dryer is running a load
// The state (and other data) is stored in a flow variable named <msg.topic>
// If state == null
// If we detect a temperatue increase
// We change state to "tracking"
// If state == "tracking"
// if the temp dif > 5°f
// We change state to "running"
// We send "power up"
// else if elasped time > 5 minutes
// We change mode to null
// if state == "running"
// If temperature drops 2°f from highest temperature
// We send "power down"
// We change state to null
let msgPowerUp;
let msgPowerDown;
let curTemp = Number(msg.payload);
let prevTemp;
// We seem to get msg.data.event.old_state.state OR msg.data.old_state.state
// Perhaos this will stablize?
if (msg.data) {
if (msg.data.old_state && msg.data.old_state.state) {
prevTemp = Number(msg.data.old_state.state);
} else if (msg.data.event.event.old_state && msg.data.old_state.event.state) {
prevTemp = Number(msg.data.event.old_state.state);
}
}
// Ignore spurious value (e.g., "undefined")
if (curTemp != NaN && prevTemp != NaN) {
let now = Date.now();
let device = flow.get(msg.topic);
if (curTemp > prevTemp) {
// Temperature rise
if (!device) {
device = { state: "tracking", timeStamp: now, temp: prevTemp };
}
if (device.state === "tracking") {
// We are tracking -- have we met requirement for "running",
// i.e., n° rise in less than n minutes
// 300000 = 5 min in milliseconds (5 * 60 * 1000)
// Note that checking the minimum time isn't really necessary
// because you'll see below that we change state to null if
// we've expired. There is the small possiblity that the sensor
// went offline for a while or some other anomaly.
if (curTemp - device.temp > 5 && now - device.timeStamp < 300000) {
// We are now "running"
// Specify our "start time" as when we started tracking
msg.startTime = device.timeStamp;
msgPowerUp = msg;
device.state = "running";
// in "running" mode .temp is now recording the highest temp
device.temp = curTemp;
}
} else {
// If we are not in "tracking" then we are in "running"
if (curTemp > device.temp) {
// Record highest temperature
device.temp = curTemp;
}
}
device.rising = true;
} else {
// Temperature drop
// Note we aren't checking the timespan here. If necessary we could set
// a timestamp in the flow var when temp first drops
if (device && device.state === "running") {
// We record the time when temperature first started dropping so
// we can have a better guesstimate of when the machine stopped
if (device.rising) {
device.timeStamp = now;
}
device.rising = false;
// Two degree fall? Probably will have to tweak this number.
if (device.temp - curTemp > 2) {
// Large temperature drop -- machine has turned off
// Specify our own "stop time"
msg.stopTime = device.timeStamp;
msgPowerDown = msg;
device = null;
}
}
}
// Time expired while tracking?
if (device && device.state === "tracking" && now - device.timeStamp >= 300000) {
// Too much time has passed without required temperature rise
// Change state to null
device = null;
}
flow.set(msg.topic, device);
msg.dev = device;
}
return [msgPowerUp, msgPowerDown];
Thank you for the code and details. And to be clear, you have this sensor in the machine?
That is already clear.
Just making sure. It’s been some time since his last post. You have your po-po hat on?
Yes, inside the machine, on a non moving part near the door, facing the drum. It’s holding up just fine using the original adhesive. If someone wanted to use hard rubber dryer balls in the load, I’d want to rethink it!
Haha! Makes absolute sense! Thanks
I have a SmaetDry too, could you share your code with me? I can get my APNS as I have the hardware and experience.
Thx
I personally won’t be working on this anymore. I’m not happy with the SmartDry, I’m replacing batteries monthly and I only use the dryer 4 times a month! (couple loads though). It’s just not cost effective.
That said, here’s the REST API sensor definition for what I’ve built:
# SmartDry
- platform: rest
name: SmartDry
json_attributes:
- active
- temperature
- humidity
- tempUnits
- shake
- shakecount
- rDate
- loadStart
- stDate
- LessDry
- Dry
- VeryDry
- tempUnits
resource: https://qn54iu63v9.execute-api.us-east-1.amazonaws.com/prod/RDSQuery
?Id=PPX9BZ&Write=1&SQLString=update%20DryerballList%20set%20PhoneEndpoint=%22arn
:aws:sns:us-east-1:074171373810:endpoint/APNS/SmartDryProduction/<APNS_HERE>%22,linkActive=1,phoneType=1
value_template: 'OK'
scan_interval: 5
Replace “<APNS_HERE>” with yours. That said, you may get a whole new resource URL in the bargain.
Have you tried moving the plug closer to the sensor? My batteries have lasted for months doing several loads each week.
Greetings everyone! I’ve been following this topic for a few months as I’m new to home assistant and was wondering if a SmartDry integration would ever come out…I emailed the creators and the above response is what I got. Unfortunately their answer has seemingly changed from “looking into it” to “no plans”
It also sucks that they don’t plan to offer any local control. As someone said on this topic a couple of years ago if the device requires a hub then it shouldn’t be too hard to allow local control along with the cloud control but according to them a significant rewrite would be required. I love local control which is one reason why I’ve been putting a lot of time into home assistant…I don’t mind cloud integration as backup but love the fact that if a server goes down or my internet goes down my devices won’t become paperweights. So it’s disappointing to see that no type of local control can be implemented with Smart Dry which means whenever that fateful date comes when they decide not to support this device anymore it will be a nice magnetic paperweight. My honeywell thermostat looks to be the same as they don’t seem to offer any local control either but that’s another story
I just wanted to give an update in case anyone was watching this thread hoping for integration or some type of control/reporting without the cloud
“There are no plans for local control, this would limit functionality our control of the data and require a substantial redesign of our data driven business model.”
Fixed that for them.
Don’t buy stuff like that. It only encourages them to create more of this cloud based crap.
Yeah, I didn’t like the cloud dependency. I ended up with a sonoff TH16 with waterproof temp sensor. I tucked the sensor inside one of the folds of the flexible exhaust hose. All local and working like a champ!
If you do/did manage to integrate this with HA I would be interested to see the method. The sensor works well but despite claims of integration with alexa it does not allow automation. The phone app works but is essentially useless. Did you manage to crack the API?
Yes, I did reverse engineer the API, but effectively I built a REST API integration that just emulates my actual phone. This isn’t something I can scale; though it worked really well for me.
Then my SmartDry died. I’ve changed the batteries, re-paired it to BT, it’s dead. Lasted about 4 months. Unfortunately, this path is a dead end, even if we did get it working reliably, the hardware itself is fragile and breaks.
Rob thanks for the response.
Mea culpa, on my tablet the rest of the forum did not scroll up immediately. I saw later your Rest approach but agree its too clumbsy and still ties you to the cloud.
My smartdry has yet to self destruct after approx 9 months but I will, like you, be seeking other alternatives.
It looks like based off my initial findings, that you only need the dryer’s ID for this to work, no APNs needed.
the URL is https://qn54iu63v9.execute-api.us-east-1.amazonaws.com/prod/RDSQuery?Id=<DRYER_ID>&Write=0&SQLString=%27select%20*%20from%20DryerballList%27
(this url was found from this github page – homebridge-smartdry/src at master · ablyler/homebridge-smartdry · GitHub )
Nice find! I can confirm that this works for me as well. As such, here is what folks need to build a SmartDry Sensor:
- platform: rest
name: SmartDry
json_attributes:
- active
- temperature
- humidity
- tempUnits
- shake
- shakecount
- rDate
- loadStart
- stDate
- LessDry
- Dry
- VeryDry
- tempUnits
resource: https://qn54iu63v9.execute-api.us-east-1.amazonaws.com/prod/RDSQuery?Id=DRYERID&Write=0&SQLString=%27select%20*%20from%20DryerballList%27
value_template: 'OK'
scan_interval: 5
Just replace “DRYERID” with your individual SmartDry ID which can be found in your App under Settings