Overview
Enable temperature lock to restrict temperature adjustments on the physical thermostat. Requires a 4-digit PIN.
Hosted service only. This endpoint is part of the hosted API at https://nolongerevil.com/api/v1 and requires an nle_ API key. It is not available on the self-hosted server.
Endpoint
POST https://nolongerevil.com/api/v1/thermostat/{deviceId}/lock
Authentication
Required Scopes : write
Request Body
To enable lock :
Field Type Required Description enabledboolean Yes truepin_hashstring Yes Base64(SHA1(PIN + SERIAL)) temp_minnumber Yes Minimum allowed temperature (°C) temp_maxnumber Yes Maximum allowed temperature (°C)
To disable lock :
Field Type Required Description enabledboolean Yes false
Example: Enable Lock
{
"enabled" : true ,
"pin_hash" : "/PiS0Kl52c8oNptmsL4Z7cxd9mg=" ,
"temp_min" : 18 ,
"temp_max" : 24
}
The pin_hash is Base64(SHA1(PIN + SERIAL)). Never send the PIN in plaintext! You must concatenate the PIN with the device serial number before hashing.
Example: Disable Lock
Response
Success (200 OK):
{
"success" : true ,
"message" : "Command handled" ,
"device" : "02AA01AB01234567" ,
"object" : "device.02AA01AB01234567" ,
"revision" : 91 ,
"timestamp" : 1764026415000
}
Generating PIN Hash
The PIN hash algorithm matches the Nest thermostat’s native format:
Algorithm: Base64( SHA1( PIN + SERIAL ) )
You must concatenate the PIN with the device’s serial number before hashing. This matches the Nest protocol and makes PINs device-specific.
JavaScript (Browser)
JavaScript (Node.js)
Python
async function hashPin ( pin , serial ) {
// Combine PIN and serial number
const combined = pin + serial ;
// Convert to bytes
const encoder = new TextEncoder ();
const data = encoder . encode ( combined );
// SHA-1 hash
const hashBuffer = await crypto . subtle . digest ( 'SHA-1' , data );
// Convert to Base64
const hashArray = Array . from ( new Uint8Array ( hashBuffer ));
const base64 = btoa ( String . fromCharCode ( ... hashArray ));
return base64 ;
}
// Example: PIN "0000" + Serial "02AA01AB01234567"
const pinHash = await hashPin ( '0000' , '02AA01AB01234567' );
// Result: /PiS0Kl52c8oNptmsL4Z7cxd9mg=
import crypto from 'crypto' ;
function hashPin ( pin , serial ) {
const combined = pin + serial ;
const hash = crypto . createHash ( 'sha1' ). update ( combined ). digest ( 'base64' );
return hash ;
}
// Example
const pinHash = hashPin ( '0000' , '02AA01AB01234567' );
// Result: /PiS0Kl52c8oNptmsL4Z7cxd9mg=
import hashlib
import base64
def hash_pin ( pin , serial ):
combined = pin + serial
sha1_hash = hashlib.sha1(combined.encode()).digest()
base64_hash = base64.b64encode(sha1_hash).decode()
return base64_hash
# Example
pin_hash = hash_pin( '0000' , '02AA01AB01234567' )
# Result: /PiS0Kl52c8oNptmsL4Z7cxd9mg=
Code Examples
cURL - Enable
cURL - Disable
JavaScript
curl -X POST https://nolongerevil.com/api/v1/thermostat/dev_abc123xyz/lock \
-H "Authorization: Bearer nle_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"pin_hash": "/PiS0Kl52c8oNptmsL4Z7cxd9mg=",
"temp_min": 18,
"temp_max": 24
}'
curl -X POST https://nolongerevil.com/api/v1/thermostat/dev_abc123xyz/lock \
-H "Authorization: Bearer nle_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
async function hashPin ( pin , serial ) {
const combined = pin + serial ;
const encoder = new TextEncoder ();
const data = encoder . encode ( combined );
const hashBuffer = await crypto . subtle . digest ( 'SHA-1' , data );
const hashArray = Array . from ( new Uint8Array ( hashBuffer ));
return btoa ( String . fromCharCode ( ... hashArray ));
}
async function enableTemperatureLock ( deviceId , serial , pin , tempMin , tempMax ) {
const pinHash = await hashPin ( pin , serial );
const response = await fetch (
`https://nolongerevil.com/api/v1/thermostat/ ${ deviceId } /lock` ,
{
method: 'POST' ,
headers: {
'Authorization' : 'Bearer nle_your_api_key_here' ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
enabled: true ,
pin_hash: pinHash ,
temp_min: tempMin ,
temp_max: tempMax
})
}
);
return await response . json ();
}
// Usage (you need the device serial from GET /devices)
await enableTemperatureLock ( 'dev_abc123xyz' , '02AA01AB01234567' , '1234' , 18 , 24 );
Use Cases
Child Safety
// Lock thermostat to prevent children from adjusting temperature
await enableTemperatureLock ( deviceId , deviceSerial , '1234' , 18 , 24 );
Commercial Buildings
// Restrict guest room temperature range in hotels
await enableTemperatureLock ( roomDeviceId , roomSerial , hotelPin , 20 , 23 );
Security Notes
Never store or transmit PINs in plaintext . Always hash the PIN client-side before sending to the API.
Important Points
PIN Format : Must be exactly 4 digits (0000-9999)
Hashing : Use SHA-1 (not SHA-256) with PIN + serial concatenated
Encoding : Hash must be Base64-encoded (not hex)
Serial Required : You must include the device serial number in the hash
Temperature Units : temp_min and temp_max must be in Celsius
Device-Specific : Same PIN produces different hashes for different devices
Why SHA-1 + Serial?
This matches the Nest thermostat’s native PIN algorithm:
Device-specific : Same PIN produces different hashes for different thermostats
Protocol compatibility : Works with the original Nest hardware
Simple validation : Thermostat can verify the hash locally without server communication
Next Steps
Get Status Check lock status
Set Temperature Set temperature