2020-01-23 17:01:32 -08:00
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
# Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# This file is licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License. A copy of
# the License is located at
2023-10-18 10:35:05 -07:00
#
2020-01-23 17:01:32 -08:00
# http://aws.amazon.com/apache2.0/
2023-10-18 10:35:05 -07:00
#
2020-01-23 17:01:32 -08:00
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
# snippet-comment:[These are tags for the AWS doc team's sample catalog. Do not remove.]
# snippet-sourcedescription:[thing_performance.py demonstrates how to push CPU and memory usage data to a thing's device shadow in AWS IoT.]
# snippet-service:[iot]
# snippet-sourcesyntax:[python]
# snippet-keyword:[Python]
# snippet-keyword:[AWS IoT]
# snippet-keyword:[Code Sample]
# snippet-keyword:[AWSIoTSDK]
# snippet-keyword:[AWSIoTMQTTShadowClient]
# snippet-sourcetype:[full-example]
# snippet-sourcedate:[2020-01-23]
# snippet-sourceauthor:[FThompsonAWS]
# snippet-start:[iot.python.thing_performance.complete]
2023-12-19 08:05:04 -06:00
import AWSIoTPythonSDK . MQTTLib as AWSIoTPyMQTT
2020-01-23 17:01:32 -08:00
import json
import psutil
import argparse
import logging
import time
2023-10-18 10:35:05 -07:00
2020-02-04 12:37:38 -08:00
# Configures the argument parser for this program.
2020-01-23 17:01:32 -08:00
def configureParser ( ) :
parser = argparse . ArgumentParser ( )
2023-10-18 10:35:05 -07:00
parser . add_argument (
" -e " ,
" --endpoint " ,
action = " store " ,
required = True ,
dest = " host " ,
help = " Your AWS IoT custom endpoint " ,
)
parser . add_argument (
" -r " ,
" --rootCA " ,
action = " store " ,
required = True ,
dest = " rootCAPath " ,
help = " Root CA file path " ,
)
parser . add_argument (
" -c " ,
" --cert " ,
action = " store " ,
required = True ,
dest = " certificatePath " ,
help = " Certificate file path " ,
)
parser . add_argument (
" -k " ,
" --key " ,
action = " store " ,
required = True ,
dest = " privateKeyPath " ,
help = " Private key file path " ,
)
parser . add_argument (
" -p " ,
" --port " ,
action = " store " ,
dest = " port " ,
type = int ,
default = 8883 ,
help = " Port number override " ,
)
parser . add_argument (
" -n " ,
" --thingName " ,
action = " store " ,
required = True ,
dest = " thingName " ,
help = " Targeted thing name " ,
)
parser . add_argument (
" -d " ,
" --requestDelay " ,
action = " store " ,
dest = " requestDelay " ,
type = float ,
default = 1 ,
help = " Time between requests (in seconds) " ,
)
parser . add_argument (
" -v " ,
" --enableLogging " ,
action = " store_true " ,
dest = " enableLogging " ,
help = " Enable logging for the AWS IoT Device SDK for Python " ,
)
2020-01-23 17:01:32 -08:00
return parser
# An MQTT shadow client that uploads device performance data to AWS IoT at a regular interval.
class PerformanceShadowClient :
2023-10-18 10:35:05 -07:00
def __init__ (
self ,
thingName ,
host ,
port ,
rootCAPath ,
privateKeyPath ,
certificatePath ,
requestDelay ,
) :
2020-01-23 17:01:32 -08:00
self . thingName = thingName
self . host = host
self . port = port
self . rootCAPath = rootCAPath
self . privateKeyPath = privateKeyPath
self . certificatePath = certificatePath
self . requestDelay = requestDelay
# Updates this thing's shadow with system performance data at a regular interval.
def run ( self ) :
print ( " Connecting MQTT client for {} ... " . format ( self . thingName ) )
mqttClient = self . configureMQTTClient ( )
mqttClient . connect ( )
print ( " MQTT client for {} connected " . format ( self . thingName ) )
2023-10-18 10:35:05 -07:00
deviceShadowHandler = mqttClient . createShadowHandlerWithName (
self . thingName , True
)
2020-01-23 17:01:32 -08:00
print ( " Running performance shadow client for {} ... \n " . format ( self . thingName ) )
while True :
performance = self . readPerformance ( )
print ( " [ {} ] " . format ( self . thingName ) )
print ( " CPU: \t {} % " . format ( performance [ " cpu " ] ) )
print ( " Memory: \t {} % \n " . format ( performance [ " memory " ] ) )
2023-10-18 10:35:05 -07:00
payload = { " state " : { " reported " : performance } }
deviceShadowHandler . shadowUpdate (
json . dumps ( payload ) , self . shadowUpdateCallback , 5
)
2020-01-23 17:01:32 -08:00
time . sleep ( args . requestDelay )
# Configures the MQTT shadow client for this thing.
def configureMQTTClient ( self ) :
2023-12-19 08:05:04 -06:00
mqttClient = AWSIoTPyMQTT . AWSIoTMQTTShadowClient ( self . thingName )
2020-01-23 17:01:32 -08:00
mqttClient . configureEndpoint ( self . host , self . port )
2023-10-18 10:35:05 -07:00
mqttClient . configureCredentials (
self . rootCAPath , self . privateKeyPath , self . certificatePath
)
2020-01-23 17:01:32 -08:00
mqttClient . configureAutoReconnectBackoffTime ( 1 , 32 , 20 )
mqttClient . configureConnectDisconnectTimeout ( 10 )
mqttClient . configureMQTTOperationTimeout ( 5 )
return mqttClient
# Returns the local device's CPU usage, memory usage, and timestamp.
def readPerformance ( self ) :
cpu = psutil . cpu_percent ( )
memory = psutil . virtual_memory ( ) . percent
timestamp = time . time ( )
2023-10-18 10:35:05 -07:00
return { " cpu " : cpu , " memory " : memory , " timestamp " : timestamp }
2020-01-23 17:01:32 -08:00
# Prints the result of a shadow update call.
def shadowUpdateCallback ( self , payload , responseStatus , token ) :
print ( " [ {} ] " . format ( self . thingName ) )
print ( " Update request {} {} \n " . format ( token , responseStatus ) )
2020-01-27 15:14:14 -08:00
# Configures debug logging for the AWS IoT Device SDK for Python.
2020-01-23 17:01:32 -08:00
def configureLogging ( ) :
logger = logging . getLogger ( " AWSIoTPythonSDK.core " )
logger . setLevel ( logging . DEBUG )
streamHandler = logging . StreamHandler ( )
2023-10-18 10:35:05 -07:00
formatter = logging . Formatter (
" %(asctime)s - %(name)s - %(levelname)s - %(message)s "
)
2020-01-23 17:01:32 -08:00
streamHandler . setFormatter ( formatter )
logger . addHandler ( streamHandler )
# Runs the performance shadow client with user arguments.
if __name__ == " __main__ " :
parser = configureParser ( )
args = parser . parse_args ( )
2023-10-18 10:35:05 -07:00
if args . enableLogging :
2020-01-23 17:01:32 -08:00
configureLogging ( )
2023-10-18 10:35:05 -07:00
thingClient = PerformanceShadowClient (
args . thingName ,
args . host ,
args . port ,
args . rootCAPath ,
args . privateKeyPath ,
args . certificatePath ,
args . requestDelay ,
)
2020-01-23 17:01:32 -08:00
thingClient . run ( )
2023-10-18 10:35:05 -07:00
# snippet-end:[iot.python.thing_performance.complete]