Posts: 375
Threads: 69
Joined: Dec 2019
Reputation:
15
Good morning and happy new year st all.
I'm working with Smartthings API, in command mode I reached good results. My problem it is the status update and I'm asking at the community if some other is working on this.... I 've thought to use the 'https://api.smartthings.com/v1/devices/<deviceId>/components/<componentID>/status' and create a resident script for x seconds to update the values reading the response Json.
I'm asking, is there a more pretty solution?
Best regards Cristian
Posts: 8391
Threads: 45
Joined: Jun 2015
Reputation:
480
Looks like polling is the only way to get the status info.
Posts: 375
Threads: 69
Joined: Dec 2019
Reputation:
15
(02.01.2025, 11:35)admin Wrote: Looks like polling is the only way to get the status info.
How many time in a minute, by your experience, do you suggest? I don't want overload the communication with the cloud.
BR Cristian
Posts: 8391
Threads: 45
Joined: Jun 2015
Reputation:
480
This is a question for Smartthings support
Check if API has any rate limits and adjust your scripts accordingly.
Posts: 375
Threads: 69
Joined: Dec 2019
Reputation:
15
(02.01.2025, 14:30)admin Wrote: This is a question for Smartthings support 
Check if API has any rate limits and adjust your scripts accordingly.
Ok I will check again.
BR Cristian
Posts: 26
Threads: 1
Joined: Mar 2017
Reputation:
0
Hello all
I am successfully reading the status of individual devices from Smartthings
But when I am trying to set the status via command I am receiving 422.
Same code works from Postman. Is it a string issue?
Thank you in advanced for the comments
Code: local https = require('ssl.https')
local ltn12 = require('ltn12')
local token = '++++++++'
local cam_id = '++++++++++'
-- Function to turn camera on or off using a raw JSON string
local function set_camera_onoff(cam_id, state)
local cmd = state and 'on' or 'off'
local body = string.format([[
{
"commands": [
{
"component": "main",
"capability": "switch",
"command": "%s"
}
]
}
]], cmd)
log('Request body: ' .. body)
local sink_tbl = {}
local res, code = https.request({
url = 'https://api.smartthings.com/v1/devices/' .. cam_id .. '/commands',
method = 'POST',
headers = {
['Content-Type'] = 'application/json',
['Authorization'] = 'Bearer ' .. token,
['Accept'] = 'application/json',
['User-Agent'] = 'Mozilla/5.0',
['Content-Length'] = tostring(#body)
},
source = ltn12.source.string(body),
sink = ltn12.sink.table(sink_tbl),
})
local response_body = table.concat(sink_tbl)
log('SmartThings response code: ' .. tostring(code))
log('SmartThings response body: ' .. response_body)
return res, code, response_body
end
-- Usage:
set_camera_onoff(cam_id, true) -- to turn ON
set_camera_onoff(cam_id, false) -- to turn OFF
Posts: 8391
Threads: 45
Joined: Jun 2015
Reputation:
480
What do you get in response? It should contain some explanation on what is wrong with the request.
Posts: 26
Threads: 1
Joined: Mar 2017
Reputation:
0
(02.10.2025, 11:04)admin Wrote: What do you get in response? It should contain some explanation on what is wrong with the request.
Code: string: SmartThings response body: {"requestId":"7895205675944081778","error":{"code":"ConstraintViolationError","message":"The request is malformed.","details":[{"code":"BodyMalformedError","target":"httpRequestBody","message":"The request body is malformed and cannot be processed by server.","details":[]}]}}
Here it is Saying after 422
Posts: 8391
Threads: 45
Joined: Jun 2015
Reputation:
480
Try encoding POST body using JSON library:
Code: local body = require('json').encode({
commands = {
{
component = 'main',
capability = 'switch',
command = cmd,
}
}
})
Posts: 26
Threads: 1
Joined: Mar 2017
Reputation:
0
I receıved below 422
Code: * string: Request body: {"commands":[{"capability":"switch","command":"on","component":"main"}]}
* string: SmartThings response code: 422
* string: SmartThings response body: {"requestId":"391879646930462279","error":{"code":"ConstraintViolationError","message":"The request is malformed.","details":[{"code":"BodyMalformedError","target":"httpRequestBody","message":"The request body is malformed and cannot be processed by server.","details":[]}]}}
Here is the full code
Code: local https = require('ssl.https')
local json = require('json')
local ltn12 = require('ltn12')
-- ️ put your smartthings pat here
local token = '*************'
local livingr_cam_id = '**************************'
-- Camera KNX group objects (choose addresses as needed)
local ga_cam_onoff_set = grp.create({ datatype = dt.bool, address = '33/4/1', name = 'Camera On/Off' })
local ga_cam_onoff = grp.create({ datatype = dt.bool, address = '33/4/2', name = 'Camera On/Off Status' })
local ga_cam_motion = grp.create({ datatype = dt.bool, address = '33/4/11', name = 'Camera Motion Detected' })
local ga_cam_sound = grp.create({ datatype = dt.bool, address = '33/4/12', name = 'Camera Sound Detected' })
local cam_set = grp.getvalue(ga_cam_onoff_set) -- Set
local cam_set_status = grp.getvalue(ga_cam_onoff) -- Status
-- Helper to turn camera on or off using a raw JSON string
local function set_camera_onoff(cam_id, state)
local cmd = state and 'on' or 'off'
local body = require('json').encode({
commands = {
{
component = 'main',
capability = 'switch',
command = cmd,
}
}
})
log('Request body: ' .. body)
local sink_tbl = {}
local res, code = https.request({
url = 'https://api.smartthings.com/v1/devices/' .. cam_id .. '/commands',
method = 'POST',
headers = {
['authorization'] = 'Bearer ' .. token,
['content-type'] = 'application/json; charset=utf-8',
['accept'] = 'application/json',
},
source = ltn12.source.string(body),
sink = ltn12.sink.table(sink_tbl),
})
local response_body = table.concat(sink_tbl)
log('SmartThings response code: ' .. tostring(code))
log('SmartThings response body: ' .. response_body)
return res, code, response_body
end
if cam_set == true then
if cam_set_status == false then
set_camera_onoff(livingr_cam_id, true)
end
elseif cam_set == false then
if cam_set_status == true then
set_camera_onoff(livingr_cam_id, false)
end
end
Here is the working postman cURL
Code: curl --location 'https://api.smartthings.com/v1/devices/***************************/commands' \
--header 'Content-Type: application/json' \
--header 'Authorization: **********' \
--data '{
"commands": [
{
"component": "main",
"capability": "switch",
"command": "on"
} ]
}'
Thank you for the support
Posts: 8391
Threads: 45
Joined: Jun 2015
Reputation:
480
Your code is missing content-length header. If it still does not work then send your token and device ID via PM.
Posts: 375
Threads: 69
Joined: Dec 2019
Reputation:
15
(02.10.2025, 18:44)Ozturker Wrote: I receıved below 422
Code: * string: Request body: {"commands":[{"capability":"switch","command":"on","component":"main"}]}
* string: SmartThings response code: 422
* string: SmartThings response body: {"requestId":"391879646930462279","error":{"code":"ConstraintViolationError","message":"The request is malformed.","details":[{"code":"BodyMalformedError","target":"httpRequestBody","message":"The request body is malformed and cannot be processed by server.","details":[]}]}}
Here is the full code
Code: local https = require('ssl.https')
local json = require('json')
local ltn12 = require('ltn12')
-- ️ put your smartthings pat here
local token = '*************'
local livingr_cam_id = '**************************'
-- Camera KNX group objects (choose addresses as needed)
local ga_cam_onoff_set = grp.create({ datatype = dt.bool, address = '33/4/1', name = 'Camera On/Off' })
local ga_cam_onoff = grp.create({ datatype = dt.bool, address = '33/4/2', name = 'Camera On/Off Status' })
local ga_cam_motion = grp.create({ datatype = dt.bool, address = '33/4/11', name = 'Camera Motion Detected' })
local ga_cam_sound = grp.create({ datatype = dt.bool, address = '33/4/12', name = 'Camera Sound Detected' })
local cam_set = grp.getvalue(ga_cam_onoff_set) -- Set
local cam_set_status = grp.getvalue(ga_cam_onoff) -- Status
-- Helper to turn camera on or off using a raw JSON string
local function set_camera_onoff(cam_id, state)
local cmd = state and 'on' or 'off'
local body = require('json').encode({
commands = {
{
component = 'main',
capability = 'switch',
command = cmd,
}
}
})
log('Request body: ' .. body)
local sink_tbl = {}
local res, code = https.request({
url = 'https://api.smartthings.com/v1/devices/' .. cam_id .. '/commands',
method = 'POST',
headers = {
['authorization'] = 'Bearer ' .. token,
['content-type'] = 'application/json; charset=utf-8',
['accept'] = 'application/json',
},
source = ltn12.source.string(body),
sink = ltn12.sink.table(sink_tbl),
})
local response_body = table.concat(sink_tbl)
log('SmartThings response code: ' .. tostring(code))
log('SmartThings response body: ' .. response_body)
return res, code, response_body
end
if cam_set == true then
if cam_set_status == false then
set_camera_onoff(livingr_cam_id, true)
end
elseif cam_set == false then
if cam_set_status == true then
set_camera_onoff(livingr_cam_id, false)
end
end
Here is the working postman cURL
Code: curl --location 'https://api.smartthings.com/v1/devices/***************************/commands' \
--header 'Content-Type: application/json' \
--header 'Authorization: **********' \
--data '{
"commands": [
{
"component": "main",
"capability": "switch",
"command": "on"
} ]
}'
Thank you for the support
Hi, try to add this in the header, for me works
['content-length'] = #body,
Best regards Cristian
Posts: 26
Threads: 1
Joined: Mar 2017
Reputation:
0
(03.10.2025, 10:02)CristianAgata Wrote: (02.10.2025, 18:44)Ozturker Wrote: I receıved below 422
Code: * string: Request body: {"commands":[{"capability":"switch","command":"on","component":"main"}]}
* string: SmartThings response code: 422
* string: SmartThings response body: {"requestId":"391879646930462279","error":{"code":"ConstraintViolationError","message":"The request is malformed.","details":[{"code":"BodyMalformedError","target":"httpRequestBody","message":"The request body is malformed and cannot be processed by server.","details":[]}]}}
Here is the full code
Code: local https = require('ssl.https')
local json = require('json')
local ltn12 = require('ltn12')
-- ️ put your smartthings pat here
local token = '*************'
local livingr_cam_id = '**************************'
-- Camera KNX group objects (choose addresses as needed)
local ga_cam_onoff_set = grp.create({ datatype = dt.bool, address = '33/4/1', name = 'Camera On/Off' })
local ga_cam_onoff = grp.create({ datatype = dt.bool, address = '33/4/2', name = 'Camera On/Off Status' })
local ga_cam_motion = grp.create({ datatype = dt.bool, address = '33/4/11', name = 'Camera Motion Detected' })
local ga_cam_sound = grp.create({ datatype = dt.bool, address = '33/4/12', name = 'Camera Sound Detected' })
local cam_set = grp.getvalue(ga_cam_onoff_set) -- Set
local cam_set_status = grp.getvalue(ga_cam_onoff) -- Status
-- Helper to turn camera on or off using a raw JSON string
local function set_camera_onoff(cam_id, state)
local cmd = state and 'on' or 'off'
local body = require('json').encode({
commands = {
{
component = 'main',
capability = 'switch',
command = cmd,
}
}
})
log('Request body: ' .. body)
local sink_tbl = {}
local res, code = https.request({
url = 'https://api.smartthings.com/v1/devices/' .. cam_id .. '/commands',
method = 'POST',
headers = {
['authorization'] = 'Bearer ' .. token,
['content-type'] = 'application/json; charset=utf-8',
['accept'] = 'application/json',
},
source = ltn12.source.string(body),
sink = ltn12.sink.table(sink_tbl),
})
local response_body = table.concat(sink_tbl)
log('SmartThings response code: ' .. tostring(code))
log('SmartThings response body: ' .. response_body)
return res, code, response_body
end
if cam_set == true then
if cam_set_status == false then
set_camera_onoff(livingr_cam_id, true)
end
elseif cam_set == false then
if cam_set_status == true then
set_camera_onoff(livingr_cam_id, false)
end
end
Here is the working postman cURL
Code: curl --location 'https://api.smartthings.com/v1/devices/***************************/commands' \
--header 'Content-Type: application/json' \
--header 'Authorization: **********' \
--data '{
"commands": [
{
"component": "main",
"capability": "switch",
"command": "on"
} ]
}'
Thank you for the support
Hi, try to add this in the header, for me works
['content-length'] = #body,
Best regards Cristian
Thank you Cristian. Thank you both. NOW IT IS WORKING properly.
|