or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

device-shadows.mdexception-handling.mdgreengrass-discovery.mdindex.mdiot-jobs.mdmqtt-client.md

device-shadows.mddocs/

0

# Device Shadow Management

1

2

Device shadow operations for synchronizing device state between physical devices and the cloud. Provides shadow retrieval, updates, deletion, and delta notifications for state changes. Device shadows are JSON documents that store and retrieve current state information for a device.

3

4

## Capabilities

5

6

### Shadow Client Creation

7

8

Create a specialized MQTT client for device shadow operations with automatic subscription management and optimized for time-sensitive shadow messages.

9

10

```python { .api }

11

class AWSIoTMQTTShadowClient:

12

def __init__(self, clientID: str, protocolType: int = MQTTv3_1_1, useWebsocket: bool = False, cleanSession: bool = True, awsIoTMQTTClient = None):

13

"""

14

Create AWS IoT MQTT Shadow client.

15

16

Args:

17

clientID (str): Client identifier for MQTT connection

18

protocolType (int): MQTT version (MQTTv3_1=3, MQTTv3_1_1=4)

19

useWebsocket (bool): Enable MQTT over WebSocket SigV4

20

cleanSession (bool): Start with clean session state

21

awsIoTMQTTClient (AWSIoTMQTTClient): Existing MQTT client to reuse (optional)

22

"""

23

```

24

25

### Shadow Handler Creation

26

27

Create individual shadow handlers for specific devices with configurable subscription persistence.

28

29

```python { .api }

30

def createShadowHandlerWithName(self, shadowName: str, isPersistentSubscribe: bool) -> 'deviceShadow':

31

"""

32

Create device shadow handler for named shadow.

33

34

Args:

35

shadowName (str): Name of the device shadow

36

isPersistentSubscribe (bool): Whether to maintain persistent subscriptions to shadow topics

37

38

Returns:

39

deviceShadow: Shadow handler for shadow operations

40

"""

41

```

42

43

### Connection Management

44

45

Shadow clients inherit all connection management from the base MQTT client.

46

47

```python { .api }

48

def getMQTTConnection(self) -> 'AWSIoTMQTTClient':

49

"""

50

Get underlying MQTT client for direct MQTT operations.

51

52

Returns:

53

AWSIoTMQTTClient: The underlying MQTT client instance

54

"""

55

```

56

57

### Shadow Operations

58

59

Individual device shadow operations for state management and synchronization.

60

61

```python { .api }

62

class deviceShadow:

63

def shadowGet(self, callback: callable, timeout: int) -> str:

64

"""

65

Retrieve current shadow state from AWS IoT.

66

67

Args:

68

callback (callable): Response callback (topic, payload) -> None

69

timeout (int): Operation timeout in seconds

70

71

Returns:

72

str: Token for tracking this shadow operation

73

"""

74

75

def shadowUpdate(self, JSONPayload: str, callback: callable, timeout: int) -> str:

76

"""

77

Update shadow state in AWS IoT.

78

79

Args:

80

JSONPayload (str): JSON shadow update payload

81

callback (callable): Response callback (topic, payload) -> None

82

timeout (int): Operation timeout in seconds

83

84

Returns:

85

str: Token for tracking this shadow operation

86

"""

87

88

def shadowDelete(self, callback: callable, timeout: int) -> str:

89

"""

90

Delete shadow from AWS IoT.

91

92

Args:

93

callback (callable): Response callback (topic, payload) -> None

94

timeout (int): Operation timeout in seconds

95

96

Returns:

97

str: Token for tracking this shadow operation

98

"""

99

```

100

101

### Delta Notifications

102

103

Register for notifications when shadow desired state differs from reported state.

104

105

```python { .api }

106

def shadowRegisterDeltaCallback(self, callback: callable):

107

"""

108

Register callback for shadow delta events.

109

110

Args:

111

callback (callable): Delta callback (topic, payload) -> None

112

"""

113

114

def shadowUnregisterDeltaCallback(self):

115

"""Unregister delta callback for this shadow."""

116

```

117

118

## Usage Examples

