Meter Reading AI Agent Setup Guide
This guide covers deployment and configuration of Meter Reading AI Agent.
Quick Start
Prerequisites
- AWS Account
- AWS CLI installed and configured
- CloudFormation execution permissions
- Access permissions to Bedrock AgentCore Runtime
- Access permissions to S3 Tables
Deploy Meter Reading AI Agent and Related Resources
Deploy CloudFormation Stack (CLI)
aws cloudformation create-stack \
--stack-name meter-reading-agent-stack \
--template-url https://cm-seller-resources.s3.us-east-1.amazonaws.com/meter-reading-ai-agent/cfn/reader-agent.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--region us-east-1Verify Deployment Completion
aws cloudformation describe-stacks \
--stack-name meter-reading-agent-stack \
--region us-east-1 \
--query 'Stacks[0].StackStatus'Retrieve Output Values
After deployment is complete, retrieve the following output values:
aws cloudformation describe-stacks \
--stack-name meter-reading-agent-stack \
--region us-east-1 \
--query 'Stacks[0].Outputs'Important output values:
RuntimeArn: AgentCore Runtime ARNEndpointArn: AgentCore Runtime Endpoint ARNImageBucketName: S3 bucket name for image uploadsKnowledgeBaseId: Knowledge Base IDKnowledgeBaseSourceBucketName: Knowledge Base source bucket nameMeterReadingsTableArn: S3 Tables table ARN
Deploy Sample Dashboard Implementation
Deploy Dashboard Stack (CLI)
aws cloudformation create-stack \
--stack-name meter-dashboard-stack \
--template-url https://cm-seller-resources.s3.us-east-1.amazonaws.com/meter-reading-ai-agent/cfn/dashboard-stack.yaml \
--parameters \
ParameterKey=ImageUri,ParameterValue=<ECR_IMAGE_URI> \
ParameterKey=S3TablesArn,ParameterValue=<S3_TABLES_ARN> \
ParameterKey=S3TablesNamespaceName,ParameterValue=meter_data \
ParameterKey=S3TablesTableName,ParameterValue=meter_readings \
--capabilities CAPABILITY_NAMED_IAM \
--region us-east-1Retrieve CloudFront URL
After deployment is complete, retrieve the CloudFront URL:
aws cloudformation describe-stacks \
--stack-name meter-dashboard-stack \
--region us-east-1 \
--query 'Stacks[0].Outputs[?OutputKey==`CloudFrontDistributionURL`].OutputValue' \
--output textConfiguration
Register Meter Reading Instructions
Register instruction files to the Knowledge Base source bucket.
Prepare Instruction File
Create instructions in Markdown format. Example:
markdown# Meter Reading Instructions ## Reading Procedure ...Download a sample from here.
Upload to S3 Bucket
# Get Knowledge Base source bucket name
KB_BUCKET=$(aws cloudformation describe-stacks \
--stack-name meter-reading-agent-stack \
--region us-east-1 \
--query 'Stacks[0].Outputs[?OutputKey==`KnowledgeBaseSourceBucketName`].OutputValue' \
--output text)
# Upload instruction file
aws s3 cp reading-instructions.md \
s3://${KB_BUCKET}/instructions/reading-instructions.md \
--region us-east-1Register Meter Specification File
Create meter specification files in JSON format and register them to the Knowledge Base source bucket.
Prepare Meter Specification File
Create in
meter-specs/meter-types.jsonformat:json{ "meter_types": [ { "id": "pressure-gauge-001", "name": "Pressure Gauge (Analog Single Needle)", "type": "pressure", "description": "Single needle pressure gauge with 0-10MPa range", "unit": "MPa", "min_value": 0, "max_value": 10, "graduation": 0.5, "reading_method": "Read the position indicated by the single needle", "validation_rules": { "min": 0, "max": 10, "decimal_places": 2 }, "qr_code_prefix": "PRESS" } ], "common_instructions": { "image_quality": "Take photos with sufficient lighting", "reading_angle": "Photograph the meter from the front", "qr_code": "Photograph the QR code together with the meter" } }Upload to S3 Bucket
# Get Knowledge Base source bucket name
KB_BUCKET=$(aws cloudformation describe-stacks \
--stack-name meter-reading-agent-stack \
--region us-east-1 \
--query 'Stacks[0].Outputs[?OutputKey==`KnowledgeBaseSourceBucketName`].OutputValue' \
--output text)
# Upload meter specification file
aws s3 cp meter-types.json \
s3://${KB_BUCKET}/meter-specs/meter-types.json \
--region us-east-1Synchronize Knowledge Base
Knowledge Base synchronization can be performed from the Bedrock console or CLI.
Synchronize via CLI:
# Get Knowledge Base ID and DataSource ID
KB_ID=$(aws cloudformation describe-stacks \
--stack-name meter-reading-agent-stack \
--region us-east-1 \
--query 'Stacks[0].Outputs[?OutputKey==`KnowledgeBaseId`].OutputValue' \
--output text)
DS_ID=$(aws cloudformation describe-stacks \
--stack-name meter-reading-agent-stack \
--region us-east-1 \
--query 'Stacks[0].Outputs[?OutputKey==`KnowledgeBaseDataSourceId`].OutputValue' \
--output text)
# Start synchronization job
aws bedrock start-ingestion-job \
--knowledge-base-id ${KB_ID} \
--data-source-id ${DS_ID} \
--region us-east-1
# Check synchronization job status
aws bedrock get-ingestion-job \
--knowledge-base-id ${KB_ID} \
--data-source-id ${DS_ID} \
--ingestion-job-id <JOB_ID> \
--region us-east-1Synchronize via Console:
- Access the AWS Bedrock console
- Select "Knowledge bases"
- Select the target Knowledge Base
- Open the "Data sources" tab
- Select the target data source and click "Sync"
Specifications
AI Agent Interface Specifications
Entry Point
Call the AgentCore Runtime endpoint in the following format:
Request Format:
{
"s3_bucket": "camera-image-123456789012-us-east-1",
"s3_key": "images/2025/01/15/image.jpg",
"session_id": "uuid-string",
"meter_info": {
"meter_id": "001",
"meter_type": "pressure",
"unit": "MPa"
}
}Response Format:
{
"meter_id": "001",
"meter_type": "pressure",
"reading_value": 5.5,
"status": "processed",
"reading_unit": "MPa",
"confidence_score": 0.95,
"image_s3_key": "images/2025/01/15/image.jpg",
"qr_code_data": "PRESS-001-A1F",
"processing_duration_ms": 12000,
"image_quality": 0.88,
"validation_passed": true,
"error_message": null,
"notes": null
}Field Descriptions
| Field Name | Type | Required | Description |
|---|---|---|---|
meter_id | string | Required | Unique identifier for the meter |
meter_type | string | Required | Meter type (pressure, temperature, flow, power, water) |
reading_value | number | Required | Reading value (numeric) |
status | string | Required | Processing status (processed, error, warning) |
reading_unit | string | Optional | Unit (MPa, °C, L/min, kWh, m³) |
confidence_score | number | Optional | Confidence score (0.0-1.0) |
image_s3_key | string | Optional | S3 key for the image file |
qr_code_data | string | Optional | Data read from QR code |
processing_duration_ms | integer | Optional | Processing time (milliseconds) |
image_quality | number | Optional | Image quality score (0.0-1.0) |
validation_passed | boolean | Optional | Validation result |
error_message | string | Optional | Error message (on error) |
notes | string | Optional | Notes |
Error Response
When an error occurs, the response is returned in the following format:
{
"error": "Error message",
"status": "error",
"meter_id": "001",
"meter_type": "pressure"
}Meter Specification File Format
Meter specification files are in JSON format with the following structure:
Schema Definition
{
"meter_types": [
{
"id": "string (required)",
"name": "string (required)",
"type": "string (required)",
"description": "string (required)",
"unit": "string (required)",
"min_value": "number (required)",
"max_value": "number (required)",
"graduation": "number (required)",
"reading_method": "string (required)",
"validation_rules": {
"min": "number (required)",
"max": "number (required)",
"decimal_places": "integer (required)"
},
"qr_code_prefix": "string (required)"
}
],
"common_instructions": {
"image_quality": "string (required)",
"reading_angle": "string (required)",
"qr_code": "string (required)",
"error_handling": "string (required)",
"confidence": "string (required)"
}
}Meter Specification File Field Descriptions
Each element in the meter_types array:
| Field Name | Type | Description |
|---|---|---|
id | string | Unique ID for the meter type |
name | string | Display name for the meter type |
type | string | Meter category (pressure, temperature, flow, power, water) |
description | string | Meter description |
unit | string | Measurement unit |
min_value | number | Minimum measurement value |
max_value | number | Maximum measurement value |
graduation | number | Scale interval |
reading_method | string | Description of reading method |
validation_rules | object | Validation rules |
qr_code_prefix | string | QR code prefix (PRESS, TEMP, FLOW, POWER, WATER) |
Sample File
{
"meter_types": [
{
"id": "pressure-gauge-001",
"name": "Pressure Gauge (Analog Single Needle)",
"type": "pressure",
"description": "Single needle pressure gauge with 0-10MPa range. Scale graduation is 0.5MPa.",
"unit": "MPa",
"min_value": 0,
"max_value": 10,
"graduation": 0.5,
"reading_method": "Read the position indicated by the single needle. Interpolate when reading between scale marks.",
"validation_rules": {
"min": 0,
"max": 10,
"decimal_places": 2
},
"qr_code_prefix": "PRESS"
}
]
}File Location
Place meter specification files under the meter-specs/ prefix in the Knowledge Base source bucket:
s3://<knowledge-base-source-bucket>/
└── meter-specs/
└── meter-types.jsonS3 Tables Schema
Meter reading data is saved to S3 Tables with the following schema:
| Column Name | Type | Required | Description |
|---|---|---|---|
timestamp | timestamp | Required | Reading datetime (UTC) |
meter_id | string | Required | Meter ID |
meter_type | string | Required | Meter type |
reading_value | double | Required | Reading value |
reading_unit | string | Optional | Unit |
confidence_score | double | Optional | Confidence score |
image_s3_key | string | Optional | S3 key for image file |
qr_code_data | string | Optional | QR code data |
processing_duration_ms | int | Optional | Processing time (milliseconds) |
image_quality | double | Optional | Image quality score |
validation_passed | boolean | Optional | Validation result |
error_message | string | Optional | Error message |
notes | string | Optional | Notes |
status | string | Required | Status |
record_id | string | Required | Record ID (UUID) |
Troubleshooting
Deployment Related
Dashboard Stack Deployment Error
Error: "The maximum number of rules per security group has been reached."
Cause: Security group rule limit has been reached
Solution:
- Access the AWS Service Quotas console
- Check the "Inbound or outbound rules per security group" quota
- Submit a limit increase request if necessary
Error: CloudFormation stack enters CREATE_FAILED state
Cause: Insufficient IAM permissions, resource limits, template errors, etc.
Solution:
- Check stack events in the CloudFormation console
- Review error messages to identify the cause
- Add IAM permissions or check resource limits as needed
Knowledge Base Cannot Be Referenced
Cause: Knowledge Base ID configuration error, synchronization not complete
Solution:
- Verify the
KNOWLEDGE_BASE_IDenvironment variable is correctly set - Verify the Knowledge Base synchronization job is complete
- Check data source configuration
Other
QR Code Cannot Be Read
Cause: Insufficient image quality, invalid QR code format
Solution:
- Verify the image is clearly captured
- Verify the QR code format is
{PREFIX}-{METER_ID}-{LOCATION} - Verify the QR code is captured together with the meter
Low Reading Accuracy
Cause: Insufficient image quality, meter specification configuration error
Solution:
- Check image quality score (0.7 or higher recommended)
- Verify meter specification file is correctly registered
- Verify Knowledge Base synchronization is complete
- Retake with a clearer image
