使用 Soracom Beam 和 Amazon SageMaker 预测 M5Stack 的电力需求

今天,我想分享一个在科技界掀起波澜的令人兴奋的新整合。我说的是将Amazon SageMaker与Soracom Beam集成在一起,后者是一种数据传输服务,现在与AWS Signature V4兼容。

通过Amazon SageMaker和Soracom Beam的集成,您不再需要担心在设备上管理身份验证信息和SigV4生成逻辑。这使得您的设备可以在没有aws凭证的情况下向Amazon SageMaker发送数据,并将AI功能集成到您的设备中。例如,您可以使用Amazon SageMaker端点轻松预测一些统计数据。

这篇博客将重点关注的就是后一种功能。一起,我们将仔细研究微控制器M5Stack如何与Amazon SageMaker集成。那么,让我们开始吧!

体系结构概述

我们先来看一下系统架构。
M5Stack通过Soracom Beam向Amazon SageMaker发送数据。在此步骤中,Soracom Beam将接收未使用TLS加密的HTTP流量,并将其转发给使用TLS加密的Amazon SageMaker。Soracom Beam将在对Amazon SageMaker的请求中添加SigV4身份验证头。

接下来,我将向大家展示下面的硬件架构。

M5Stack通过ENVⅢ传感器捕获湿度,温度和压力,并通过3G扩展板将数据发送到Soracom Beam。

如何设置环境

那么现在让我们来创建你的环境吧!

建立人工智能模型与Amazon SageMaker

通过配置,从蜂窝设备到Soracom Beam http://beam.soracom.io:18080/ 的HTTP流量被转发到Amazon SageMaker端点,例如https://runtime.sagemaker.us-west-2.amazonaws.com/ ,并带有AWS身份验证头。

:warning:在本例中,该模型基于2022年12月的真实数据,针对东京的天气状况进行了优化。根据你的气候环境,你的预测可能会得到较低的准确性。

配置M5 Stack

请在Arduino IDE中安装以下软件。

创建一个新的草图并将其安装在M5Stack中

#include <M5Stack.h>

//Libraries for cellular connectivity
#define TINY_GSM_MODEM_UBLOX
#include <TinyGsmClient.h>
#include <HTTPClient.h>
#include <ArduinoHttpClient.h>

//Libraries for sensor
#include "UNIT_ENV.h"

TinyGsm modem(Serial2); 
TinyGsmClient ctx(modem);

const char* beamServerAddress = "beam.soracom.io";
const int beamPort = 18080;
const String powerModelName = "sagemaker-xgboost-2023-02-28-00-54-23-394";

const char* clockServerAddress = "worldtimeapi.org";
const int clockServerPort = 80;
const String datetime_prefix = "datetime: ";
  
SHT3X sht30;
QMP6988 qmp6988;


void setup() {

  //Initialization
  M5.begin();
  M5.lcd.setTextSize(2);
  M5.Lcd.clear(BLACK);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.println("M5Stack Now Powered On");

  //Initializing the modem and configure APN
  M5.Lcd.print("Restarting Modem...");
  Serial2.begin(115200, SERIAL_8N1, 16, 17);
  modem.restart();
  M5.Lcd.println("Done.");

  M5.Lcd.print("Modem Info:");
  String modemInfo = modem.getModemInfo();
  M5.Lcd.println(modemInfo);

  M5.Lcd.print("Waiting to be registered..");
  while (!modem.waitForNetwork()) M5.Lcd.print(".");
  M5.Lcd.println("done.");

  M5.Lcd.print("Creating PDP context with APN soracom.io..");
  modem.gprsConnect("soracom.io", "sora", "sora");
  M5.Lcd.println("done.");

  M5.Lcd.print("Connecting to the network..");
  while (!modem.isNetworkConnected()) M5.Lcd.print(".");
  M5.Lcd.println("done.");

  M5.Lcd.print("My IP addr:");
  IPAddress ipaddr = modem.localIP();
  M5.Lcd.print(ipaddr);
  
  //Initializing the sensor
  Wire.begin(); 
  qmp6988.init();

  
  delay(2000);
  
}

void loop() {

  //1.Get hour
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.clear(BLACK);
  M5.Lcd.setTextColor(WHITE);
  
  String datetime = get_datetime();
  
  int currentHour = datetime.substring(11,13).toInt();  
  
  //2.Get temperature and humidity
  float tmp = 0.0; // temperature
  float hum = 0.0; // humidity
  
  if(sht30.get()==0){ 
    tmp = sht30.cTemp; 
    hum = sht30.humidity; 
  }
  M5.Lcd.printf("Hour: %d Temp: %2.1f Humi: %2.0f%%  \r\n", currentHour, tmp, hum);

  
  M5.Lcd.printf("Predicting power demand.. ");
  HttpClient client = HttpClient(ctx, beamServerAddress, beamPort);

  //3.Inference power demand for the next hour based
  String contentType = "text/csv";
  String body = String(currentHour) + ","  + String(tmp) + ","  + String(hum);
  int err = client.post("/endpoints/" + powerModelName + "/invocations", contentType, body);

  //Check if the request is succeeded
   if (err != 0) {
    M5.Lcd.println("failed.");
    return;
  }
  M5.Lcd.println("done.");

  // Read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  M5.Lcd.printf("Power Demand: ");
  M5.Lcd.println(response);
              
  delay(5000);
  
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.clear(BLACK);
  M5.Lcd.setTextColor(WHITE);
  M5.Lcd.println("Retrying now...");

}


//Get time info
String get_datetime()
{
  M5.Lcd.printf("Get current time..");

  HttpClient client = HttpClient(ctx, clockServerAddress, clockServerPort);

  int err = client.get("/api/timezone/Asia/Tokyo.txt");

  //Check if the request is succeeded
   if (err != 0) {
    M5.Lcd.println("failed.");
    return "";
  }
  
  String response = client.responseBody();

  int start = response.indexOf(datetime_prefix);
  int end = response.indexOf('\n', start);
  String datetime = response.substring(start + datetime_prefix.length(), end);
  M5.Lcd.println("done.");
  return datetime;
  
}

我将在草图中解释loop()方法中发生了什么。

WorldTimeAPI获取当前时间,并在24小时内提取小时。

使用带有温湿度空气压力传感器(SHT30+QMP6988)的ENV III单元获取温度[℃]和湿度[%]

推断下一小时的电力需求:通过Soracom Beam将小时、温度和湿度发送到亚马逊SageMaker,以预测下一小时的电力需求。请注意,通过Soracom Beam调用亚马逊SageMaker不需要aws凭据,因为Soracom Beam添加了其身份验证头。

运行

现在我们来跑吧!

你会得到如下所示的预测结果。我在2023年2月进行了测试,温度为24.2,湿度为37%,时间是下午3点,然后预测的电力需求约为2873.53 / 10000千瓦。