A SmartThings-compatible MQTT server and device provisioning tool for WiFi-enabled, stdk-based Direct Connected Devices.
You need the following prerequitites in order to use this software:
A WiFi-enabled, stdk-based, SmartThings-compatible Direct Connected Device and its provisioning URL (scan the SmartThings QR code). These devices are working:
Samsung Dishwasher: DW60A8050, DW60A8060
A registered domain name.
A SSL certificate for that domain name, which is signed by the DigiCert Global Root G2. RapidSSL is known to work, others might work as well.
Either a publicly accessible server reachable under the registered domain name or a custom DNS server in your local network, which overrides the registered domain name.
First, install the software:
git clone https://codeberg.org/ldb/localthings.git
cd localthings
virtualenv -p python3 sandbox
source sandbox/bin/activate
pip install -e .
Create a new consumer user:
mkdir -p state/
localthings-server \
--state state/ \
create-user \
<username>
Then, run the server:
mkdir -p state/
localthings-server \
--state state/
run \
--ssl-key privkey.pem \
--ssl-cert chain.pem \
--port 8883 \
--host 0.0.0.0 \
--allow-register <serial>=<device name> \
Then put your device into AP mode, connect your computer to the new WiFi network (password is 1111122222) and run:
localthings-provision \
-n devicename \
-b ssl://example.com:8883 \
-s SSID \
-u 'https://qr.samsungiots.com/?m=XXXX&s=XXX&r=XXX'
It will prompt for the WiFi password. If provisioning with your server fails for some reason, the device will go back into AP mode. You can re-connect to it and add the -l flag to the command above to retrieve error logs (which is usually not implemented on production devices, but you can try).
If it does work, the device should connect to your server after a few seconds and send one or more events containing its initial status. You can query its reported values by using:
localthings-consumer --user <username> event <device name>
And for example turn the device on using:
localthings-consumer --user <username> command <device name> main/switch/on
Or use a command with arguments:
localthings-consumer --user <username> command <device name> main/switchLevel/setLevel 100 20
There is a list of public capabilities available, but devices may support undocumented capabilities too.
To decode the attribute reportRawData of samsungce.remoteManagementData, use this tool:
localthings-mgmtdata <base64-encoded data>
Samsung makes it quite easy to integrate newly developed devices into their SmartThings home automation platform. There is extensive developer documentation, a public API and even an SDK for embedded devices.
What is not documented is how to talk to these SmartThings-enabled embedded devices directly. In particular, how to talk to WiFi-enabled “Direct Connected Devices.”
This protocol documentation is based on reading the source code of the public SDK for embedded devices and probing a WiFi-enabled, Samsung-branded dishwasher.
The first step of connecting a WiFi-capable “Direct Connected Device” to SmartThings is connect it to the internet via a wireless network. This is done through the EasySetup protocol. It roughly works like this: First the mobile phone app scans a QR code and the user is prompted to enable “AP (access point) mode” on the device by pressing a certain button. The app then uses the information contained in the QR code to connect to the WiFi access point the device created. A Diffie-Hellmann key exchange follows to establish a secure connection. The app optionally confirms it is in the vicinity of the device, for example by sending the device’s serial number. Then the device returns a list of WiFi access points it can see, followed by the mobile app sending authentication credentials for one of them and a final confirmation, which disables AP mode on the device, so it can connect to the newly configured wireless network.
Every SmartThings-compatible device should have an onboarding QR code sticker somewhere, whose contents are actually well documented.
The QR code contains a URL with the following pattern: https://qr.samsungiots.com/?m={Your mnId}&s={Device onboardingId}&r={Device serialNumber}. It also seems to be completely redundant, as the app offers to search for devices even without scanning a QR code.
After the user presses a certain button on the SmartThings-device, that device will create a WiFi access point (AP). Its SSID exposes almost the same information as the QR code and its password is fixed to 1111122222 (five times 1, five times 2) for every device.
Dishwasher_E40AwG0006WljY0009
++ fixed: E4
++++ mnid: 0AwG
+++ onboardingId: 000
+ setup type: 6 (fixed)
++++ first 4 digits of hashed serial number: WljY
++++ last 4 digits of serial number: 0009
After connecting to the WiFi AP and with known mnid, onboardingId/setupId and serial number (or parts of it) we can continue with the Diffie-Hellman key exchange. Normally we would generate a private/public key pair, send our public key to the device, somehow retrieve it’s public key and then compute a shared secret. However, there is no way to retrieve a device’s unique[1] public key, because Samsung decided to use “cloud assisted Diffie-Hellmann”. For that we generate a random, 32 byte hex- and then urlsafe-base64-encoded nonce (rand) and send it along with the parts of the serial number we know to their server. For the type hybrid_sn that is the first four characters of the SHA256-hashed and urlsafe-base64-encoded serial number plus the last four digits of the plaintext serial number.
POST https://client.smartthings.com/identity/easysetup/blob HTTP/1.1
accept: application/vnd.smartthings+json;v=2
content-type: application/json
authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXX
{
"keyid": {
"type": "hybrid_sn",
"value": "WljY0009"
},
"mnId": "0AwG",
"rand": "ZWU3MDkwMzU5YzkzZjRjNjViY2U4ZTAzNTk2ODRkNWY5ZTE2OTRjM2YzMGEyYjE5M2UyZWEzZWE1ZTg4YWY2Ng==",
"setupId": "000"
}
The server then generates a private/public key pair for us, but sends us only the public part (cloudPubKey) and the pre-computed Diffie-Hellmann shared key (blob).
{
"code": 2000000,
"message": "SUCCESS",
"data": [
{
"type": "ECDH_ED25519",
"blob": "gRt305a1hhWinTIPeDrUA02uoVpYYxoxkhS-Y4CCNiA=",
"cloudPubKey": "i7nZKUV5AnqLWn_IuT9XGfHB8DdG-yAlpvPzC7aZ1wY=",
"sn": "WljY0TvvL3dhelS4CmieyED_ULB49S5pf2gPid8Bt9c=",
"meta": {
"mfgr": "Midea",
"mnId": "0AwG",
"onboardingId": "000",
"modelName": "Dishwasher",
"sku": [
"DW60A8040",
"DW60A8050",
"DW60A8060",
"DW60A8070"
],
"partner": "Midea"
}
}
]
}
With that information we can start talking to the device. Its HTTP server listens on the default gateway’s address (usually 192.168.4.1) on port 8888. First, we retrieve an initialization vector (IV) for AES.
GET http://192.168.4.1/deviceinfo HTTP/1.1
It will answer with a random IV (iv) and its SHA256-hashed serial number (hashedSn).
{
"protocolVersion": "1.0.0",
"firmwareVersion": "20010101",
"hashedSn": "WljY0TvvL3dhelS4CmieyED_ULB49S5pf2gPid8Bt9c=",
"wifiSupportFrequency": 0,
"iv": "L0k3NxzQwmQdYcurvAXH3A=="
}
We then share our public Diffie-Hellmann key (spub) and the random nonce we generated and sent to the cloud server (rand):
POST http://192.168.4.1/keyinfo HTTP/1.1
content-type: application/json
{
"spub": "i7nZKUV5AnqLWn_IuT9XGfHB8DdG-yAlpvPzC7aZ1wY=",
"rand": "ZWU3MDkwMzU5YzkzZjRjNjViY2U4ZTAzNTk2ODRkNWY5ZTE2OTRjM2YzMGEyYjE5M2UyZWEzZWE1ZTg4YWY2Ng==",
"datetime": "MjAwMS0wMS0wMVQwMC4wMC4wMCBVVEM=",
"regionaldatetime": "MjAwMS0wMS0wMVQwMC4wMC4wMCBHTVQ=",
"timezoneid": "RXVyb3BlL0Jlcmxpbg=="
}
While the code snippets following will show plaint-text only, from now on requests and responses are encrypted with the shared secret we retrieved from the cloud service. We use AES in CBC mode with 16 bytes PKCS7 padding and initialized the cipher with the IV retrieved from the device above. JSON responses are encryted, then encoded with urlsafe base64 and stored in another layer of JSON like so:
{"message": "<payload>"}
Decrypted the answer contains the ownership validation methods the device supports. In this case the “just works” method, which requires a dummy verification.
{"otmSupportFeatures": [0]}
Now we can confirm to the device that we are indeed its owner.
POST http://192.168.4.1/confirminfo HTTP/1.1
content-type: application/json
{"otmSupportFeature": 0}
Which it confirms with an empty response.
{}
Afterwards we can scan for available WiFi networks.
GET http://192.168.4.1/wifiscaninfo HTTP/1.1
Besides the WiFi name the returned list also contains an authType, which has the value 3 for the most common WPA2-PSK-based network.
{
"wifiScanInfo": [
{
"bssid": "a1:b2:c3:d4:e5:f6",
"ssid": "<ssid name>",
"rssi": -123,
"frequency": 0,
"authType": 3
}
]
}
With that information we can now send the credentials for one of these wireless networks. The bssid from above can be filled in as macAddress. authType should match what was returned during the scan. brokerUrl must point to an MQTT broker. Password and SSID are not base64-encoded.
POST http://192.168.4.1/wifiprovisioninginfo HTTP/1.1
content-type: application/json
{
"wifiCredential": {
"ssid": "<ssid name>",
"password": "<password>",
"macAddress": "a1:b2:c3:d4:e5:f6",
"authType": 3
},
"brokerUrl": "ssl://mqtt-regional-euwest1.api.smartthings.com:8883",
"deviceName": "myFancyDeviceName"
}
The device responds with a lookupId, which it also sends to the broker later, and in case of “just works” authentication, with its serial number.
{"lookupId": "e64a8186-9d50-41e1-b8e8-883f7e80f85b", "sn": "11812652000009"}
In a final step we confirm the setup is complete and correct.
POST http://192.168.4.1/setupcomplete HTTP/1.1
content-type: application/json
{}
An empty JSON object is returned.
{}
Each device has a TLS root certificate burnt in, which is validated when contacting the broker given above. It will therefore not talk to any MQTT server with a self-signed certificate. However this root certificate is DigiCert Global Root G2[2], which also signs several sub-CA’s, which in turn sign ordinary domain-validated TLS-certificates. Therefore the brokerUrl must host an MQTT broker serving requests signed by this exact root certificate.
If all is well, the device will connect to the broker with its serial number as username and a JWT as password. Since the JWT is signed with the device’s private key and we don’t have access to its public key we cannot verify its authenticity. Then the device subscribes to /v1/registrations/notification/<serialnumber> and waits for this event:
{"event": "connect.success"}
After receiving it, it sends a register event like the following to /v1/registrations:
{
"label": "myFancyDeviceName",
"mnId": "0AwG",
"vid": "DA-WM-DW-31001",
"deviceTypeId": "Dishwasher",
"lookupId": "e64a8186-9d50-41e1-b8e8-883f7e80f85b",
"serialHash": "WljY0TvvL3dhelS4CmieyED_ULB49S5pf2gPid8Bt9c=",
"provisioningTs": 1729243966,
"firmwareVersion": "20200818",
"osType": "TizenRT",
"osVersion": "2.0",
"stdkVersion": "1.7.4",
"deviceIntegrationProfileKey": {
"id": "bc5ecba8-f445-4c94-b8da-38b2998bd2ea",
"majorVersion": 2,
"minorVersion": 0
}
}
It then waits for a response, assigning it its deviceId and disconnects again:
{"deviceId": "46f92efd-918a-457e-9d04-c587a53db41e"}
How do we know that? The certificate for mqtt-regional-euwest1.api.smartthings.com is issued by GeoTrust, which is signed by the DigiCert CA mentioned above. If we ask the device to connect to a local TLS server with self-signed certificate and observe its traffic we can see a fatal TLS alert of type Unknown CA immediately after the server sends its certificate. Obviously it does not trust the self-signed certificate. If we ask it to connect to digicert.com on port 443 we cannot observe such a TLS alert and the connection aborts after the device tries to talk MQTT to an HTTP server. The certificate of digicert.com, however, is signed by DigiCert EV RSA CA G2, which in turn is signed by the DigiCert CA mentioned above. Therefore the common root must be that DigiCert CA.
A much easier way for figuring this out would have been to look at src/iot_root_ca.c of the SDK, which contains exactly this root certificate.
To understand this section it is helpful to first read up on SmartThings’ Device Basics to understand capabilities and commands.
During normal operation the device will connect to the MQTT broker with deviceId as its username and a JWT as password, then subscribe to /v1/notifications/<deviceId> and /v1/commands/<deviceId> and wait again for the event:
{"event": "connect.success"}
Every time an attribute changes an event is sent to /v1/deviceEvents/<deviceId>:
{
"deviceEvents": [
{
"component": "main",
"capability": "samsungce.errorAndAlarmState",
"attribute": "events",
"value": [],
"visibility": {
"displayed": false
},
"providerData": {
"sequenceNumber": 5,
"timestamp": "1729335398219",
"stateChange": "Y"
}
}
]
}
Commands are sent by the SmartThings Cloud to the device via /v1/commands/<deviceId>:
{
"commands": [
{
"component": "main",
"capability": "switch",
"command": "on",
"arguments": [],
"id": "4be1dad9-c025-4964-beb8-ef7f6ffda458"
}
]
}
If attributes of capabilities change, the device will reply with events, as described above.
Official capabilities are documented here, so this section documents proprietary/private capabilities used by SmartThings-enabled devices, via the official getCapability introspetion API call augmented with observed behavior.
Cooktop Operating State, version 1
supportedCooktopOperatingState: array | Array of string. Allowed values: ready, run, paused, finished. |
cooktopOperatingState: string | Allowed values: ready, run, paused, finished. |
Device Report State Configuration, version 1
reportStateRealtimePeriod: string | Allowed values: disabled, enabled. |
reportStateRealtime: object |
When enabled, the device reports for example changes to samsungce.dishwasherOperation in real-time and not in a fixed interval. Value is reset to defaults on reconnect.
|
reportStatePeriod: string | If enabled, periodic state report events for example for samsungce.errorAndAlarmState will be sent. Allowed values: disabled, enabled. |
setReportStatePeriod(​value: string) | Allowed values: disabled, enabled. |
setReportStateRealtime(​value: object) |
|
setReportStateRealtimePeriod(​value: string) | Allowed values: disabled, enabled. |
Disabled Capabilities, version 1
disabledCapabilities: array | Array of string. |
Dishwasher Operating Progress, version 1
dishwasherOperatingProgress: string | Allowed values: none, delaywash, weightsensing, prewash, wash, rinse, spin, sud, drying, airwash, cooling, wrinkleprevent, finish, waitend, predrain, sanitizing, autoreleasedrying. |
User Notification, version 1
message: object |
|
Water Filter, version 1
waterFilterUsageStep: integer | 1 ≤ x ≤ 100 |
waterFilterResetType: array | Array of string. Allowed values: replaceable, washable, notresetable. |
waterFilterCapacity: integer | Unit: Allowed values: CC, Cycle, Gallon, Hour, Month. |
waterFilterLastResetDate: string | Matches pattern ^(?:[1-9]\d{3}-?(?:(?:0[1-9]|1[0-2])-?(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-?(?:29|30)|(?:0[13578]|1[02])-?31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-?02-?29)T(?:[01]\d|2[0-3]):?[0-5]\d:?[0-5]\d(?:\.\d{3})?(?:Z|[+-][01]\d(?::?[0-5]\d)?)$. |
waterFilterUsage: integer | 0 ≤ x ≤ 100 |
waterFilterStatus: string | Allowed values: normal, replace, wash, notused. |
resetWaterFilter(​) |
Auto Door Release, version 1
autoDoorReleaseEnabled: boolean |
enable(​) | |
disable(​) |
Connection State, version 1
connectionState: string | Allowed values: connected, disconnected. |
Consumed Energy, version 1
monthlyUsage: array |
Array of object.
|
timeOffset: string | Matches pattern ^[+,-](2[0-3]|[0-1][0-9]):[0-5][0-9]$. |
setTimeOffset(​timeOffset: string) | Matches pattern ^[+,-](2[0-3]|[0-1][0-9]):[0-5][0-9]$. |
Cooktop Flex Zone, version 1
flexZones: array |
Array of object.
|
Cooktop Heating Power, version 1
manualLevel: number | |
heatingMode: string | Allowed values: off, onOff, manual, boost, keepWarm, quickPreheat, defrost, melt, simmer. |
manualLevelMin: number | |
supportedHeatingModes: array | Array of string. Allowed values: off, onOff, manual, boost, keepWarm, quickPreheat, defrost, melt, simmer. |
manualLevelMax: number |
Count Down Timer, version 1
startValue: number | Unit: Allowed values: hour, min (default), sec. |
currentValue: number | Unit: Allowed values: hour, min (default), sec. |
status: string | Allowed values: idle, running, paused. |
resume(​) | |
cancel(​) | |
start(​) | |
setStartValue(​startValue: number, [unit: string]) |
|
pause(​) |
Detergent State, version 1
remainingAmount: number | Unit: Allowed values: ea (default), cc. |
dosage: number | Unit: Allowed values: ea (default), cc. |
initialAmount: number | Unit: Allowed values: ea (default), cc. |
detergentType: string | Allowed values: none, liquid, capsule, drySheet, unknown. |
setDetergentType(​detergentType: string) | |
setInitialAmount(​amount: number) | |
setRemainingAmount(​amount: number) | |
setDosage(​amount: number) |
Device Identification, version 1
micomAssayCode: string | |
modelName: string | |
serialNumber: string | |
serialNumberExtra: string | |
modelClassificationCode: string | Matches pattern ^([0-9a-fA-F]){32}$. |
description: string | |
releaseYear: integer | |
binaryId: string |
Dishwasher Job State, version 1
scheduledJobs: array |
Array of object.
|
dishwasherJobState: string | Allowed values: none, delayWashing, preWashing, washing, rinsing, drying, cooling, draining, finished, preDrain, sanitizing, autoReleaseDrying. |
Dishwasher Operation, version 1
supportedOperatingState: array | Array of string. Allowed values: idle, ready, running, paused. |
operatingState: string | Allowed values: idle, ready, running, paused. |
reservable: boolean | Defaults to False. |
progressPercentage: number | |
remainingTimeStr: string | Matches pattern ^[0-2]{0,1}[0-9]:[0-5][0-9]$. |
operationTime: number | Unit: Allowed values: hour, min, sec. |
remainingTime: number | Unit: Allowed values: hour, min, sec. |
timeLeftToStart: number | Unit: Allowed values: hour, min, sec. |
resume(​) | |
cancel(​[drain: boolean]) | |
setOperatingState(​operatingState: string) | Allowed values: running, paused, ready. |
start(​[option: object]) |
|
startLater(​delay: number) | |
pause(​) |
Dishwasher Washing Course, version 1
customCourseCandidates: array | Array of string. Allowed values: auto, eco, intensive, delicate, express, preWash, selfClean, extraSilence, rinseOnly, plastics, potsAndPans, babycare, normal, selfSanitize, dryOnly, upperExpress, night, babyBottle, coldRinse, glasses, quick, heavy, daily, chef, preBlast, steamSoak, rinseDry, machineCare, AI, nightSilence, express_0C, daily_09, eco_08, eco_10, drinkware. |
washingCourse: string | Allowed values: auto, eco, intensive, delicate, express, preWash, selfClean, extraSilence, rinseOnly, plastics, potsAndPans, babycare, normal, selfSanitize, dryOnly, upperExpress, night, babyBottle, coldRinse, glasses, quick, heavy, daily, chef, preBlast, steamSoak, rinseDry, machineCare, AI, nightSilence, express_0C, daily_09, eco_08, eco_10, drinkware. |
supportedCourses: array | Array of string. Allowed values: auto, eco, intensive, delicate, express, preWash, selfClean, extraSilence, rinseOnly, plastics, potsAndPans, babycare, normal, selfSanitize, dryOnly, upperExpress, night, babyBottle, coldRinse, glasses, quick, heavy, daily, chef, preBlast, steamSoak, rinseDry, machineCare, AI, nightSilence, express_0C, daily_09, eco_08, eco_10, drinkware. |
setWashingCourse(​course: string) | Allowed values: auto, eco, intensive, delicate, express, preWash, selfClean, extraSilence, rinseOnly, plastics, potsAndPans, babycare, normal, selfSanitize, dryOnly, upperExpress, night, babyBottle, coldRinse, glasses, quick, heavy, daily, chef, preBlast, steamSoak, rinseDry, machineCare, AI, nightSilence, express_0C, daily_09, eco_08, eco_10, drinkware. |
setCustomCourse(​course: string) | Allowed values: auto, eco, intensive, delicate, express, preWash, selfClean, extraSilence, rinseOnly, plastics, potsAndPans, babycare, normal, selfSanitize, dryOnly, upperExpress, night, babyBottle, coldRinse, glasses, quick, heavy, daily, chef, preBlast, steamSoak, rinseDry, machineCare, AI, nightSilence, express_0C, daily_09, eco_08, eco_10, drinkware. |
startWashingCourse(​course: string) | Starts the dishwashing process with selected program immediately, even if the dishwasher is turned off. Allowed values: auto, eco, intensive, delicate, express, preWash, selfClean, extraSilence, rinseOnly, plastics, potsAndPans, babycare, normal, selfSanitize, dryOnly, upperExpress, night, babyBottle, coldRinse, glasses, quick, heavy, daily, chef, preBlast, steamSoak, rinseDry, machineCare, AI, nightSilence, express_0C, daily_09, eco_08, eco_10, drinkware. |
startWashingCourseWithOptions(​course: string, options: object) |
|
Dishwasher Washing Course Details, version 1
predefinedCourses: array |
Array of object.
|
waterUsageMax: integer | |
energyUsageMax: integer |
Dishwasher Washing Options, version 1
dryPlus: object |
|
stormWash: object |
|
hotAirDry: object |
|
selectedZone: object |
|
speedBooster: object |
|
highTempWash: object |
|
sanitizingWash: object |
|
zoneBooster: object |
|
addRinse: object |
|
supportedList: array | Array of string. Allowed values: selectedZone, zoneBooster, speedBooster, sanitize, highTempWash, steamSoak, addRinse, dryPlus, stormWash, sanitizingWash, rinsePlus, hotAirDry. |
rinsePlus: object |
|
sanitize: object |
|
steamSoak: object |
|
setSelectedZone(​selectedZone: string) | Allowed values: none, lower, upper, all. |
setSanitize(​sanitize: boolean) | |
setZoneBooster(​zoneBooster: string) | Allowed values: none, left, right, all. |
setDryPlus(​dryPlus: boolean) | |
setAddRinse(​addRinse: boolean) | |
setHotAirDry(​hotAirDry: boolean) | |
setStormWash(​stormWash: boolean) | |
setHighTempWash(​highTempWash: boolean) | |
setSanitizingWash(​sanitizingWash: boolean) | |
setSpeedBooster(​speedBooster: boolean) | |
setRinsePlus(​rinsePlus: boolean) | |
setOptions(​options: object) |
|
setSteamSoak(​steamSoak: boolean) |
Drum Self Cleaning, version 1
washingCountAfterSelfClean: number | 0 ≤ x |
history: array | Array of string. Matches pattern ^(?:[1-9]\d{3}-?(?:(?:0[1-9]|1[0-2])-?(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-?(?:29|30)|(?:0[13578]|1[02])-?31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-?02-?29)T(?:[01]\d|2[0-3]):?[0-5]\d:?[0-5]\d(?:\.\d{3})?(?:Z|[+-][01]\d(?::?[0-5]\d)?)$. |
suggestionThreshold: number | 0 ≤ x |
Error And Alarm State, version 1
events: array |
Array of object.
|
Hood Fan Speed, version 1
settableMaxFanSpeed: integer | |
hoodFanSpeed: integer | |
supportedHoodFanSpeed: array | Array of integer. |
settableMinFanSpeed: integer |
setHoodFanSpeed(​speed: integer) |
Kids Lock Control, version 1
lockState: string | Allowed values: locked, unlocked, paused. |
unlock(​) | |
lock(​) |
Kitchen Device Identification, version 1
regionCode: string | Allowed values: IT, UK, FR, US, JP, EU, KR, CN, ZZ, UNKNOWN. |
modelCode: string | |
fuel: string | Allowed values: gas. |
type: string | Allowed values: oven, range, microwave, cooktop. |
representativeComponent: string | Allowed values: main (default), cavity-01, cavity-02, cavity-03. |
Lamp, version 1
brightnessLevel |
One of these:
|
supportedBrightnessLevel: array |
Array of .
One of these:
|
setBrightnessLevel(​level) |
One of these:
|
Oven Operating State, version 1
completionTime: string | Matches pattern ^(?:[1-9]\d{3}-?(?:(?:0[1-9]|1[0-2])-?(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-?(?:29|30)|(?:0[13578]|1[02])-?31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-?02-?29)T(?:[01]\d|2[0-3]):?[0-5]\d:?[0-5]\d(?:\.\d{3})?(?:Z|[+-][01]\d(?::?[0-5]\d)?)$. |
operatingState: string | Allowed values: ready, running, paused. |
progress: integer | 0 ≤ x |
ovenJobState: string | Allowed values: cleaning, cooking, cooling, draining, preheat, ready, rinsing, finished, scheduledStart, warming, defrosting, sensing, searing, fastPreheat, scheduledEnd, stoneHeating, timeHoldPreheat. |
operationTime: string | Matches pattern ^\d\d+:[0-5]\d:[0-5]\d$. |
setOperationTime(​operationTime: string) | Matches pattern ^\d\d+:[0-5]\d:[0-5]\d$. |
stop(​) | |
start(​) | |
pause(​) |
Remote Management Data, version 1
reportRawData: string | Base64-encoded string encoding vendor-specific binary data. |
version: string | Matches pattern ^[A-Z]{2,4}-[0-9]{2}.[0-9]{2,4}$. |
rmCommand(​rawData: string) |
Software Update, version 1
targetModule: object |
|
otnDUID: string | Device unique ID, probably for samsungotn.net |
lastUpdatedDate: string | Matches pattern ^(?:[1-9]\d{3}-?(?:(?:0[1-9]|1[0-2])-?(?:0[1-9]|1\d|2[0-8])|(?:0[13-9]|1[0-2])-?(?:29|30)|(?:0[13578]|1[02])-?31)|(?:[1-9]\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-?02-?29). |
availableModules: array | Array of string. |
newVersionAvailable: boolean | |
operatingState: string | Allowed values: none, available, preparing, delayed, inprogress, checking, completed, rebooting, swapRebooting. |
progress: integer | 0 ≤ x ≤ 100 Unit: Allowed values: % (default). |
agreeUpdate(​[module: string]) | |
disagreeUpdate(​[module: string]) |
Software Version, version 1
versions: array |
Array of object.
|
Surface Residual Heat, version 1
surfaceResidualHeat: string | Allowed values: normal, low, high, veryHigh. |