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

greengrass-discovery.mddocs/

0

# Greengrass Discovery

1

2

Discovery service for finding and connecting to AWS Greengrass Core devices in local networks. Enables devices to discover Greengrass cores, retrieve connectivity information, and obtain CA certificates for establishing secure connections within the Greengrass group.

3

4

## Capabilities

5

6

### Discovery Provider

7

8

Create a discovery client to find Greengrass cores and retrieve connectivity information for local communication.

9

10

```python { .api }

11

class DiscoveryInfoProvider:

12

def __init__(self, caPath: str = "", certPath: str = "", keyPath: str = "", host: str = "", port: int = 8443, timeoutSec: int = 120):

13

"""

14

Create Greengrass discovery client.

15

16

Args:

17

caPath (str): Path to root CA certificate file

18

certPath (str): Path to device certificate file

19

keyPath (str): Path to private key file

20

host (str): Discovery service endpoint hostname

21

port (int): Discovery service port (default 8443)

22

timeoutSec (int): Discovery request timeout in seconds

23

"""

24

```

25

26

### Discovery Configuration

27

28

Configure discovery endpoint, credentials, and timeout settings.

29

30

```python { .api }

31

def configureEndpoint(self, host: str, port: int = 8443):

32

"""

33

Configure discovery service endpoint.

34

35

Args:

36

host (str): Discovery service hostname

37

port (int): Discovery service port (default 8443)

38

"""

39

40

def configureCredentials(self, caPath: str, certPath: str, keyPath: str):

41

"""

42

Configure X.509 certificate credentials for discovery authentication.

43

44

Args:

45

caPath (str): Path to root CA certificate file

46

certPath (str): Path to device certificate file

47

keyPath (str): Path to private key file

48

"""

49

50

def configureTimeout(self, timeoutSec: int):

51

"""

52

Configure discovery request timeout.

53

54

Args:

55

timeoutSec (int): Timeout in seconds for discovery requests

56

"""

57

```

58

59

### Discovery Operations

60

61

Perform discovery requests to find Greengrass cores and retrieve connectivity information.

62

63

```python { .api }

64

def discover(self, thingName: str) -> 'DiscoveryInfo':

65

"""

66

Discover Greengrass cores for the specified thing.

67

68

Args:

69

thingName (str): AWS IoT thing name to discover cores for

70

71

Returns:

72

DiscoveryInfo: Discovery results with core connectivity information

73

74

Raises:

75

DiscoveryTimeoutException: Discovery request timed out

76

DiscoveryUnauthorizedException: Authentication failed

77

DiscoveryDataNotFoundException: No discovery data found for thing

78

"""

79

```

80

81

## Discovery Data Models

82

83

Data structures for managing Greengrass discovery information and connectivity details.

84

85

### DiscoveryInfo

86

87

Container for all discovery information including cores, groups, and CA certificates.

88

89

```python { .api }

90

class DiscoveryInfo:

91

def getAllCores(self) -> list:

92

"""

93

Get all core connectivity information.

94

95

Returns:

96

list: List of CoreConnectivityInfo objects

97

"""

98

99

def getAllCas(self) -> list:

100

"""

101

Get all CA certificates from discovery.

102

103

Returns:

104

list: List of (groupId, caContent) tuples

105

"""

106

107

def getAllGroups(self) -> list:

108

"""

109

Get all group connectivity information.

110

111

Returns:

112

list: List of GroupConnectivityInfo objects

113

"""

114

115

def toObjectAtGroupLevel(self) -> dict:

116

"""

117

Convert discovery info to group-level dictionary structure.

118

119

Returns:

120

dict: Dictionary with groupId keys and GroupConnectivityInfo values

121

"""

122

```

123

124

### GroupConnectivityInfo

125

126

Connectivity information for a Greengrass group containing cores and CA certificates.

127

128

