天天看點

阿裡雲物聯網平台IoT Studio調用人臉識别服務示例

概述

目前IoT Studio服務開發子產品提供了雲市場人臉識别API的調用子產品,但是還沒有直接調用阿裡雲人臉識别API的方法,本文從裝置端開始上傳圖檔到oss服務,然後通過上行消息傳遞圖檔URL,使用NodeJS節點進行阿裡雲人臉識别服務的調用,将調用的結果通過雲資料庫MySQL進行存儲。

Step By Step

一、裝置端開發

1、pom.xml

<dependencies>
        <dependency>
            <groupId>org.eclipse.paho</groupId>
            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
            <version>1.1.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.8.0</version>
        </dependency>
    </dependencies>           

2、Device Code Sample

import com.alibaba.taro.AliyunIoTSignUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class FaceDemoUpload {

    public static String productKey = "a1o9N******";
    public static String deviceName = "d******";
    public static String deviceSecret = "7Ukl6Ka80nIEXhUwCmw7XrUC********";
    public static String regionId = "cn-shanghai";

    // 物模型-屬性上報topic
    private static String pubTopic = "/sys/" + productKey + "/" + deviceName + "/thing/event/property/post";
    // 自定義topic,在産品Topic清單位置定義
    private static String subTopic = "/sys/" + productKey + "/" + deviceName + "/thing/event/property/post_reply";

    private static MqttClient mqttClient;

    public static void main(String[] args) {

        initAliyunIoTClient();
        ScheduledExecutorService scheduledThreadPool = new ScheduledThreadPoolExecutor(1,
                new ThreadFactoryBuilder().setNameFormat("thread-runner-%d").build());

        scheduledThreadPool.scheduleAtFixedRate(() -> postDeviceProperties(), 10, 5, TimeUnit.SECONDS);

        try {
            mqttClient.subscribe(subTopic); // 訂閱Topic
        } catch (MqttException e) {
            System.out.println("error:" + e.getMessage());
            e.printStackTrace();
        }

        // 設定訂閱監聽
        mqttClient.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable throwable) {
                System.out.println("connection Lost");

            }

            @Override
            public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
                System.out.println("Sub message");
                System.out.println("Topic : " + s);
                System.out.println(new String(mqttMessage.getPayload())); //列印輸出消息payLoad
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

            }
        });

    }

    /**
     * 初始化 Client 對象
     */
    private static void initAliyunIoTClient() {

        try {
            // 構造連接配接需要的參數
            String clientId = "java" + System.currentTimeMillis();
            Map<String, String> params = new HashMap<>(16);
            params.put("productKey", productKey);
            params.put("deviceName", deviceName);
            params.put("clientId", clientId);
            String timestamp = String.valueOf(System.currentTimeMillis());
            params.put("timestamp", timestamp);
            // cn-shanghai
            String targetServer = "tcp://" + productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883";

            String mqttclientId = clientId + "|securemode=3,signmethod=hmacsha1,timestamp=" + timestamp + "|";
            String mqttUsername = deviceName + "&" + productKey;
            String mqttPassword = AliyunIoTSignUtil.sign(params, deviceSecret, "hmacsha1");

            connectMqtt(targetServer, mqttclientId, mqttUsername, mqttPassword);

        } catch (Exception e) {
            System.out.println("initAliyunIoTClient error " + e.getMessage());
        }
    }

    public static void connectMqtt(String url, String clientId, String mqttUsername, String mqttPassword) throws Exception {

        MemoryPersistence persistence = new MemoryPersistence();
        mqttClient = new MqttClient(url, clientId, persistence);
        MqttConnectOptions connOpts = new MqttConnectOptions();
        // MQTT 3.1.1
        connOpts.setMqttVersion(4);
        connOpts.setAutomaticReconnect(false);
        connOpts.setConnectionTimeout(10);
//        connOpts.setCleanSession(true);
        connOpts.setCleanSession(false);

        connOpts.setUserName(mqttUsername);
        connOpts.setPassword(mqttPassword.toCharArray());
        connOpts.setKeepAliveInterval(60);

        mqttClient.connect(connOpts);
    }

    /**
     * 彙報屬性
     */
    private static void postDeviceProperties() {

        try {
            //上報資料
            //進階版 物模型-屬性上報payload
            System.out.println("上報屬性值");

            //上傳本地圖檔
            // Request body  C:\Users\Administrator\Desktop\timg.jpg
            String pic_path = "C:\\Users\\Administrator\\Desktop\\timg.jpg";//本地圖檔的路徑

            String picURL = uploadPicToOss(pic_path);

            String payloadJson = "{\"params\":{\"textdata\":\"" + picURL + "\"}}";
            MqttMessage message = new MqttMessage(payloadJson.getBytes("utf-8"));
            message.setQos(1);
            mqttClient.publish(pubTopic, message);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }


    public static String uploadPicToOss(String filePath) {
        // Endpoint以上海為例,其它Region請按實際情況填寫。
        String endpoint = "http://oss-cn-shanghai.aliyuncs.com";
        String bucketName = "taro******";  // bucket名稱
        String key = "pic/timg.jpg";   // 檔案路徑及名稱
        // 阿裡雲主賬号AccessKey擁有所有API的通路權限,風險很高。強烈建議您建立并使用RAM賬号進行API通路或日常運維,請登入 https://ram.console.aliyun.com 建立RAM賬号。
        String accessKeyId = "LTAIOZZg********";
        String accessKeySecret = "v7CjUJCMk7j9aKduMA************";

        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 建立PutObjectRequest對象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, new File(filePath));

        // 如果需要上傳時設定存儲類型與通路權限,請參考以下示例代碼。
        ObjectMetadata metadata = new ObjectMetadata();

        // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        metadata.setObjectAcl(CannedAccessControlList.PublicRead);
        putObjectRequest.setMetadata(metadata);

        // 上傳檔案。
        ossClient.putObject(putObjectRequest);

        // 關閉OSSClient。
        ossClient.shutdown();

        return "https://" + bucketName + ".oss-cn-shanghai.aliyuncs.com/" + key; // 傳回圖檔在OSS中公網可以直接通路的URL
    }
}           
參考連結: 基于開源JAVA MQTT Client連接配接阿裡雲IoT

