endpoint : a37j5ardzq7hal-ats.iot.ap-northeast-2.amazonaws.com
ref : https://theskenengineering.com/building-a-react-js-app-with-aws-iot/
device에서 aws mqtt broker에게 데이터를 publishing
react app은 적절한 cognito auth 절차 (현재는 인증 없이 풀어놓은 상태)를 거치고
인증 완료 이후 mqtt broker로부터 특정 topic을 Subscribe
현재 Python 코드는 ec2에서 디바이스 대신 데이터를 올리는 중.
https://kimsehwan96.github.io/Mqtt-React-Poc/
npm install aws-amplify
npm install aws-sdk
{
"region": "ap-northeast-2",
"cognitoUserPoolId": "ap-northeast-2_0OJVDWgPa",
"cognitoUserPoolClientId": "3siov6brjoecvq3d0djgrsohvd",
"cognitoIdentityPoolId": "ap-northeast-2:b100e387-8238-4ac6-a1e2-5d18dd5ec77a",
"mqttBrokerEndpoint": "a37j5ardzq7hal-ats.iot.ap-northeast-2.amazonaws.com"
}
import Amplify, {PubSub} from 'aws-amplify';
import {AWSIoTProvider} from '@aws-amplify/pubsub/lib/Providers';
import awsConfig from './awsConfig.json'
import React, {useEffect, useState, Suspense} from 'react';
import {makeStyles, useTheme} from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';
import styled from "styled-components";
import RealTimeChart from './components/RealTimeChart';
function init(awsConfig) {
Amplify.configure({
Auth: {
userPoolId: awsConfig.cognitoUserPoolId,
userPoolWebClientId: awsConfig.cognitoUserPoolClientId,
identityPoolId: awsConfig.cognitoIdentityPoolId,
region: awsConfig.region,
}
});
Amplify.addPluggable(new AWSIoTProvider({
aws_pubsub_region: awsConfig.region,
aws_pubsub_endpoint: `wss://${awsConfig.mqttBrokerEndpoint}/mqtt`,
}));
}
const topic = 'app/test' //우리가 임의로 지정 할 수 있는 mqtt subscribe 토픽
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
paper: {
padding: theme.spacing(2),
textAlign: 'center',
color: theme.palette.text.primary,
},
}));
const getTime = (unixTimestamp) => new Date((unixTimestamp + 3600 * 9) * 1000) //for korean time
function App() {
init(awsConfig);
const [fields, setFields] = useState([])
const [values, setValues] = useState([0, 0, 0, 0, 0])
const [provider, setProvider] = useState("");
const classes = useStyles();
useEffect(() => {
PubSub.subscribe('app/test', {
provider: 'AWSIoTProvider'
}).subscribe({
next: (data) => {
setFields(data.value.fields);
setValues(data.value.values);
setProvider(JSON.stringify(data));
console.log(data);
},
error: (error) => console.log(error)
})
})
return (
<Suspense fallback={<div>Loading....</div>}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}> Hello world </Paper>
</Grid>
{
fields.map((item, idx) => {
return (
(item === "timestamp") ? null :
<Grid item xs={4}>
<RealTimeChartWrap>
<RealTimeChart
title={item}
value={values[idx]}
time={Date.now()}
/>
</RealTimeChartWrap>
</Grid>
)
})
}
<Grid item xs={12}>
<Paper className={classes.paper} variant="outlined" square>
<p> This is provider context </p>
<p> {provider} </p>
</Paper>
</Grid>
</Grid>
</Suspense>
);
}
export default React.memo(App);
const RealTimeChartWrap = styled.div`
margin-top: 10px;
display: flex;
justify-content: space-between;
align-items: center;
`;
import Amplify, {PubSub} from 'aws-amplify';
import {AWSIoTProvider} from '@aws-amplify/pubsub/lib/Providers';
import awsConfig from './awsConfig.json'
import React, {useEffect, useState} from 'react';
import {makeStyles, useTheme} from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import Grid from '@material-ui/core/Grid';
import {LineChart, Line, XAxis, YAxis, Label, ResponsiveContainer} from 'recharts';
function init(awsConfig) {
Amplify.configure({
Auth: {
userPoolId: awsConfig.cognitoUserPoolId,
userPoolWebClientId: awsConfig.cognitoUserPoolClientId,
identityPoolId: awsConfig.cognitoIdentityPoolId,
region: awsConfig.region,
}
});
Amplify.addPluggable(new AWSIoTProvider({
aws_pubsub_region: awsConfig.region,
aws_pubsub_endpoint: `wss://${awsConfig.mqttBrokerEndpoint}/mqtt`,
}));
}
init
함수를 만들었다. aws sdk를 사용하기 위한 인증 내용을 세팅하는 내용임.function App() {
init(awsConfig);
const [fields, setFields] = useState([])
const [values, setValues] = useState([0, 0, 0, 0, 0])
const [provider, setProvider] = useState("");
const classes = useStyles();
useEffect(() => {
PubSub.subscribe('app/test', {
provider: 'AWSIoTProvider'
}).subscribe({
next: (data) => {
setFields(data.value.fields);
setValues(data.value.values);
setProvider(JSON.stringify(data));
console.log(data);
},
error: (error) => console.log(error)
})
})
yml
형식으로 정의 가능.import logging
import time
import json
from random import randint
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
host = 'a37j5ardzq7hal-ats.iot.ap-northeast-2.amazonaws.com'
port = 8883 # TLS SSL
rootCaPath = './root.pem'
certificatePath = './TestDevice_0214.cert.pem'
privateCertificatePath = './TestDevice_0214.private.key'
clientId = 'iotconsole-{}'.format(randint(1, 5000))
topic = 'app/test'
AllowedActions = ['both', 'publish', 'subscribe']
logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)
myAWSIoTMQTTClient = None
myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId)
myAWSIoTMQTTClient.configureEndpoint(host, port)
myAWSIoTMQTTClient.configureCredentials(rootCaPath, privateCertificatePath, certificatePath)
myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing
myAWSIoTMQTTClient.configureDrainingFrequency(2) # Draining: 2 Hz
myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10) # 10 sec
myAWSIoTMQTTClient.configureMQTTOperationTimeout(5) # 5 sec
myAWSIoTMQTTClient.connect()
loopCount = 0
def make_message(rand_randge: tuple) -> dict:
message = {
"fields": [
"timestamp",
"speed",
"rpm",
"temperature",
"engineLoad"
],
"values": [
time.time(),
randint(*rand_randge),
randint(*rand_randge),
randint(*rand_randge),
randint(*rand_randge)
]
}
return message
while True:
myAWSIoTMQTTClient.publish(topic, json.dumps(make_message((1, 1000))), 1)
print("published.")
time.sleep(1)
$nohup python3 main.py &