Help us understand the problem. What is going on with this article?

AWS IoTのMQTT over WebSocketを使ってHTMLでsubscribeしたデータをリアルタイムグラフ化する

More than 3 years have passed since last update.

概要

AWS IoT Device Gatewayにpublishしたデータをwebsocket経由でブラウザでsubscribeして、グラフ化します。

Publisher

topic_2というトピックに対して、0,1,2,3とカウントアップしたデータをpublishします。

var count = 0;
const minimumDelay = 250;
timeout = setInterval(function() {
  count++;
  device.publish('topic_2', JSON.stringify({
     mode1Process: count
  }));
}, minimumDelay);

Subscriber

AWS IoTのMQTT over WebSocketにHTMLから接続してみた
を参考にブラウザからwebsocketでデータをsubscribeします。

リアルタイムなグラフ可視化はEpochというD3.jsベースのライブラリを使います。

ソースは以下の通り

<html lang="ja">
<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js" type="text/javascript"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core-min.js" type="text/javascript"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/hmac-min.js" type="text/javascript"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/sha256-min.js" type="text/javascript"></script>
  <script src="https://code.jquery.com/jquery-2.2.2.min.js"></script>
  <script src="./mqttws31.js" type="text/javascript"></script>
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  <script src="./dist/js/epoch.min.js"></script>
  <link rel="stylesheet" type="text/css" href="./dist/css/epoch.min.css">
  <script type="text/javascript">
    var RealTimeData = function(layers) {
        this.layers = layers;
        this.timestamp = ((new Date()).getTime() / 1000)|0;
    };


    RealTimeData.prototype.history = function(entries) {
        if (typeof(entries) != 'number' || !entries) {
            entries = 1;
        }

        var history = [];
        for (var k = 0; k < this.layers; k++) {
            history.push({ values: [] });
        }

        for (var i = 0; i < entries; i++) {
            for (var j = 0; j < this.layers; j++) {
                history[j].values.push({time: this.timestamp, y: 10});
            }
            this.timestamp++;
        }

        return history;
    };

    RealTimeData.prototype.next = function(y) {
        var entry = [];
        for (var i = 0; i < this.layers; i++) {
            entry.push({ time: this.timestamp, y: y });
        }
        this.timestamp++;
        return entry;
    }

    window.RealTimeData = RealTimeData;


$(function(){

  var data = new RealTimeData(1);

  var chart = $('#lineChart')
   .epoch({
        type: 'time.line',
        data: data.history(),
        axes: ['left', 'bottom']
    });

    var data_v = {
      messages: []
    };

    function SigV4Utils(){}

    SigV4Utils.sign = function(key, msg) {
      var hash = CryptoJS.HmacSHA256(msg, key);
      return hash.toString(CryptoJS.enc.Hex);
    };

    SigV4Utils.sha256 = function(msg) {
      var hash = CryptoJS.SHA256(msg);
      return hash.toString(CryptoJS.enc.Hex);
    };

    SigV4Utils.getSignatureKey = function(key, dateStamp, regionName, serviceName) {
      var kDate = CryptoJS.HmacSHA256(dateStamp, 'AWS4' + key);
      var kRegion = CryptoJS.HmacSHA256(regionName, kDate);
      var kService = CryptoJS.HmacSHA256(serviceName, kRegion);
      var kSigning = CryptoJS.HmacSHA256('aws4_request', kService);
      return kSigning;
    };

    function createEndpoint(regionName, awsIotEndpoint, accessKey, secretKey) {
      var time = moment.utc();
      var dateStamp = time.format('YYYYMMDD');
      var amzdate = dateStamp + 'T' + time.format('HHmmss') + 'Z';
      var service = 'iotdevicegateway';
      var region = regionName;
      var secretKey = secretKey;
      var accessKey = accessKey;
      var algorithm = 'AWS4-HMAC-SHA256';
      var method = 'GET';
      var canonicalUri = '/mqtt';
      var host = awsIotEndpoint;

      var credentialScope = dateStamp + '/' + region + '/' + service + '/' + 'aws4_request';
      var canonicalQuerystring = 'X-Amz-Algorithm=AWS4-HMAC-SHA256';
      canonicalQuerystring += '&X-Amz-Credential=' + encodeURIComponent(accessKey + '/' + credentialScope);
      canonicalQuerystring += '&X-Amz-Date=' + amzdate;
      canonicalQuerystring += '&X-Amz-SignedHeaders=host';

      var canonicalHeaders = 'host:' + host + '\n';
      var payloadHash = SigV4Utils.sha256('');
      var canonicalRequest = method + '\n' + canonicalUri + '\n' + canonicalQuerystring + '\n' + canonicalHeaders + '\nhost\n' + payloadHash;

      var stringToSign = algorithm + '\n' +  amzdate + '\n' +  credentialScope + '\n' +  SigV4Utils.sha256(canonicalRequest);
      var signingKey = SigV4Utils.getSignatureKey(secretKey, dateStamp, region, service);
      var signature = SigV4Utils.sign(signingKey, stringToSign);

      canonicalQuerystring += '&X-Amz-Signature=' + signature;
      return 'wss://' + host + canonicalUri + '?' + canonicalQuerystring;
    }

    var endpoint = createEndpoint(
        'us-east-1', // Your Region
        '<aws iot endpoint>', // Require 'lowercamelcase'!!
        '<YOUR_AWS_ACCESS_KEY>',
        '<YOUR_AWS_SECRET_ACCESS_KEY>');
    var clientId = Math.random().toString(36).substring(7);
    var client = new Paho.MQTT.Client(endpoint, clientId);
    var connectOptions = {
      useSSL: true,
      timeout: 3,
      mqttVersion: 4,
      onSuccess: subscribe
    };
    client.connect(connectOptions);
    client.onMessageArrived = onMessage;
    client.onConnectionLost = function(e) { console.log(e) };

    function subscribe() {
      client.subscribe("topic_2");
      console.log("subscribed");
    }

    function onMessage(message) {
      console.log("message received: " + message.payloadString);
      chart.push(data.next(JSON.parse(message.payloadString).mode1Process));
    }
});
  </script>
  <div id="lineChart" class="epoch" style="width: 100%; height: 100px;border:solid 1px #C0C0C0;"></div>
<script>

</script>
</body>
</html>

結果

こんな感じでリアルタイムにグラフが描画されます
AWS IoTのMQTT over WebSocketでHTMLでsubscribeしたデータをリアルタイムグラフ化する

horike37
CEO of Serverless Operations, Inc Serverless Framework Core Maintainer
https://serverless.co.jp
serverless-operations
AWSクラウド技術の豊富な知見を活かし、サーバーレスによる開発や運用の支援、コンサルティングまで行う会社です
https://serverless.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした