[DzVents] Lave-linge Samsung
Publié : 18 sept. 2021, 23:46
Bonjour à tous
Au retour de vacances, après 1 décennies de bon et loyaux services, mon lave-linge est décédé.
S'en est alors suivi un tas de recherches, de benchmarks, de comparatifs... PAS DU TOUT !
Il me fallait une machine rapidement, correspondant à un budget quelque peu réduit par des congés bien mérités.
Mon dévolu s'est donc porté sur ce modèle (en stock, en promo et avec un ODR de 50€).
Cerise sur le gâteau, c'est un modèle connecté (c'était vraiment pas voulu, promis
).
J'avais connecté mon ancienne machine en lisant l'état des LED en façade.
Ici, pas besoin de capteur, elle est connectée en wifi (Yes !) mais passe par le cloud (Noooo !).
Pas d'accès local possible (j'ai scanné tous les ports
), tant pis, on fera avec et si un jour ça coupe, une prise qui mesure la puissance fera le job.
En attendant, un script adapté du forum officiel me permet de nouveau d'avoir ma notif de fin de lessive avec quelques bonus
Sans plus attendre, le script :
SamsungLaveLinge.lua
Il doit être possible de piloter le lave linge à distance mais c'est déjà pas vraiment simple via l'appli smartthings, alors via domoticz...
Au retour de vacances, après 1 décennies de bon et loyaux services, mon lave-linge est décédé.
S'en est alors suivi un tas de recherches, de benchmarks, de comparatifs... PAS DU TOUT !
Il me fallait une machine rapidement, correspondant à un budget quelque peu réduit par des congés bien mérités.
Mon dévolu s'est donc porté sur ce modèle (en stock, en promo et avec un ODR de 50€).
Cerise sur le gâteau, c'est un modèle connecté (c'était vraiment pas voulu, promis
J'avais connecté mon ancienne machine en lisant l'état des LED en façade.
Ici, pas besoin de capteur, elle est connectée en wifi (Yes !) mais passe par le cloud (Noooo !).
Pas d'accès local possible (j'ai scanné tous les ports
En attendant, un script adapté du forum officiel me permet de nouveau d'avoir ma notif de fin de lessive avec quelques bonus
Sans plus attendre, le script :
SamsungLaveLinge.lua
Code : Tout sélectionner
-- Source : https://www.domoticz.com/forum/viewtopic.php?p=237384#p237384
-- SETUP YOUR API CONFIGURATION HERE --
-- API key from https://account.smartthings.com/tokens (You'll need to register first and ensure your machine is on the same account)
-- Device ID from https://graph-eu01-euwest1.api.smartthings.com/device/list (click on your machine, then use the number in the URL after the last /)
local API = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx'
local wmDevice = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
-- CREATE YOUR OWN OUTPUTS HERE --
-- Create virtual sensors in Domoticz Hardware settings that will show the output from the washing machine.
-- Names are suggested [in square brackets], you need to input the device ID in (brackets) below.
local TEST_SWITCH = (81) -- Virtual on switch to activated the script manually for testing.
local WM_PROGRAM = ("LL - Programme") -- Virtual device showing washing machine Program - Device type = text
local WM_COMPLETION = ("LL - Heure de Fin") -- Virtual device showing washing cycle completion time - Device type = text
local WM_SPIN = ("LL - Essorage") -- Virtual device showing washing spin state - Device type = text
local WM_REMAINING = ("LL - Temps Restant") -- Virtual device showing time remaining on wash - Device type = text
local WM_TEMP = ("LL - Temperature") -- Virtual device showing washing machine Temperature - Device type = text
local WM_STATUS = ("Lave-Linge") -- Virtual device showing washing machine On/Off - Device type = on/off switch
local WM_PERCENT = ("LL - Progression") -- Virtual device showing washing machine percentage - Device type = percentage
local WM_STATE = ("LL - Etat") -- Virtual device showing washing cycle state - Device type = text
-- ------------------------
local wmScriptVar = 'WashingMachine'
--Convert Table_00_Course_* and WashingState to French
local function codeToFrench(dz, code)
local translationcode =
{
Table_00_Course_D0 = 'Lavage Coton',
Table_00_Course_D1 = 'Eco Coton',
Table_00_Course_D2 = 'Synthetique',
Table_00_Course_D3 = 'Délicat',
Table_00_Course_D4 = 'Rinçage & Essorage',
Table_00_Course_D5 = 'Nettoyage Tambour',
Table_00_Course_D6 = 'Draps',
Table_00_Course_D7 = 'Extérieur',
Table_00_Course_D8 = 'Laine',
Table_00_Course_D9 = 'Foncé',
Table_00_Course_DA = 'Super Eco ',
Table_00_Course_DB = 'Super Rapide',
Table_00_Course_DC = '15\' Rapide',
Table_00_Course_BA = 'Essorage',
Table_02_Course_1B = 'Coton',
Table_02_Course_1C = 'Eco 40-60',
Table_02_Course_1D = 'Super Rapide',
Table_02_Course_1E = 'Express 15\'',
Table_02_Course_1F = 'Intensif à Froid',
Table_02_Course_20 = 'Anti-allergènes',
Table_02_Course_21 = 'Couleurs',
Table_02_Course_22 = 'Laine',
Table_02_Course_23 = 'Extérieur',
Table_02_Course_24 = 'Draps',
Table_02_Course_25 = 'Synthétiques',
Table_02_Course_26 = 'Délicat',
Table_02_Course_27 = 'Rinçage + Essorage',
Table_02_Course_28 = 'Vidange / Essorage',
Table_02_Course_29 = 'Nettoyage Tambour',
Table_02_Course_2A = 'Jeans',
Table_02_Course_2B = 'All Wash',
Table_02_Course_2D = 'Lavage Silencieux',
Table_02_Course_2E = 'Bébé Coton',
Table_02_Course_2F = 'Sport',
Table_02_Course_30 = 'Journée Nuageuse',
Table_02_Course_32 = 'Chemises',
Table_02_Course_33 = 'Serviette',
Table_02_Course_34 = 'Mix',
none = 'Pas de programme actif',
weightSensing = 'Pesage',
wash = 'Lavage',
rinse = 'Rinçage',
spin = 'Essorage',
finish = 'Fin',
}
local code = tostring(code)
local translatedCode = translationcode[code]
if translatedCode == nil then
dz.log('codeToFrench: Found unknown code: ' .. tostring(code),dz.LOG_ERROR )
end
return translatedCode or '?'
end
--Update text devices only when status is changed to prevent too many irrelevant log rows
local function updateTextOnlyWhenChanged(dz, textSensorName, newText)
dz.log(textSensorName.." : "..newText,dz.LOG_DEBUG)
if textSensorName ~= nil then
local textDevice = dz.devices(textSensorName)
if textDevice.text ~= newText then
textDevice.updateText(newText)
end
end
end
--Update percentage devices only when status is changed to prevent too many irrelevant log rows
local function updatePercentageOnlyWhenChanged(dz, percentageSensorName, newPercentage)
dz.log(percentageSensorName.." : "..newPercentage,dz.LOG_DEBUG)
if percentageSensorName ~= nil then
local percentageDevice = dz.devices(percentageSensorName)
if percentageDevice.percentage ~= newPercentage then
-- percentage.updatePercentage(newPercentage)
percentageDevice.updatePercentage(newPercentage)
end
end
end
--Update switch selector devices only when exists
local function updateSelectorOnlyWhenExists(dz, switchName, newState)
dz.log(switchName.." : "..newState,dz.LOG_DEBUG)
if switchName ~= nil then
local switch = dz.devices(switchName)
if newState == 'Pas de programme actif' then
--switch.switchOff().checkFirst()
switch.switchSelector(newState).checkFirst()
else
switch.switchSelector(newState).checkFirst()
end
end
end
--Convert the time to Hour,Minute,second.
local function convertTime(dz,dateString)
dz.log("date de fin : "..dateString,dz.LOG_DEBUG)
local pattern = '(%d+)%-(%d+)%-(%d+)%T(%d+):(%d+):(%d+)(%.*)' -- %d+ = 1 or more digits , %.* = 0 or more any character
local xyear, xmonth, xday, xhour, xminute, xseconds = dateString:match(pattern) -- split the string using the pattern
local convertedTimestamp = os.time({year = xyear, month = xmonth, day = xday, hour = xhour, min = xminute, sec = xseconds, isdst = os.date("*t", os.time()).isdst})
local now = os.time()
tz = os.difftime(now, os.time(os.date("!*t", now)))/3600
if os.date("*t", os.time()).isdst then tz = tz + 1 end
return os.date('%H:%M:%S', convertedTimestamp + (3600*tz))
end
return
{
active = true,
on =
{
timer =
{
'every minute', -- just an example to trigger the request
},
devices =
{
TEST_SWITCH, -- Just on Switch to activated the script manually for testing.
},
httpResponses =
{
wmScriptVar, -- must match with the callback passed to the openURL command
},
},
logging =
{
level = domoticz.LOG_DEBUG,
marker = 'SamsungWashingMachines',
},
execute = function(dz, item)
-- This function should make a nested (serialized) JSON behave like a normal one when converted to a Lua table
local function deSerializeJSON(json)
return json:gsub('\\"','"'):gsub('"{','{'):gsub('"%["','["'):gsub('"%]"','"]'):gsub('}"','}'):gsub('"%[{"','[{"'):gsub('"}%]"','"}]'):gsub('%]"}',']}')
end
if item.isTimer or item.isDevice then
if wmDevice ~= nil and wmScriptVar ~= nill then
dz.openURL({
url = 'https://api.smartthings.com/v1/devices/'.. wmDevice .. '/states',
headers = { ['Authorization'] = 'Bearer '.. API },
method = 'GET',
callback = wmScriptVar, -- httpResponses above.
})
return
end
elseif item.ok then
if (item.isJSON) then -- when recognized as json then dzVents will convert it to a table for you
item.json = dz.utils.fromJSON(deSerializeJSON(item.data)) -- again after deserializing the nested JSON
rt = item.json.main
local endProgram = 'Pas de programme actif'
local switch = rt.switch.value
if switch == ('on') then
local values = item.json.main.data.value
local remainingTime = values.payload.remainingTime or values.payload["x.com.samsung.da.remainingTime"] or 'A déterminer'
local progressPercentage = values.payload.progressPercentage or values.payload["x.com.samsung.da.progressPercentage"] or 'A déterminer'
local completionTime = convertTime(dz,rt.completionTime.value)
local washerWaterTemperature = rt.washerWaterTemperature.value
local washerJobState = rt.washerJobState.value
local washerCycle = rt.washerCycle.value
local washerSpinLevel = rt.washerSpinLevel.value
local washerLockState = rt.lockState.value
local washerEnergy = rt.powerConsumption.value.energy
local washerPower = rt.powerConsumption.value.power
-- Turn on Domoticz switches updates only when Washer is Active.
dz.log('Debug if switch on:' .. switch, dz.LOG_DEBUG)
updateSelectorOnlyWhenExists(dz, WM_STATUS, codeToFrench(dz, washerJobState)) --turn on dz WM status switch
updateTextOnlyWhenChanged(dz, WM_TEMP, washerWaterTemperature )
updateTextOnlyWhenChanged(dz, WM_SPIN, washerSpinLevel)
updateTextOnlyWhenChanged(dz, WM_REMAINING, remainingTime)
updateTextOnlyWhenChanged(dz, WM_COMPLETION, completionTime)
updateTextOnlyWhenChanged(dz, WM_PROGRAM, codeToFrench(dz, washerCycle))
updatePercentageOnlyWhenChanged(dz, WM_PERCENT, progressPercentage)
else
--Update text devices with endProgram when switch is off
dz.log('Debug if switch off:' .. switch, dz.LOG_DEBUG)
updateSelectorOnlyWhenExists(dz, WM_STATUS, endProgram) --turn off dz WM status switch
dz.log('washerMode if switch off:' .. endProgram, dz.LOG_DEBUG)
updateTextOnlyWhenChanged(dz, WM_TEMP, endProgram)
updateTextOnlyWhenChanged(dz, WM_SPIN, endProgram)
updateTextOnlyWhenChanged(dz, WM_REMAINING, endProgram)
updateTextOnlyWhenChanged(dz, WM_COMPLETION, endProgram)
updateTextOnlyWhenChanged(dz, WM_PROGRAM, endProgram)
updatePercentageOnlyWhenChanged(dz, WM_PERCENT, 100)
end
return
else
dz.log('result was not recognized as a JSON', dz.LOG_ERROR)
end
else
dz.log('result was not OK', dz.LOG_ERROR)
end
dz.log(item, dz.LOG_ERROR) -- dump all to log as one long string
end
}