```python { .api }

129

class GroupConnectivityInfo:

130

# Properties

131

groupId: str # Greengrass group ID

132

coreConnectivityInfoList: list # List of CoreConnectivityInfo objects

133

caList: list # List of CA certificates for this group

134

135

def getCoreConnectivityInfo(self, coreThingArn: str) -> 'CoreConnectivityInfo':

136

"""

137

Get connectivity info for specific core by ARN.

138

139

Args:

140

coreThingArn (str): Core thing ARN to find

141

142

Returns:

143

CoreConnectivityInfo: Connectivity info for the specified core

144

"""

145

146

def appendCoreConnectivityInfo(self, coreConnectivityInfo: 'CoreConnectivityInfo'):

147

"""

148

Add core connectivity information to this group.

149

150

Args:

151

coreConnectivityInfo (CoreConnectivityInfo): Core connectivity info to add

152

"""

153

154

def appendCa(self, ca: str):

155

"""

156

Add CA certificate to this group.

157

158

Args:

159

ca (str): CA certificate content to add

160

"""

161

```

162

163

### CoreConnectivityInfo

164

165

Connectivity information for a specific Greengrass core device.

166

167

```python { .api }

168

class CoreConnectivityInfo:

169

# Properties

170

coreThingArn: str # Core thing ARN

171

groupId: str # Associated group ID

172

connectivityInfoList: list # List of ConnectivityInfo objects

173

174

def getConnectivityInfo(self, id: str) -> 'ConnectivityInfo':

175

"""

176

Get connectivity info by ID.

177

178

Args:

179

id (str): Connectivity info ID to find

180

181

Returns:

182

ConnectivityInfo: Connectivity information for the specified ID

183

"""

184

185

def appendConnectivityInfo(self, connectivityInfo: 'ConnectivityInfo'):

186

"""

187

Add connectivity information to this core.

188

189

Args:

190

connectivityInfo (ConnectivityInfo): Connectivity info to add

191

"""

192

```

193

194

### ConnectivityInfo

195

196

Individual connectivity endpoint information for reaching a Greengrass core.

197

198

```python { .api }

199

class ConnectivityInfo:

200

# Properties

201

id: str # Connectivity info ID

202

host: str # Hostname or IP address

203

port: int # Port number

204

metadata: dict # Additional metadata

205

```

206

207

## Usage Examples

208

209

### Basic Discovery

210

211

```python

212

from AWSIoTPythonSDK.core.greengrass.discovery.providers import DiscoveryInfoProvider

213

from AWSIoTPythonSDK.exception.AWSIoTExceptions import DiscoveryTimeoutException

214

import json

215

216

# Create discovery provider

217

discoveryInfoProvider = DiscoveryInfoProvider()

218

219

# Configure discovery endpoint

220

discoveryInfoProvider.configureEndpoint("greengrass-ats.iot.region.amazonaws.com")

221

222

# Configure credentials

223

discoveryInfoProvider.configureCredentials(

224

"rootCA.crt",

225

"certificate.crt",

226

"private.key"

227

)

228

229

# Configure timeout

230

discoveryInfoProvider.configureTimeout(10)

231

232

try:

233

# Perform discovery

234

discoveryInfo = discoveryInfoProvider.discover("myThingName")

235

236

# Get all discovered cores

237

cores = discoveryInfo.getAllCores()

238

print(f"Discovered {len(cores)} Greengrass cores")

239

240

# Get all CA certificates

241

cas = discoveryInfo.getAllCas()

242

print(f"Retrieved {len(cas)} CA certificates")

243

244

# Print discovery results

245

for core in cores:

246

print(f"Core: {core.coreThingArn}")

247

print(f"Group: {core.groupId}")

248

for conn_info in core.connectivityInfoList:

249

print(f" Endpoint: {conn_info.host}:{conn_info.port}")

250

251

except DiscoveryTimeoutException:

252

print("Discovery request timed out")

253

except Exception as e:

254

print(f"Discovery failed: {e}")

255

```

256

257

### Core Selection and Connection

258

259

