Using this script with my new Samsung washing machine. Works great. I used this one from page 3 and translated it to dutch / NL. I left out drDevice, because my dryer is not a Samsung device (yet). For anyone who cares:
Code: Select all
-- 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 = 'XYZ'
local wmDevice = 'XYZ'
local drDevice = ''
-- eg. local API = '1a1a1a1a-1a1a-1a1a-1111-1a1a1a1a1a1a1'
-- 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 IDX in (brackets) below.
local TEST_SWITCH = (713) -- Virtual on switch to activated the script manually for testing.
local WM_PROGRAM = (714) -- Virtual device showing washing machine Program - Device type = text
local WM_COMPLETION = (715) -- Virtual device showing washing cycle completion time - Device type = text
local WM_SPIN = (716) -- Virtual device showing washing spin state - Device type = text
local WM_REMAINING = (717) -- Virtual device showing time remaining on wash - Device type = text
local WM_TEMP = (718) -- Virtual device showing washing machine Temperature - Device type = text
local WM_STATUS = (719) -- Virtual device showing washing machine On/Off - Device type = on/off switch
local WM_PERCENT = (720) -- Virtual device showing washing machine percentage - Device type = percentage
local WM_STATE = (721) -- Virtual device showing washing cycle state - Device type = text
local DR_PROGRAM = (56) -- Virtual device showing dryer Program - Device type = text
local DR_COMPLETION = (57) -- Virtual device showing drying cycle completion time - Device type = text
local DR_REMAINING = (58) -- Virtual device showing time remaining on wash - Device type = text
local DR_STATUS = (61) -- Virtual device showing dryer On/Off - Device type = on/off switch
local DR_PERCENT = (62) -- Virtual device showing dryer percentage - Device type = percentage
-- ------------------------
local wmScriptVar = 'WashingMachine'
--local drScriptVar = 'Dryer'
local LOGGING = true
--Convert Table_00_Course_* and WashingState to English
local function codeToEnglish(dz, code)
local translationcode =
{
Table_00_Course_D0 = 'Katoen',
Table_00_Course_D1 = 'Eco Katoen',
Table_00_Course_D2 = 'Synthetisch',
Table_00_Course_D3 = 'Fijne was',
Table_00_Course_D4 = 'Spoelen+centrifugeren',
Table_00_Course_D5 = 'Trommelreiniging',
Table_00_Course_D6 = 'Beddengoed',
Table_00_Course_D7 = 'Outdoor',
Table_00_Course_D8 = 'Wol',
Table_00_Course_D9 = 'Donkere Was',
Table_00_Course_DA = 'Super Eco Was',
Table_00_Course_DB = 'Super Speed Was',
Table_00_Course_DC = '15\' Snelle Was',
Table_00_Course_BA = 'Centrifugeren',
Table_02_Course_1B = 'Katoen',
Table_02_Course_1C = 'Eco 40-60',
Table_02_Course_1D = 'Super Speed Wash',
Table_02_Course_1E = '15\' kort programma',
Table_02_Course_1F = 'Intens Koud',
Table_02_Course_20 = 'Hygiënisch stomen',
Table_02_Course_21 = 'Gekleurde was',
Table_02_Course_22 = 'Wol',
Table_02_Course_23 = 'Outdoor',
Table_02_Course_24 = 'Bedlinnen',
Table_02_Course_25 = 'Synthetisch',
Table_02_Course_26 = 'Fijne was',
Table_02_Course_27 = 'Spoelen+centrifugeren',
Table_02_Course_28 = 'Afvoeren/centrifugeren',
Table_02_Course_29 = 'Trommelreiniging',
Table_02_Course_2A = 'Spijkerbroeken',
Table_02_Course_2B = 'All Wash',
Table_02_Course_2D = 'Stille was',
Table_02_Course_2E = 'Babykleding',
Table_02_Course_2F = 'Sportkleding',
Table_02_Course_30 = 'Bewolkte dag',
Table_02_Course_32 = 'Overhemden',
Table_02_Course_33 = 'Handdoeken',
Table_03_Course_16 = 'Katoen',
Table_03_Course_17 = 'Super Speed',
Table_03_Course_18 = 'Synthetisch',
Table_03_Course_19 = 'Fijne was',
Table_03_Course_1A = 'Wol',
Table_03_Course_1B = 'Bedlinnen',
Table_03_Course_1C = 'Overhemden',
Table_03_Course_1D = 'Handdoeken',
Table_03_Course_1E = 'Outdoor',
Table_03_Course_1F = 'Gekleurde was',
Table_03_Course_20 = 'Strijkdroog',
Table_03_Course_21 = 'Hygiënisch stomen',
Table_03_Course_23 = '35\' Snel Drogen',
Table_03_Course_24 = 'Koude Lucht',
Table_03_Course_25 = 'Warme Lucht',
Table_03_Course_26 = 'Air Wash',
Table_03_Course_27 = 'Time Program',
none = 'Nothing',
weightSensing = 'Weight Sensing',
wash = 'Wassen',
rinse = 'Spoelen',
spin = 'Centrifugeren',
finish = 'Beëindigd',
}
local code = tostring(code)
local translatedCode = translationcode[code]
if translatedCode == nil then
dz.log('codeToEnglish: 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)
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)
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 devices only when exists
local function updateSwitchOnlyWhenExists(dz, switchName, newState)
if switchName ~= nil then
local switch = dz.devices(switchName)
if newState == 'ON' then
switch.switchOn().checkFirst()
else
switch.switchOff().checkFirst()
end
end
end
--Convert the time to Hour,Minute,second.
local function convertTime(dateString)
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})
local tmp_time = os.time()
local d1 = os.date("*t", tmp_time)
local d2 = os.date("!*t", tmp_time)
d1.isdst = false
local zone_diff = os.difftime(os.time(d1), os.time(d2))
return os.date('%H:%M:%S', convertedTimestamp + zone_diff)
end
-- 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
return
{
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
drScriptVar, -- must match with the callback passed to the openURL command
},
},
logging =
{
level = domoticz.LOG_ERROR,
marker = 'SamsungWashingMachines',
},
execute = function(dz, item)
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.
})
end
if drDevice ~= nil and drScriptVar ~= nill then
dz.openURL({
url = 'https://api.smartthings.com/v1/devices/'.. drDevice .. '/states',
headers = { ['Authorization'] = 'Bearer '.. API },
method = 'GET',
callback = drScriptVar, -- httpResponses above.
})
end
return
elseif item.ok then
if (item.isJSON) then
-- when recognized as json then dzVents will convert it to a table for you
-- again after deserializing the nested JSON
item.json = dz.utils.fromJSON(deSerializeJSON(item.data))
rt = item.json.main
local endProgram = 'Geen actief programma'
local values = item.json.main.data.value
local remainingTime = values.payload.remainingTime or values.payload["x.com.samsung.da.remainingTime"] or 'not found'
local progressPercentage = values.payload.progressPercentage or values.payload["x.com.samsung.da.progressPercentage"] or 'not found'
local completionTime = convertTime(rt.completionTime.value)
local switch = rt.switch.value
-- Check whether it is a dryer or a washing machine
if rt.n.value == "[dryer] Samsung" then
local dryerCycle = rt.dryerCycle.value
if switch == ('on') then
-- Turn on Domoticz switches updates only when Washer is Active.
dz.log('Debug if switch on:' .. switch, dz.LOG_DEBUG)
updateSwitchOnlyWhenExists(dz, DR_STATUS, 'ON') --turn on dz DR status switch
updateTextOnlyWhenChanged(dz, DR_REMAINING, remainingTime)
updateTextOnlyWhenChanged(dz, DR_COMPLETION, completionTime)
updateTextOnlyWhenChanged(dz, DR_PROGRAM, codeToEnglish(dz, dryerCycle))
updatePercentageOnlyWhenChanged(dz, DR_PERCENT, progressPercentage)
else
--Update text devices with endProgram when switch is off
dz.log('Debug if switch off:' .. switch, dz.LOG_DEBUG)
updateSwitchOnlyWhenExists(dz, DR_STATUS, 'OFF') --turn off dz DR status switch
dz.log('dryerMode if switch off:' .. endProgram, dz.LOG_DEBUG)
updateTextOnlyWhenChanged(dz, DR_REMAINING, endProgram)
updateTextOnlyWhenChanged(dz, DR_COMPLETION, endProgram)
updateTextOnlyWhenChanged(dz, DR_PROGRAM, endProgram)
updatePercentageOnlyWhenChanged(dz, DR_PERCENT, 100)
end
else
local washerWaterTemperature = rt.washerWaterTemperature.value
local washerJobState = rt.washerJobState.value
local washerCycle = rt.washerCycle.value
local washerSpinLevel = rt.washerSpinLevel.value
if switch == ('on') then
-- Turn on Domoticz switches updates only when Washer is Active.
dz.log('Debug if switch on:' .. switch, dz.LOG_DEBUG)
updateSwitchOnlyWhenExists(dz, WM_STATUS, 'ON') --turn on dz WM status switch
updateTextOnlyWhenChanged(dz, WM_TEMP, washerWaterTemperature )
updateTextOnlyWhenChanged(dz, WM_STATE, codeToEnglish(dz, washerJobState))
updateTextOnlyWhenChanged(dz, WM_SPIN, washerSpinLevel)
updateTextOnlyWhenChanged(dz, WM_REMAINING, remainingTime)
updateTextOnlyWhenChanged(dz, WM_COMPLETION, completionTime)
updateTextOnlyWhenChanged(dz, WM_PROGRAM, codeToEnglish(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)
updateSwitchOnlyWhenExists(dz, WM_STATUS, 'OFF') --turn off dz WM status switch
dz.log('washerMode if switch off:' .. endProgram, dz.LOG_DEBUG)
updateTextOnlyWhenChanged(dz, WM_TEMP, endProgram)
updateTextOnlyWhenChanged(dz, WM_STATE, 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
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
}