Basic Idea
I wanted to add my anova sous vide stick (WiFi Version) status to openhab. Therefor we need to get the information from the (undocumented) API and parse it into openhab.
Later I will add some options to start / stop the stick, set timers etc.
Prerequisites
You need your credentials for the API. I found two ways
- Get the information from your rooted android phone (not tested since my phone is not rooted)
https://forum.fhem.de/index.php?topic=56697.0
$ cat /data/data/com.anovaculinary.android/shared_prefs/com.anovaculinary.android_preferences.xml
- Get the information via man in the midle attack in your home WiFi
https://github.com/bmedicke/anova.py/blob/master/readme.md
anova.rules
var String anova_cooker = "anova%20fxxxxyxxyxyxx2"
var String anova_secret = "xxxxxxxx"
rule "Check Anova Status"
when
Time cron "0 0/1 * * * ?"
then
logInfo( "anova.rules" , "Rule triggered")
var String Anova_ApiCall = "https://api.anovaculinary.com/cookers/%s?secret=%s"
var Integer minute = now.getMinuteOfHour
// Get Info every 5 Minutes or every minute if anova is running to avoid spamming API
if( (minute%5) == 0 || Anova_Status.state == ON ){
logInfo( "anova.rules" , "Requesting API Data")
var String Anova_Answer = sendHttpGetRequest(String::format(Anova_ApiCall, anova_cooker , anova_secret))
// logInfo( "anova.rules" , Anova_Answer)
// Check JSON answer for Status
var String Anova_online = transform( "JSONPATH", "$.error.code" , Anova_Answer)
if( Anova_online == "404" ){
// Anova Offline
Anova_Online.sendCommand( OFF )
Anova_Status.sendCommand( OFF )
Anova_Current_job.postUpdate( "-" )
Anova_Timer_running.postUpdate( OFF )
Anova_Timer_remaining.postUpdate( -1 )
Anova_Target_temp.postUpdate(-1)
Anova_Current_temp.postUpdate( -1 )
}else{
// Anova Online
Anova_Online.sendCommand( ON )
// Anova temperatures
Anova_Target_temp.postUpdate( Double::parseDouble( transform( "JSONPATH" , "$.status.target_temp" , Anova_Answer) ))
Anova_Current_temp.postUpdate( Double::parseDouble( transform( "JSONPATH" , "$.status.current_temp" , Anova_Answer) ))
// Anova status (running or not)
var String Anova_running = transform( "JSONPATH" , "$.status.is_running", Anova_Answer)
if( Anova_running == "true" ){
Anova_Status.sendCommand( ON )
// Get job information
Anova_Current_job.postUpdate( transform( "JSONPATH" , "$.status.current_job_id", Anova_Answer) )
// Timer
var String anova_timer = transform( "JSONPATH" , "$.status.is_timer_running", Anova_Answer)
if( anova_timer == "false"){
// No timer running
Anova_Timer_running.postUpdate( OFF )
Anova_Timer_remaining.postUpdate( -1 ) // -1 as default if no timer running
}else{
Anova_Timer_running.postUpdate( ON )
var Number anova_timer_remaining = Integer::parseInt( transform( "JSONPATH" , "$.status.timer_length", Anova_Answer))/60
Anova_Timer_remaining.postUpdate( anova_timer_remaining )
}
}else{
// Anova not running
Anova_Status.sendCommand( OFF )
Anova_Current_job.postUpdate( "-" )
Anova_Timer_running.postUpdate( OFF )
Anova_Timer_remaining.postUpdate( -1 )
}
}
}
end