119

120

### Basic Shadow Operations

121

122

```python

123

import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT

124

import json

125

import time

126

127

# Create shadow client

128

shadowClient = AWSIoTPyMQTT.AWSIoTMQTTShadowClient("myShadowClient")

129

shadowClient.configureEndpoint("endpoint.iot.region.amazonaws.com", 8883)

130

shadowClient.configureCredentials("rootCA.crt", "private.key", "certificate.crt")

131

132

# Configure connection

133

shadowClient.configureAutoReconnectBackoffTime(1, 32, 20)

134

shadowClient.configureConnectDisconnectTimeout(10)

135

shadowClient.configureMQTTOperationTimeout(5)

136

137

# Connect to AWS IoT

138

shadowClient.connect()

139

140

# Create device shadow handler

141

deviceShadowHandler = shadowClient.createShadowHandlerWithName("myDevice", True)

142

143

# Shadow response callbacks

144

def shadowUpdateCallback(payload, responseStatus, token):

145

if responseStatus == "timeout":

146

print("Shadow update request timed out")

147

elif responseStatus == "accepted":

148

print("Shadow update accepted")

149

elif responseStatus == "rejected":

150

print("Shadow update rejected")

151

152

def shadowGetCallback(payload, responseStatus, token):

153

if responseStatus == "timeout":

154

print("Shadow get request timed out")

155

elif responseStatus == "accepted":

156

payloadDict = json.loads(payload)

157

print(f"Shadow state: {payloadDict}")

158

elif responseStatus == "rejected":

159

print("Shadow get rejected")

160

161

# Get current shadow state

162

deviceShadowHandler.shadowGet(shadowGetCallback, 5)

163

164

# Update shadow state

165

shadowPayload = {

166

"state": {

167

"desired": {

168

"temperature": 25.0,

169

"humidity": 60.0

170

},

171

"reported": {

172

"temperature": 23.5,

173

"humidity": 58.0

174

}

175

}

176

}

177

178

deviceShadowHandler.shadowUpdate(json.dumps(shadowPayload), shadowUpdateCallback, 5)

179

```

180

181

### Delta Handling

182

183

```python

184

import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT

185

import json

186

187

# Create and configure shadow client

188

shadowClient = AWSIoTPyMQTT.AWSIoTMQTTShadowClient("deltaClient")

189

shadowClient.configureEndpoint("endpoint.iot.region.amazonaws.com", 8883)

190

shadowClient.configureCredentials("rootCA.crt", "private.key", "certificate.crt")

191

shadowClient.connect()

192

193

# Create shadow handler

194

deviceShadowHandler = shadowClient.createShadowHandlerWithName("myDevice", True)

195

196

# Delta callback - called when desired state differs from reported state

197

def shadowDeltaCallback(payload, responseStatus, token):

198

print(f"Received shadow delta: {payload}")

199

deltaPayload = json.loads(payload)

200

201

# Extract delta state changes

202

if "state" in deltaPayload:

203

deltaState = deltaPayload["state"]

204

print(f"Delta state changes: {deltaState}")

205

206

# Apply delta changes to device

207

for key, value in deltaState.items():

208

print(f"Updating device {key} to {value}")

209

# Implement device-specific logic here

210

211

# Report updated state back to shadow

212

reportedPayload = {

213

"state": {

214

"reported": deltaState

215

}

216

}

217

deviceShadowHandler.shadowUpdate(json.dumps(reportedPayload), shadowUpdateCallback, 5)

218

219

def shadowUpdateCallback(payload, responseStatus, token):

220

if responseStatus == "accepted":

221

print("Device state updated successfully")

222

223

# Register for delta notifications

224

deviceShadowHandler.shadowRegisterDeltaCallback(shadowDeltaCallback)

225

226

# Keep client running to receive delta notifications

227

try:

228

while True:

229

time.sleep(1)

230

except KeyboardInterrupt:

231

deviceShadowHandler.shadowUnregisterDeltaCallback()

232

shadowClient.disconnect()

233

```

234

235

### Multiple Shadow Management

236

237

