
暂无个人介绍
一.创建数据API本文以产品数据为示例,自定义API可以参见:创建数据分析API二.添加依赖 <dependency> <groupId>com.aliyun</groupId> <artifactId>tea-openapi</artifactId> <version>0.0.11</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>iot20180120</artifactId> <version>1.1.0</version> </dependency> <!--以下依赖为非必须项,只为下文示例代码中JSON序列化输出结果使用--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.61</version> </dependency>三.java示例condition设置参数,可以在API详情中API测试中查看,参数保持一致。一个请求参数对应一个condition。在API详情页,查看API的请求参数,您可配置指定数量的condition。本文示例代码中,该API有3个请求参数__instance_id__、entityId、statDate分别对应condition、condition1、condition2。import com.alibaba.fastjson.JSON; import com.aliyun.iot20180120.Client; import com.aliyun.iot20180120.models.*; import com.aliyun.teaopenapi.models.Config; public class JavaDemo { /** * 使用AccessKey ID和AccessKey Secret初始化账号Client * @param accessKeyId * @param accessKeySecret * @return Client * @throws Exception */ public static Client createClient(String accessKeyId, String accessKeySecret) throws Exception { Config config = new Config(); config.setAccessKeyId(accessKeyId); config.setAccessKeySecret(accessKeySecret); // 您的接入域名 config.setEndpoint("iot.cn-shanghai.aliyuncs.com"); return new Client(config); } public static void main(String[] args_) throws Exception { // 您的AccessKey ID和AccessKey Secret Client client = JavaDemo.createClient("LTAI4FyDFmKN************", "WF3onkl8cq3cTyVW8n************")); ListAnalyticsDataRequest request = new ListAnalyticsDataRequest(); // 您的API Path request.setApiPath("/iot-cn-npk1v******/system/query/hist_dev_cnt_stat"); // 您的API所在实例ID request.setIotInstanceId("iot-cn-npk1v******"); //分页参数:页号 request.setPageNum(1); //分页参数:页大小 request.setPageSize(100); List<ListAnalyticsDataRequest.ListAnalyticsDataRequestCondition> conditions = new ArrayList<>(); //您的业务相关的请求参数。Condition的配置说明,请参见下文的相关说明。 ListAnalyticsDataRequest.ListAnalyticsDataRequestCondition condition = new ListAnalyticsDataRequest .ListAnalyticsDataRequestCondition(); condition.setFieldName("__instance_id__"); condition.setOperate("="); condition.setValue("iot-public"); conditions.add(condition); ListAnalyticsDataRequest.ListAnalyticsDataRequestCondition condition1 = new ListAnalyticsDataRequest .ListAnalyticsDataRequestCondition(); condition1.setFieldName("entityId"); condition1.setOperate("="); condition1.setValue("all"); conditions.add(condition1); ListAnalyticsDataRequest.ListAnalyticsDataRequestCondition condition2 = new ListAnalyticsDataRequest .ListAnalyticsDataRequestCondition(); condition2.setFieldName("statDate"); condition2.setOperate("="); condition2.setValue("20210221"); conditions.add(condition2); request.setCondition(conditions); ListAnalyticsDataResponse listAnalyticsDataResponse = client.listAnalyticsData(request); System.out.println(JSON.toJSONString(listAnalyticsDataResponse)); } }四.查看结果
一.创建可信实体为阿里云账号的RAM角色在RAM访问控制 - 角色 中创建角色,可信实体类型为阿里云账号。权限添加iotfull,表示可以读写物联网平台。信任权限策略中Principal中有RAM字段 "RAM": ["acs:ram::uid:root"]root表示授权的任何RAM用户、RAM角色扮演需要单个RAM用户可以扮演:"RAM": ["acs:ram::uid:user/XXX"],XXX为RAM用户名称二.RAM用户添加sts权限。RAM用户需要添加AliyunSTSAssumeRoleAccess权限,表示允许该角色切换身份。三.RAM用户切换身份在RAM用户下没有iotfull权限,切换到RAM角色身份后,依然可以操作物联网平台。
前提准备 将0.0.0.0/0添加到RDS MySQL实例的白名单,0.0.0.0/0表示允许任何设备访问RDS实例,请谨慎使用一.配置业务逻辑HTTP请求,必要节点,在Web下使用,必须要为HTTP请求。Nodejs节点,连接数据库使用HTTP返回,将为数据的返回二.配置数据库参数下载MySQL扩展库配置实例的外网、接口、数据库用户、密码、数据库名称可以动态设置参数""放入SQL语句 ?表示需要动态改变的参数 []放入参数 connection.query( 'SELECT * FROM iottest where pk = ?',[payload.addtime],function (error, results, fields)三.在Web可视化下配置业务逻辑接口
Step By Step部署表格、弹窗获取数据,进行阀值判断结果展示一.部署表格、弹窗准备3个组件,表格、弹窗、数字框。1.表格用于展示数据,可以只管查看数据。2.弹窗用于提示用户发生了特殊状况3.数据框用于打开弹窗,由于iot studio只能通过交互时间来打开弹窗,而表格没有很好的事件可以做到,所以本文以数字框作为监听器,来打开弹窗二.获取数据,进行阀值判断1.数字框通过业务逻辑来获取需要监听的数据。2.在配置数据源中,以数据过滤脚本来判断数据是否达到报警条件。返回null为了避免初次打开时跳出弹框3.配置交互事件与动作,当值改变时通知用户报警 和 恢复的通知。三.结果展示后续可以将数字框隐藏。
Step By StepAMQP客户端连接消息监听响应设备端查看结果一.AMQP客户端连接 Python3 SDK接入示例accessKeyLTAI4GFGQvKuqHJhFa******登录物联网平台控制台,将鼠标移至账号头像上,然后单击AccessKey管理,获取AccessKey ID和AccessKey Secret。说明 如果使用RAM用户,您需授予该RAM用户管理物联网平台的权限(AliyunIOTFullAccess),否则将连接失败。授权方法请参见授权RAM用户访问物联网平台。accessSecretiMS8ZhCDdfJbCMeA005sieKe******consumerGroupIdVWhGZ2QnP7kxWpeSSjt******消费组ID。登录物联网平台控制台,在对应实例的规则引擎 > 服务端订阅 > 消费组列表查看您的消费组ID。iotInstanceIdiot-***j实例ID。您可在物联网平台控制台的实例概览页面,查看当前实例的ID。若有ID值,必须传入该ID值。若无ID值,传入空值,即iotInstanceId = ""。clientId12345表示客户端ID,建议使用您的AMQP客户端所在服务器UUID、MAC地址、IP等唯一标识。长度不可超过64个字符。登录物联网平台控制台,在对应实例的规则引擎 > 服务端订阅 > 消费组列表,单击消费组对应的查看,消费组详情页将显示该参数,方便您识别区分不同的客户端。connstomp.Connection([('iot-cn-***.amqp.iothub.aliyuncs.com', 61614)])创建AMQP客户端与物联网平台的TLS连接。${YourHost}对应的AMQP接入域名信息,请参见查看实例终端节点。conn.set_sslfor_hosts=[('iot-cn-***.amqp.iothub.aliyuncs.com', 61614)], ssl_version=ssl.PROTOCOL_TLS二.消息监听 on_message方法监听frame"{cmd=MESSAGE,headers=[{'qos': '1', 'destination': '/productKey/deviceName/user/get', 'message-id': 'XXXX', 'topic': '/productKey/deviceName/user/get', 'subscription': '1', 'generateTime': '1653539187524'}],body=13}"消息整体frame.headers.get("topic")"/productKey/deviceName/user/get"消息Topicframe.body13消息内容三.响应设备端from aliyunsdkcore import client from aliyunsdkiot.request.v20180120 import PubRequest accessKeyId = 'XXXX' accessKeySecret = 'XXXX' clt = client.AcsClient(accessKeyId, accessKeySecret, 'cn-shanghai') def settest(pk,topic,message): request = PubRequest.PubRequest() request.set_accept_format('json') # 设置返回数据格式,默认为XML,此例中设置为JSON request.set_ProductKey(pk) request.set_TopicFullName(topic) # 消息发送到的Topic全名 request.set_MessageContent(message) # hello world Base64 String request.set_Qos(0) result = clt.do_action_with_exception(request) print("cc", result)四.查看结果
设置报警回调报警信息一.设置报警回调在报警规则面板,输入报警回调的URL地址二.报警信息alertNameString报警名称。alertStateString报警状态。根据实际情况返回以下三种状态中的一种:OK:正常。ALERT:报警。INSUFFICIENT_DATA:无数据。curValueString报警发生或恢复时监控项的当前值。dimensionsString发生报警的对象。示例:{userId=110803419679****, instanceId=i-8psdh7l6lphbn10l****}。expressionString报警条件。instanceNameString实例名称。metricNameString监控项名称。关于监控项名称,请参见云服务监控项。metricProjectString云服务名称。metricProject与namespace相同。关于云服务名称,请参见云服务监控项。namespaceString云服务命名空间。namespace与metricProject相同。关于云服务命名空间,请参见云服务监控项。preTriggerLevelString上一次触发报警的级别。取值:CRITICAL:严重。WARN:警告。INFO:信息。ruleIdString触发本次报警的报警规则ID。timestampString触发本次报警的时间戳。triggerLevelString本次触发报警的级别。取值:CRITICAL:严重。WARN:警告。INFO:信息。userIdString用户ID。
Step By Step站点监控一次性拨测工具一.站点监控对指定服务站点进行探测请求,可设置报警服务,监控各个运营商对服务站点的访问情况HTTP(S)对指定的URL和IP地址进行HTTP或HTTPS探测。PING对指定的URL和IP地址进行ICMP ping探测。TCP对指定的端口进行TCP探测。UDP对指定的端口进行UDP探测。DNS对指定的域名进行DNS探测。POP3对指定的URL和IP地址进行POP3探测。SMTP对指定的URL和IP地址进行SMTP探测。FTP对指定的URL和IP地址进行FTP探测。二.一次性探测工具不同探测点对服务站点的HTTP、ping探测请求,监控全国各省市运营商网络终端用户到您服务站点的访问情况
Step By Step设置生效时间设置报警黑名单两者区别一.设置生效时间 报警规则 --- 修改(创建) --- 选择生效事件二.设置报警黑名单 产品:报警黑名单策略中的指定云产品 实例:指定云产品的具体实例ID,多个实例ID之间用半角逗号(,)分隔。 指标:指定产品的监控项,可以不添加,添加仅在具体指标中生效;添加指标但没有具体选择则所有指标生效 指定生效时间范围:黑名单策略生效时间; 维度:用户指当前阿里云账号下资源,分组指应用分组下资源 三.两者区别 生效时间适用于少量修改 或 创建,且其他时间内发生的报警不会被感知到 报警黑名单适用于大量,且可以感知黑名单期间内屏蔽的报警,在报警历史中可以看到,被黑名单屏蔽了会有命中状态
Step By Step上报自定义数据自定义监控视图自定义报警服务一.上报自定义数据 调用PutCustomMetric接口上报自定义监控数据 GroupId:自定义监控分组id Time:上报时间,与当前时间不能超过相隔1小时 二.自定义监控视图 在左侧导航栏,单击Dashhoard,在大盘中添加自定义监控视图,选择需要监控的指标和维度 三.自定义监控报警服务 需要在维度下创建,其他地方创建没有自定义监控的分组 和 指标选项
Step By Step报警规则参数介绍对一些云产品进行相同的监控项配置报警规则其他功能一.报警规则介绍产品:需要监控的云产品资源范围:监控云产品的范围报警规则:监控数据阈值报警通道沉默周期、生效时间、报警联系人 : 报警信息每隔多久触发、监控时间范围、需要通知的人员报警回调:默认支持电话、短信、钉钉、邮箱报警,可以设置其他地方的公网URL接收报警信息。支持json格式,在URL后添加&ali_cms_cb_type=json无数据报警处理方式:分为不做任何处理、发送无数据报警、视为正常; 不做任何处理和视为正常: 不做任何处理(默认值):触发报警后实例开始缺失数据,则规则一直处于报警状态,直到24hour后才会恢复正常 发送无数据报警:实例若出现数据缺失则会触发无数据报警通知,恢复也会发送恢复通知 视为正常:触发报警后,若三个interval之后如果仍然无数据,且策略配置为『视为正常』,则该实例恢复正常二.对一些云产品进行相同的监控项配置报警规则 可以使用应用分组 + 报警模板,报警模板中的规则会应用到分组下对应云产品下的所有实例将需要监控的云产品添加到应用分组中创建报警模板,选择需要监控的云产品,支持多个云产品,设置报警规则将报警规则应用到分组中 三.其他功能正在报警:当资源发生报警时,可以从云产品和应用分组维度查看正在报警资源的数量、监控图表详情、报警规则详情和报警历史报警历史:当报警发生后,可以按照云产品、应用分组、报警级别、报警联系人组等查看报警历史信息
Step By Step主机安装插件功能介绍一.主机安装插件自动安装 方法1:选择主机,点击安装按钮 方法2:开启自动安装按钮,在添加主机到云监控下会自动安装插件。 手动安装 root身份登录主机,执行安装命令 查看插件状态是否正常 执行以下命令,查看插件的状态ps aux | grep argusagent | grep -v grep二.其他功能操作系统监控 和 基础监控 都是对主机的CPU、内存、磁盘、TCP连接数等监控项以图表形式展示。云盘展示当前主机下的系统盘 和 数据盘使用情况。周期是每隔固定的事件采集监控项数据。
Step By Step服务器安装Grafana软件创建指标仓库设置Grafana并添加监控指标数据监控视图一.服务器安装Grafana软件yum install https://dl.grafana.com/oss/release/grafana-8.0.6-1.x86_64.rpm启动Grafana服务 service grafana-server start二.创建指标仓库创建指标仓库接入云产品数据,选择监控数据的指标对接线下获取域名,据源对接到Grafana需要三.设置Grafana并添加监控指标数据登录Grafana,地址:http://服务器ip地址:3000; 初始账号密码:admin设置数据源,URL:指标仓库中对接线下提供的域名,user 和 password 分别为账号的AccessKeyId、AccessKey Secret四.监控视图
Step By StepWeb可视化添加页面设置组件设计业务逻辑组件添加交互效果展示 一.Web可视化添加页面设置组件 本文以按钮 和 文字组件展示,将按钮的文本信息传递给另一个页面的文字组件。 分别创建两个页面,页面A 和 B;A页面放置一个按钮组件,B页面放置一个文本组件。 二.设计业务逻辑 通过HTTP请求获取到需要传递的参数,放入脚本中,通过脚本将参数值赋值给变量。HTTP参数设置入参配置添加变量,根据自己的需求设置类型通过脚本决定参数的返回 module.exports = async function(payload, node, query, context, global) { console.log("payload: ", payload); //判断入参是否为空,空则返回变量,不为空重新为变量赋值 //变量:global.变量名称 入参:payload.入参名称 if(payload.inputData == ""){ return global.data; } global.data = payload.inputData; return global.data; }三.组件添加交互 1.将按钮内容赋值给页面变量,作为后续的参数输出。 2.调用业务逻辑,将按钮内容保存到变量中 3.设置需要跳转的页面 4.文字组件同样也设置业务逻辑API,选择静态参数,值为""四.效果展示
Step By Step创建项目创建产品功能定义添加设备在线调试一.创建项目 使用生活物联网平台的第一步是创建项目,项目间数据相互隔离 二.创建产品 产品相当于一类设备的集合,同一产品下的设备具有相同的功能。每个项目中,可以新建多个产品 三.功能定义 标准功能 : 平台为每个品类提供了默认标准功能。创建产品后,功能定义页面自动显示该产品默认的标准功能 自定义功能 :根据自身设备的需求,自定义添加 四.添加设备 设备必须使用平台颁发的唯一设备证书(ProductKey、DeviceName、DeviceSecret)才能接入生活物联网平台 五.在线调试 可以在控制台模拟设备控制属性、事件、服务的变更,查看日志。
Step By Step开启设备数据同步开关配置AMQP SDK、一.开启设备数据同步开关API服务 -- 数据同步二.配置AMQP SDK导入依赖更换EndPoint、AppKey和AppSecret;consumerGroupId 与 AppKey 保持一致。<!-- amqp 1.0 qpid client --> <dependency> <groupId>org.apache.qpid</groupId> <artifactId>qpid-jms-client</artifactId> <version>0.47.0</version> </dependency> <!-- util for base64--> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> //EndPoint是连接节点,具体取值如下表所示 中国内地 :amqps://ilop.iot-amqp.cn-shanghai.aliyuncs.com:5671 新加坡 : amqps://ilop.iot-amqp.ap-southeast-1.aliyuncs.com:5671 美国(弗吉尼亚) :amqps://ilop.iot-amqp.us-east-1.aliyuncs.com:5671 德国(法兰克福) :amqps://ilop.iot-amqp.eu-central-1.aliyuncs.com:5671import java.net.URI; import java.util.Hashtable; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Destination; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.MessageProducer; import javax.jms.Session; import javax.naming.Context; import javax.naming.InitialContext; import org.apache.commons.codec.binary.Base64; import org.apache.qpid.jms.JmsConnection; import org.apache.qpid.jms.JmsConnectionListener; import org.apache.qpid.jms.message.JmsInboundMessageDispatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class AmqpJavaClientDemo { private final static Logger logger = LoggerFactory.getLogger(AmqpJavaClientDemo.class); //业务处理异步线程池,线程池参数可以根据您的业务特点调整,或者您也可以用其他异步方式处理接收到的消息。 private final static ExecutorService executorService = new ThreadPoolExecutor( Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors() * 2, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(50000)); public static void main(String[] args) throws Exception { String appKey = "${YourAppkey}"; String appSecret = "${YourAppSecret}"; String consumerGroupId = "${YourAppkey}"; long random = xxxxx; //建议使用机器UUID、MAC地址、IP等唯一标识等作为clientId。便于您区分识别不同的客户端。 String clientId = "${YourClientId}"; String userName = clientId + "|authMode=appkey" + ",signMethod=" + "SHA256" + ",random=" + random + ",appKey=" + appKey + ",groupId=" + consumerGroupId + "|"; String signContent = "random=" + random; String password = doSign(signContent, appSecret, "HmacSHA256"); String connectionUrlTemplate = "failover:(${AMQPEndPointUrl}?amqp.idleTimeout=80000)" + "?failover.maxReconnectAttempts=10&failover.reconnectDelay=30"; Hashtable<String, String> hashtable = new Hashtable<>(); hashtable.put("connectionfactory.SBCF",connectionUrlTemplate); hashtable.put("queue.QUEUE", "default"); hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory"); Context context = new InitialContext(hashtable); ConnectionFactory cf = (ConnectionFactory)context.lookup("SBCF"); Destination queue = (Destination)context.lookup("QUEUE"); // 创建连接。 Connection connection = cf.createConnection(userName, password); ((JmsConnection) connection).addConnectionListener(myJmsConnectionListener); // 创建会话。 // Session.CLIENT_ACKNOWLEDGE: 收到消息后,需要手动调用message.acknowledge()。 // Session.AUTO_ACKNOWLEDGE: SDK自动ACK(推荐)。 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); connection.start(); // 创建Receiver连接。 MessageConsumer consumer = session.createConsumer(queue); consumer.setMessageListener(messageListener); } private static MessageListener messageListener = new MessageListener() { @Override public void onMessage(Message message) { try { //1.收到消息之后一定要ACK。 // 推荐做法:创建Session选择Session.AUTO_ACKNOWLEDGE,这里会自动ACK。 // 其他做法:创建Session选择Session.CLIENT_ACKNOWLEDGE,这里一定要调message.acknowledge()来ACK。 // message.acknowledge(); //2.建议异步处理收到的消息,确保onMessage函数里没有耗时逻辑。 // 如果业务处理耗时过程过长阻塞住线程,可能会影响SDK收到消息后的正常回调。 executorService.submit(() -> processMessage(message)); } catch (Exception e) { logger.error("submit task occurs exception ", e); } } }; /** * 在这里处理您收到消息后的具体业务逻辑。 */ private static void processMessage(Message message) { try { byte[] body = message.getBody(byte[].class); String content = new String(body); String topic = message.getStringProperty("topic"); String messageId = message.getStringProperty("messageId"); logger.info("receive message" + ", topic = " + topic + ", messageId = " + messageId + ", content = " + content); } catch (Exception e) { logger.error("processMessage occurs error ", e); } } private static JmsConnectionListener myJmsConnectionListener = new JmsConnectionListener() { /** * 连接成功建立。 */ @Override public void onConnectionEstablished(URI remoteURI) { logger.info("onConnectionEstablished, remoteUri:{}", remoteURI); } /** * 尝试过最大重试次数之后,最终连接失败。 */ @Override public void onConnectionFailure(Throwable error) { logger.error("onConnectionFailure, {}", error.getMessage()); } /** * 连接中断。 */ @Override public void onConnectionInterrupted(URI remoteURI) { logger.info("onConnectionInterrupted, remoteUri:{}", remoteURI); } /** * 连接中断后又自动重连上。 */ @Override public void onConnectionRestored(URI remoteURI) { logger.info("onConnectionRestored, remoteUri:{}", remoteURI); } @Override public void onInboundMessage(JmsInboundMessageDispatch envelope) {} @Override public void onSessionClosed(Session session, Throwable cause) {} @Override public void onConsumerClosed(MessageConsumer consumer, Throwable cause) {} @Override public void onProducerClosed(MessageProducer producer, Throwable cause) {} }; /** * 计算签名,password组装方法,请参见AMQP客户端接入说明文档。 */ private static String doSign(String toSignString, String secret, String signMethod) throws Exception { SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), signMethod); Mac mac = Mac.getInstance(signMethod); mac.init(signingKey); byte[] rawHmac = mac.doFinal(toSignString.getBytes()); return Hex.encodeHexString(rawHmac); } }参考文档:数据AMQP推送
Step By Step 一.创建"地理位置"物模型 二.设备接入并获取token 三.发送HTTP请求一.创建"地理位置"物模型添加地理位置物模型属性,权限为读写。二.设备接入并获取token在pom.xml文件中,添加以下依赖,引入阿里fastjson包进行设备认证以获取设备token、使用获取的token进行持续地数据上报<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.68</version> </dependency>package javasdk;/* * Copyright © 2019 Alibaba. All rights reserved. */ import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.HttpsURLConnection; import com.alibaba.fastjson.JSONObject; /** * 设备使用HTTP协议接入阿里云物联网平台。 * 协议规范说明,请参见《HTTP协议规范》。 * 数据格式,请参见《HTTP连接通信》。 */ public class IotHttpClient { // 地域ID,以华东2(上海)为例。 private static String regionId = "cn-shanghai"; // 定义加密方式,MAC算法可选以下算法:HmacMD5、HmacSHA1,需和signmethod一致。 private static final String HMAC_ALGORITHM = "hmacsha1"; // token有效期7天,失效后需要重新获取。 private String token = null; /** * 初始化HTTP客户端。 * * @param productKey,产品key。 * @param deviceName,设备名称。 * @param deviceSecret,设备密钥。 */ public void conenct(String productKey, String deviceName, String deviceSecret) { try { // 注册地址。 URL url = new URL("https://iot-as-http." + regionId + ".aliyuncs.com/auth"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-type", "application/json"); conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流。 PrintWriter out = new PrintWriter(conn.getOutputStream()); // 发送请求参数。 out.print(authBody(productKey, deviceName, deviceSecret)); // flush输出流的缓冲。 out.flush(); // 获取URLConnection对象对应的输入流。 BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); // 读取URL的响应。 String result = ""; String line = ""; while ((line = in.readLine()) != null) { result += line; } System.out.println("----- auth result -----"); System.out.println(result); // 关闭输入输出流。 in.close(); out.close(); conn.disconnect(); // 获取token。 JSONObject json = JSONObject.parseObject(result); if (json.getIntValue("code") == 0) { token = json.getJSONObject("info").getString("token"); } } catch (Exception e) { e.printStackTrace(); } } private String authBody(String productKey, String deviceName, String deviceSecret) { // 构建认证请求。 JSONObject body = new JSONObject(); body.put("productKey", productKey); body.put("deviceName", deviceName); body.put("clientId", productKey + "." + deviceName); body.put("timestamp", String.valueOf(System.currentTimeMillis())); body.put("signmethod", HMAC_ALGORITHM); body.put("version", "default"); body.put("sign", sign(body, deviceSecret)); System.out.println("----- auth body -----"); System.out.println(body.toJSONString()); return body.toJSONString(); } /** * 设备端签名。 * * @param params,签名参数。 * @param deviceSecret,设备密钥。 * @return 签名十六进制字符串。 */ private String sign(JSONObject params, String deviceSecret) { // 请求参数按字典顺序排序。 Set<String> keys = getSortedKeys(params); // sign、signmethod和version除外。 keys.remove("sign"); keys.remove("signmethod"); keys.remove("version"); // 组装签名明文。 StringBuffer content = new StringBuffer(); for (String key : keys) { content.append(key); content.append(params.getString(key)); } // 计算签名。 String sign = encrypt(content.toString(), deviceSecret); System.out.println("sign content=" + content); System.out.println("sign result=" + sign); return sign; } /** * 获取JSON对象排序后的key集合。 * * @param json,需要排序的JSON对象。 * @return 排序后的key集合。 */ private Set<String> getSortedKeys(JSONObject json) { SortedMap<String, String> map = new TreeMap<String, String>(); for (String key : json.keySet()) { String vlaue = json.getString(key); map.put(key, vlaue); } return map.keySet(); } /** * 使用HMAC_ALGORITHM加密。 * * @param content,明文。 * @param secret,密钥。 * @return 密文。 */ private String encrypt(String content, String secret) { try { byte[] text = content.getBytes(StandardCharsets.UTF_8); byte[] key = secret.getBytes(StandardCharsets.UTF_8); SecretKeySpec secretKey = new SecretKeySpec(key, HMAC_ALGORITHM); Mac mac = Mac.getInstance(secretKey.getAlgorithm()); mac.init(secretKey); return byte2hex(mac.doFinal(text)); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 二进制转十六进制字符串。 * * @param b,二进制数组。 * @return 十六进制字符串。 */ private String byte2hex(byte[] b) { StringBuffer sb = new StringBuffer(); for (int n = 0; b != null && n < b.length; n++) { String stmp = Integer.toHexString(b[n] & 0XFF); if (stmp.length() == 1) { sb.append('0'); } sb.append(stmp); } return sb.toString().toUpperCase(); } public static void main(String[] args) { String productKey = ""; String deviceName = ""; String deviceSecret = ""; IotHttpClient client = new IotHttpClient(); client.conenct(productKey, deviceName, deviceSecret); } }三.发送HTTP请求本文以IPV4定位展示Topic: /sys/"+productKey+"/"+deviceName+"/_thing/service/postPayload: {"id":"123","version":"1.0","params":{"identifier":"Location.Position","serviceParams":{"type":"ip","ip":"10.1.1.1"}},"method":"_thing.service.post"} /** * 发送消息。 * * @param topic,发送消息的Topic。 * @param payload,消息内容。 */ public void publish(String topic, byte[] payload) { try { // 注册地址。 URL url = new URL("https://iot-as-http." + regionId + ".aliyuncs.com/topic" + topic); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-type", "application/octet-stream"); conn.setRequestProperty("password", token); conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流。 BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream()); out.write(payload); out.flush(); // 获取URLConnection对象对应的输入流。 BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); // 读取URL的响应。 String result = ""; String line = ""; while ((line = in.readLine()) != null) { result += line; } System.out.println("----- publish result -----"); System.out.println(result); // 关闭输入输出流。 in.close(); out.close(); conn.disconnect(); } catch (Exception e) { e.printStackTrace(); } }参考文档HTTP定位HTTPS连接通讯
Step By StepOpenAPI云端SDK一.OpenAPI二.云端SDK(本文以Java为例)1.添加pom依赖<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-iot --> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-iot</artifactId> <version>7.31.0</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.5.6</version> </dependency>2.发起调用String accessKey = "${accessKey}"; String accessSecret = "${accessSecret}"; IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKey, accessSecret); DefaultAcsClient client = new DefaultAcsClient(profile); PubRequest request = new PubRequest(); request.setIotInstanceId("${iotInstanceId}"); request.setProductKey("${productKey}"); request.setMessageContent(Base64.encodeBase64String("hello world".getBytes())); request.setTopicFullName("/${productKey}/${deviceName}/user/get"); request.setQos(0); //目前支持QoS0和QoS1。 try { PubResponse response = client.getAcsResponse(request); System.out.println(response.getSuccess()); System.out.println(response.getCode()); System.out.println(response.getErrorMessage()); } catch (ServerException e) { e.printStackTrace(); } catch (ClientException e) { System.out.println("ErrCode:" + e.getErrCode()); System.out.println("ErrMsg:" + e.getErrMsg()); e.printStackTrace(); }
Step By Step 一.构建业务逻辑 二.构建数据源 三.配置数据源并查看结果一.构建业务逻辑输入名称,选择对应的项目。这里做个简单的示例,直接将组件要求的数据格式通过脚本返回。二.构建数据源闪烁告警组件数据源。"档"分别对应不同的速度,value对应数字,决定是几档控制组件数据源,本文以下拉框为示例//闪烁告警组件数据源 { "enums": [ [ 1, "一档" ], [ 2, "二挡" ], [ 3, "三挡" ], [ 4, "四挡" ], [ 5, "五档" ] ], "value": 1 }//下拉框数据源 [ { "label": "慢", "value": 1 }, { "label": "中", "value": 2 }, { "label": "快", "value": 3 }, { "label": "极快", "value": 4 } ]三.配置数据源并查看结果
业务逻辑中提供了"设备"节点,除了可以查询、下发设备物模型,也可以查询到设备的基本信息。例如产品下的设备总数、当前设备状态、iotId等信息。本文将以获取设备的在线状态、产品下的设备总数、产品下设备在线 和 离线数量,了解下如何灵活使用该节点。Step By Step创建业务逻辑构建完整的链路以示例的方式展示如何使用查询设备基本信息一.创建业务逻辑确保实例 和 选择的项目正确无误。创建好后业务逻辑将无法变更为其他实例与项目下。二.构建完整的链路一个链路必须要包含触发 和 输出节点。需要在Web中调用业务逻辑,触发节点必须是HTTP请求。三.示例演示产品下设备总数 和 当前设备的在线状态。 如图所示:设备节点获取物的数量,获取到一些信息。其中 data 是产品下设备总数;statusCode 是当前设备的状态码,1表示在线,其他表示离线。产品下设备在线 和 离线数量。可以使用NodeJS脚本调用云端提供的API来获取,本文以QueryDevice为例,具体如下。 获取到结果后,通过脚本统计ONLINE 和 OFFLINE 的数量。
使用限制:企业版实例:仅可使用新版的物联网数据分析功能。详细内容,请参见本产品文档。公共实例:新老用户均可通过购买数据型实例,使用新版的数据分析功能前提介绍:创建的产品、设备、功能定义中的属性时,会自动再数据分析中创建,无需手动创建,以"原始"标签代表iot studio中创建和项目 和 关联的产品设备,会作为指标中的子实体数据。一. 导入物模型原子词 和 新建指标二. 创建数据分析API接口一. 导入物模型原子词 和 新建指标导入物模型原子词,需要将指标类型改为全部,作为后续指标中创建的选择,方便辨别是哪个属性下的数据。 2.新建指标需要是设备地域下分组,否做iot studio无法检测到API。右边的两个选项分别为:iot studio项目 和 项目关联的产品。比较关键的地方,选择计算方式 和 指标计算方式:用于决定数据的结果指标:这里是原始指标,用于决定计算哪个属性例子:最近一天的温度、计算方法最大值 和 温度指标,返回的数据就是 最近一天内的最大值温度。二. 创建数据分析API接口之前的配置都是在指标的基础上,所以API中以指标作为数据来源。在返回参数中选择好上面创建好的指标,测试发布就可以使用了。
一.添加设备数据源二.配置设备数据并发布为API三.如何在iot studio中使用数据分析API作为组件的数据源一.添加设备数据源二.配置设备数据并发布为API可以选择可视化分析 和 SQL分析,本文已SQL分析为例子选择需要查询的设备数据,点击左下方SQL生成语句,也可以自己编写SQL语句,点击运行按钮查看结果。 3.进入测试页面,再次检查返回内容 4.进入配置页面,为返回的字段配置对应的数据类型,可添加示例值和描述。 5.以上就已经配置完成了,点击发布按钮,就可以作为API供其他地方调用。三.在iot studio中使用数据分析API 1.进入项目管理界面,在数据资产处点击关联按钮,寻找发布的数据分析API并与项目关联 2.这里以表格组件为例子,配置数据源 3.数据源配置中,选择接口 - 数据分析服务,并选择关联好的数据分析API 4.配置好后就可以看到返回的设备数据了
准备工作:两个设备:发送设备A、接收设备B两个Topic:设备A发布权限的Topic(源Topic)、设备B订阅权限Topic(目的Topic)一.基于Topic消息路由器的M2M设备间通讯调用云端API:CreateTopicRouteTable ,创建设备A 与 设备B之间的消息路由关系。由设备A向设备B发送消息二.基于规则引擎的M2M设备间通讯创建规则引擎 - 云产品流转规则由设备A向设备B发送消息一.基于Topic消息路由器的M2M设备间通讯调用云端API:CreateTopicRouteTable ,创建设备A 与 设备B之间的消息路由关系SrcTopic :源TopicDstTopic.N :目的Topci,可以有多个 2.本文使用控制台的设备模拟器(设备A) 和 mqtt.fx(设备B) 模拟M2M流程。二.基于规则引擎的M2M设备间通讯创建云产品流转规则数据源选择源Topic数据目的选择发送到另一个Topic解析器脚本输入目的TopicwriteIotTopic(数据目的ID, 目的Topic, 需要转发的数据)模拟设备发送
链路下载扩展库mysql并选择数据库使用填写数据库信息 和 需要操作的SQL语句。如何调用节点变量一. 下载扩展库mysql并选择数据库使用二. 在mysql.createConnection中填写数据库信息,在connection.query中填写SQL语句 动态参数示例(? = 节点变量): connection.query( 'SELECT * FROM 表名 where 字段= ?',[节点变量],function (error, results, fields){} 三. 可使用平台已内置的以下节点变量,调用需要的数据数据: {"id":"160865432","method":"thing.event.property.post","params":{"LightSwitch":1},"version":"1.0"}"params":{"LightSwitch":1} --------->key为params1.payload : 上个节点的输出。获取上个节点数据中某个字段数据: payload.上个节点的输出中的某个keypayload.params ==== {"LightSwitch":1}2.query:触发节点的输入query.params ==== {"LightSwitch":1}3.node : 指定节点下的输出node.节点ID.params ==== {"LightSwitch":1}
注意事项:调用过程中出现 “TIMEOUT”,超时的现象,是因为RRPC作为同步调用,设备端在接收收到RRPC请求之后,需要根据RRPC请求Topic的格式,返回响应消息到对应的响应Topic调用该接口后,如果设备端未在5秒内做出反馈,即使设备收到了消息,云端也视消息为发送失败RRpc请求Topic的messageId 与 RRpc响应Topic的MessageId必须一致,否则也将作为超时。链路: 1.调用云端API RRpc,向指定设备发送请求消息。 RRpc请求Topic:/sys/${yourProductKey}/${yourDevieName}/rrpc/request/${messageId} 2.设置设备端响应 RRpc响应Topic:/sys/${yourProductKey}/${yourDevieName}/rrpc/response/${messageId} 3.查看结果一. 调用云端API RRpc,向指定设备发送请求消息 二. 设置设备端响应 messageId需保持一致 java SDK示例: publish方法是:自定义MQTT Topic 通讯 的发布 //判断是否是RRpc消息 if (topic.contains("rrpc")) { String respTopic = topic.replace("request", "response"); //publish(String topic, String payload, int qos) publish(respTopic, "RRpc同步调用", 1); }三. 查看结果
链路:调用云端API设备端监听并响应查看结果云端API SetDeviceProperty示例 :一.OpenAPi 调用 云端API SetDeviceProperty ,将物模型属性更新请求信息发送到设备端二. 设备端接收到请求信息方法一 : 物模型开发Node.js SDK示例: device.onProps方法监听云端设置属性服务消息,并调用device.postProps响应物模型属性更新。 // 监听云端设置属性服务消息 device.onProps((cmd)=>{ console.log("接收到消息--------->\n",cmd); // 物模型属性上报 device.postProps(cmd.params); })python SDK示例:SDK只需对on_thing_prop_changed进行响应处理,其他根据官方文档操作即可。需要从云端控制台下载物模型文件,该文件需要集成到应用工程中,这样对应的topic才能正确的接收和发送消息服务端发送设置属性消息后,SDK通过设置的回调函数on_thing_prop_changed通知用户,回调函数中params为包含属性名与值的字典对象,用户需要对接收到的新属性进行处理通过thing_post_property上报属性设备端的响应结果SDK通过on_thing_prop_post 通知用户 def on_thing_prop_changed(self, params, userdata): print("接收到物模型属性更新消息_on_thing_prop_changed" + str(params)) prop_data = params # 设备端响应 rc, request_id = self.__linkkit.thing_post_property(prop_data)方法二 : 自定义MQTT Topic通讯Node.js SDK示例: device.on方法监听云端设置属性服务消息,并调用device.publish以发布物模型属性数据消息方式响应物模型属性更新。// 监听message事件 device.on('message', (topic, payload) => { console.log("监听消息topic----->",topic); console.log("监听消息payload--------->",payload.toString()); //判断是否是云端设置属性服务消息 if (topic.indexOf("property/set") != -1) { var replace_payload = payload.toString().replace("thing.service.property.set","thing.event.property.post"); console.log("响应物模型更新--------->"); device.publish('/sys/yourProductKey/yourDeviceName/thing/event/property/post', replace_payload); } }); Android SDK:通过IConnectNotifyListener监听服务端物模型属性更新请求调用MqttPublishRequest处理设备端响应设备端响应结果也是通过IConnectNotifyListener告知用户,需要订阅/sys/yourProductKey/yourDeviceName/thing/event/property/post_reply/* * SET:/sys/yourProductKey/yourDeviceName/thing/service/property/set * POST:/sys/yourProductKey/yourDeviceName/thing/event/property/post * */ if (topic.equals(SET)) { Log.i("TAG","设备端响应"); String replace_payload = new String((byte[]) aMessage.data).replace("thing.service.property.set", "thing.event.property.post"); CustomTopic.getPublish(POST, replace_payload, 1); }三. 查看结果控制台日志服务 : 物模型check状态码200 2.设备物模型数据是否更新
2022年09月
2022年08月
2022年07月
2022年06月
2022年05月
2022年04月
2022年03月
2022年02月
2022年01月
2021年12月