二、服務開發子產品搭建

1、裝置觸發

阿裡雲物聯網平台IoT Studio調用人臉識别服務示例

2、Node.js 腳本

阿裡雲物聯網平台IoT Studio調用人臉識别服務示例
/**
* @param {Object} payload 上一節點的輸出
* @param {Object} node 指定某個節點的輸出
* @param {Object} query 服務流第一個節點的輸出
* @param {Object} context  { appKey, appSecret }
*/

module.exports = async function (payload, node, query, context) {

  const Core = require('@alicloud/pop-core');

  var client = new Core({
    accessKeyId: 'LTAIOZZg********',
    accessKeySecret: 'v7CjUJCMk7j9aKduMA************',
    endpoint: 'https://face.cn-shanghai.aliyuncs.com',
    apiVersion: '2018-12-03'
  });

  var params = {
    "ImageUrl": query.props.textdata.value
  }

  var requestOption = {
    method: 'POST'
  };

    var result = await client.request('GetFaceAttribute', params, requestOption);
    return result;
}           
阿裡雲新版人臉識别 NODEJS 使用示例教程

三、雲資料庫MySQL

阿裡雲物聯網平台IoT Studio調用人臉識别服務示例
資料庫建表語句:
/*------- CREATE SQL---------*/
CREATE TABLE `iotface1` (
  `face_num` INT DEFAULT NULL,
  `gender` INT DEFAULT NULL,
  `glass` INT DEFAULT NULL,
  `expression` INT DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8           
IoT Studio服務開發MySQL資料流轉示例Demo

部署運作

阿裡雲物聯網平台IoT Studio調用人臉識别服務示例

四、運作測試

1、裝置端日志

阿裡雲物聯網平台IoT Studio調用人臉識别服務示例

2、節點日志

阿裡雲物聯網平台IoT Studio調用人臉識别服務示例

3、資料庫輸入插入查詢

阿裡雲物聯網平台IoT Studio調用人臉識别服務示例

參考連結

阿裡雲物聯網平台部落格綜述 阿裡雲新版人臉識别綜述