```python

238

import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT

239

import json

240

241

# Create shadow client

242

shadowClient = AWSIoTPyMQTT.AWSIoTMQTTShadowClient("multiShadowClient")

243

shadowClient.configureEndpoint("endpoint.iot.region.amazonaws.com", 8883)

244

shadowClient.configureCredentials("rootCA.crt", "private.key", "certificate.crt")

245

shadowClient.connect()

246

247

# Create multiple shadow handlers

248

thermostatShadow = shadowClient.createShadowHandlerWithName("thermostat", True)

249

lightingShadow = shadowClient.createShadowHandlerWithName("lighting", True)

250

securityShadow = shadowClient.createShadowHandlerWithName("security", True)

251

252

# Shadow-specific callbacks

253

def thermostatCallback(payload, responseStatus, token):

254

if responseStatus == "accepted":

255

print(f"Thermostat shadow updated: {payload}")

256

257

def lightingCallback(payload, responseStatus, token):

258

if responseStatus == "accepted":

259

print(f"Lighting shadow updated: {payload}")

260

261

def securityCallback(payload, responseStatus, token):

262

if responseStatus == "accepted":

263

print(f"Security shadow updated: {payload}")

264

265

# Update each shadow independently

266

thermostat_state = {

267

"state": {

268

"reported": {

269

"temperature": 22.0,

270

"target_temperature": 24.0

271

}

272

}

273

}

274

275

lighting_state = {

276

"state": {

277

"reported": {

278

"brightness": 80,

279

"color": {"r": 255, "g": 255, "b": 255}

280

}

281

}

282

}

283

284

security_state = {

285

"state": {

286

"reported": {

287

"armed": True,

288

"sensors": {"door": "closed", "motion": "inactive"}

289

}

290

}

291

}

292

293

# Perform shadow updates

294

thermostatShadow.shadowUpdate(json.dumps(thermostat_state), thermostatCallback, 5)

295

lightingShadow.shadowUpdate(json.dumps(lighting_state), lightingCallback, 5)

296

securityShadow.shadowUpdate(json.dumps(security_state), securityCallback, 5)

297

```

298

299

### Shadow Document Structure

300

301

```python

302

# Example shadow document structure

303

shadow_document = {

304

"state": {

305

"desired": {

306

# Desired device state set by applications

307

"temperature": 25.0,

308

"mode": "heat"

309

},

310

"reported": {

311

# Current device state reported by device

312

"temperature": 23.5,

313

"mode": "heat",

314

"connected": True

315

},

316

"delta": {

317

# Difference between desired and reported (read-only)

318

"temperature": 1.5

319

}

320

},

321

"metadata": {

322

# Timestamps and version information

323

"desired": {

324

"temperature": {"timestamp": 1609459200},

325

"mode": {"timestamp": 1609459200}

326

},

327

"reported": {

328

"temperature": {"timestamp": 1609459180},

329

"mode": {"timestamp": 1609459180},

330

"connected": {"timestamp": 1609459180}

331

}

332

},

333

"version": 123,

334

"timestamp": 1609459200

335

}

336

```

337

338

## Types

339

340

```python { .api }

341

# Shadow response callback signature

342

def shadowCallback(payload: str, responseStatus: str, token: str) -> None:

343

"""

344

Shadow operation response callback.

345

346

Args:

347

payload (str): JSON response payload

348

responseStatus (str): "accepted", "rejected", or "timeout"

349

token (str): Token from the shadow operation

350

"""

351

352

# Shadow delta callback signature

353

def shadowDeltaCallback(payload: str, responseStatus: str, token: str) -> None:

354

"""

355

Shadow delta notification callback.

356

357

Args:

358

payload (str): JSON delta payload with state differences

359

responseStatus (str): Always "delta" for delta callbacks

360

token (str): Token from delta notification

361

"""

362

363

# Shadow operation response statuses

364

SHADOW_ACCEPTED = "accepted"

365

SHADOW_REJECTED = "rejected"

366

SHADOW_TIMEOUT = "timeout"

367

SHADOW_DELTA = "delta"

368

```