```python

260

from AWSIoTPythonSDK.core.greengrass.discovery.providers import DiscoveryInfoProvider

261

import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT

262

import json

263

import ssl

264

import tempfile

265

import os

266

267

# Perform discovery

268

discoveryInfoProvider = DiscoveryInfoProvider()

269

discoveryInfoProvider.configureEndpoint("greengrass-ats.iot.region.amazonaws.com")

270

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

271

272

discoveryInfo = discoveryInfoProvider.discover("myDevice")

273

274

# Get group-level information

275

groups = discoveryInfo.toObjectAtGroupLevel()

276

277

for group_id, group_info in groups.items():

278

print(f"Processing group: {group_id}")

279

280

# Write group CA certificates to temporary files

281

ca_files = []

282

for i, (_, ca_content) in enumerate(group_info.caList):

283

ca_file = tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.crt')

284

ca_file.write(ca_content)

285

ca_file.close()

286

ca_files.append(ca_file.name)

287

288

# Try to connect to each core in the group

289

for core in group_info.coreConnectivityInfoList:

290

print(f"Trying to connect to core: {core.coreThingArn}")

291

292

# Try each connectivity option for this core

293

for conn_info in core.connectivityInfoList:

294

try:

295

print(f"Attempting connection to {conn_info.host}:{conn_info.port}")

296

297

# Create MQTT client for this core

298

client = AWSIoTPyMQTT.AWSIoTMQTTClient("greengrassDevice")

299

client.configureEndpoint(conn_info.host, conn_info.port)

300

301

# Use the first CA file for this group

302

if ca_files:

303

client.configureCredentials(ca_files[0], "private.key", "certificate.crt")

304

305

# Configure connection parameters

306

client.configureConnectDisconnectTimeout(10)

307

client.configureMQTTOperationTimeout(5)

308

309

# Attempt connection

310

if client.connect():

311

print(f"Successfully connected to {conn_info.host}:{conn_info.port}")

312

313

# Test basic MQTT operations

314

client.publish("greengrass/test", f"Hello from {conn_info.host}", 0)

315

client.disconnect()

316

317

# Clean up CA files

318

for ca_file in ca_files:

319

os.unlink(ca_file)

320

321

# Connection successful, exit loops

322

exit()

323

324

except Exception as e:

325

print(f"Failed to connect to {conn_info.host}:{conn_info.port}: {e}")

326

continue

327

328

# Clean up CA files if no connection succeeded

329

for ca_file in ca_files:

330

os.unlink(ca_file)

331

```

332

333

### Advanced Discovery with Error Handling

334

335

```python

336

from AWSIoTPythonSDK.core.greengrass.discovery.providers import DiscoveryInfoProvider

337

from AWSIoTPythonSDK.exception.AWSIoTExceptions import (

338

DiscoveryTimeoutException,

339

DiscoveryUnauthorizedException,

340

DiscoveryDataNotFoundException,

341

DiscoveryThrottlingException,

342

DiscoveryFailure

343

)

344

import time

345

import json

346

347

def perform_discovery_with_retry(thing_name, max_retries=3, retry_delay=5):

348

"""Perform discovery with retry logic and comprehensive error handling"""

349

350

discoveryInfoProvider = DiscoveryInfoProvider()

351

discoveryInfoProvider.configureEndpoint("greengrass-ats.iot.region.amazonaws.com", 8443)

352

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

353

discoveryInfoProvider.configureTimeout(30)

354

355

for attempt in range(max_retries):

356

try:

357

print(f"Discovery attempt {attempt + 1}/{max_retries} for thing: {thing_name}")

358

359

discoveryInfo = discoveryInfoProvider.discover(thing_name)

360

361

# Validate discovery results

362

cores = discoveryInfo.getAllCores()

363

if not cores:

364

raise Exception("No Greengrass cores found in discovery response")

365

366

cas = discoveryInfo.getAllCas()

367

if not cas:

368

raise Exception("No CA certificates found in discovery response")

369

370

print(f"Discovery successful: {len(cores)} cores, {len(cas)} CAs")

371

return discoveryInfo

372

373

except DiscoveryTimeoutException:

374

print(f"Discovery timeout on attempt {attempt + 1}")

375

if attempt < max_retries - 1:

376

print(f"Retrying in {retry_delay} seconds...")

377

time.sleep(retry_delay)

378

379

except DiscoveryUnauthorizedException:

380

print("Discovery unauthorized - check credentials and thing permissions")

381

break # Don't retry auth failures

382

383

except DiscoveryDataNotFoundException:

384

print(f"No discovery data found for thing: {thing_name}")

385

print("Ensure thing is associated with a Greengrass group")

386

break # Don't retry data not found

387

388

except DiscoveryThrottlingException:

389

print("Discovery request throttled")

390

if attempt < max_retries - 1:

391

backoff_delay = retry_delay * (2 ** attempt) # Exponential backoff

392

print(f"Backing off for {backoff_delay} seconds...")

393

time.sleep(backoff_delay)

394

395

except DiscoveryFailure as e:

396

print(f"Discovery service failure: {e}")

397

if attempt < max_retries - 1:

398

print(f"Retrying in {retry_delay} seconds...")

399

time.sleep(retry_delay)

400

401

except Exception as e:

402

print(f"Unexpected discovery error: {e}")

403

if attempt < max_retries - 1:

404

print(f"Retrying in {retry_delay} seconds...")

405

time.sleep(retry_delay)

406

407

raise Exception(f"Discovery failed after {max_retries} attempts")

408

409

def analyze_discovery_results(discoveryInfo):

410

"""Analyze and display discovery results in detail"""

411

412

print("=== Discovery Results Analysis ===")

413

414

# Group-level analysis

415

groups = discoveryInfo.toObjectAtGroupLevel()

416

print(f"Found {len(groups)} Greengrass groups")

417

418

for group_id, group_info in groups.items():

419

print(f"\nGroup: {group_id}")

420

print(f" Cores: {len(group_info.coreConnectivityInfoList)}")

421

print(f" CA Certificates: {len(group_info.caList)}")

422

423

# Analyze each core

424

for i, core in enumerate(group_info.coreConnectivityInfoList):

425

print(f" Core {i+1}: {core.coreThingArn}")

426

print(f" Connectivity options: {len(core.connectivityInfoList)}")

427

428

# Analyze connectivity options

429

for j, conn_info in enumerate(core.connectivityInfoList):

430

print(f" Option {j+1}: {conn_info.host}:{conn_info.port}")

431

if conn_info.metadata:

432

print(f" Metadata: {json.dumps(conn_info.metadata, indent=8)}")

433

434

# Provide recommendations

435

print("\n=== Recommendations ===")

436

total_cores = len(discoveryInfo.getAllCores())

437

if total_cores > 1:

438

print("Multiple cores available - consider load balancing or failover")

439

elif total_cores == 1:

440

print("Single core available - ensure high availability setup")

441

else:

442

print("No cores found - check Greengrass group configuration")

443

444

# Example usage

445

try:

446

discovery_results = perform_discovery_with_retry("myIoTDevice")

447

analyze_discovery_results(discovery_results)

448

except Exception as e:

449

print(f"Discovery completely failed: {e}")

450

```

451

452

## Types

453

454

```python { .api }

455

# Discovery exception types

456

class DiscoveryTimeoutException(Exception):

457

"""Raised when discovery request times out"""

458

459

class DiscoveryUnauthorizedException(Exception):

460

"""Raised when discovery authentication fails"""

461

462

class DiscoveryDataNotFoundException(Exception):

463

"""Raised when no discovery data found for thing"""

464

465

class DiscoveryThrottlingException(Exception):

466

"""Raised when discovery requests are throttled"""

467

468

class DiscoveryFailure(Exception):

469

"""Raised for general discovery service failures"""

470

471

# Discovery result structure

472

discovery_response = {

473

"GGGroups": [

474

{

475

"GGGroupId": "group-12345",

476

"Cores": [

477

{

478

"thingArn": "arn:aws:iot:region:account:thing/core-thing",

479

"Connectivity": [

480

{

481

"Id": "connection-1",

482

"HostAddress": "192.168.1.100",

483

"PortNumber": 8883,

484

"Metadata": {

485

"network": "local"

486

}

487

}

488

]

489

}

490

],

491

"CAs": [

492

"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"

493

]

494

}

495

]

496

}

497

```