如何用Link Develop开发一个智能厕所

简介: 由于阿里云悬殊的男女比例,以及厕所占地面积的限制,各位男同胞每天都要在特殊味道的包围下等待有限的坑位。我们在想能不能利用物联网技术做一个低成本的解决方案,让男同胞们不需要亲自去现场的情况下也能得知坑位的空余情况(像停车场一样),基于我们IoT事业部的一站式开发平台——Link Develop,做一个IoT的智能厕所。

概述

由于阿里云悬殊的男女比例,以及厕所占地面积的限制,各位男同胞每天都要在特殊味道的包围下等待有限的坑位。我们在想能不能利用物联网技术做一个低成本的解决方案,让男同胞们不需要亲自去现场的情况下也能得知坑位的空余情况(像停车场一样),基于我们IoT事业部的一站式开发平台——Link Develop,做一个IoT的智能厕所。

技术架构

undefined

前期准备

硬件

NodeMCU x9,PIR传感器 x9,1800mAh LiPo电池 x9,防水盒子 x9,usb mini 连接线 x1

软件

Arduino IDE

平台

阿里云账号,Link Develop平台权限开通

具体实施

建立设备模型

设备模型可以理解为一个类,或者一个模板。它规定了某种设备下的共有属性,并且允许你批量实例化设备。
undefined
undefined

进入Link Develop平台,跟其他云产品一样,需要先完成基本的入驻信息填写。
入驻流程02.gif

接下来我们会进入到一个项目空页面,我们需要在页面顶部点击“新建设备模型”。打开设备模型弹窗,输入名称以及定义类别,这里我们选择“自定义类型”即可。然后进入到设备模型的详情页之后,添加标准功能——输入红外——选择红外检测状态。我们就完成了一个可以上报红外检测数据的设备模型了。这个模型已经满足我们的需求。
设备模型1.gif

然后我们需要实例化我们的厕所监控设备,在设备模型详情页里点击“测试设备”tab。然后依次创建9个不同设备名称(deviceName)的测试设备。每个设备建立完成后都有一个ProductKey,DeviceName和DeviceSecret,我们简称为“三元组”,接下来我们还会用到这个。
测试设备1.gif

做完这些步骤之后,设备模型的建立与实例化就OK了。接下来我们进入Arduino代码编写。

硬件开发

PIR只有三个口,分别是VCC,GND和输出口。接线方法如下(NodeMCU的D7相当于arduino里的Pin 13)
undefined

然后接上usb线。打开arduino IDE。复制以下代码:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

#define SENSOR_PIN    13


/* 连接您的WIFI SSID和密码,这个9个设备可以一致 */
#define WIFI_SSID         "yourssid"
#define WIFI_PASSWD       "yourwifipassword"


/* 产品的三元组信息,根据9个测试设备的三元组,每个设备都烧录不同的*/
#define PRODUCT_KEY       "yourproductKey"
#define DEVICE_NAME       "yourdeviceName"
#define DEVICE_SECRET     "yourdeviceSecret"

/* LD线上环境域名和端口号,不需要改 */
#define MQTT_SERVER       PRODUCT_KEY".iot-as-mqtt.cn-shanghai.aliyuncs.com"
#define MQTT_PORT         1883
#define MQTT_USRNAME      DEVICE_NAME "&" PRODUCT_KEY

// TODO: MQTT连接的签名信息,哈希加密请以"clientIdtestdeviceName"+设备名称+"productKey"+设备模型标识+“timestamp123456789”前往http://tool.oschina.net/encrypt?type=2进行加密
// HMACSHA1_SRC  clientIdtestdeviceNamehuman04productKeya1rezUVs103timestamp123456789
#define CLIENT_ID         "test|securemode=3,timestamp=123456789,signmethod=hmacsha1|"
#define MQTT_PASSWD       "e0748281f8db36e12cac478801318f95ae821ba7"

#define ALINK_BODY_FORMAT         "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST     "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
#define ALINK_TOPIC_PROP_POSTRSP  "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply"
#define ALINK_TOPIC_PROP_SET      "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"
#define ALINK_METHOD_PROP_POST    "thing.event.property.post"



unsigned long lastMs = 0;

WiFiClient    espClient;
PubSubClient  client(espClient);


void callback(char *topic, byte *payload, unsigned int length)
{
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    payload[length] = '\0';
    Serial.println((char *)payload);
    
    if (strstr(topic, ALINK_TOPIC_PROP_SET))
    {
        StaticJsonBuffer<100> jsonBuffer;
        JsonObject& root = jsonBuffer.parseObject(payload);
        if (!root.success())
        {
            Serial.println("parseObject() failed");
            return ;
        }


    }
}


void wifiInit()
{
    WiFi.mode(WIFI_STA);
    WiFi.begin(WIFI_SSID, WIFI_PASSWD);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(1000);
        Serial.println("WiFi not Connect");
    }
  
    Serial.println("Connected to AP");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    
    client.setServer(MQTT_SERVER, MQTT_PORT);   /* 连接WiFi之后,连接MQTT服务器 */
    client.setCallback(callback);
}


void mqttCheckConnect()
{
    while (!client.connected())
    {
        Serial.println("Connecting to MQTT Server ...");
        if (client.connect(CLIENT_ID, MQTT_USRNAME, MQTT_PASSWD))
      
        {
            
            Serial.println("MQTT Connected!");
            // client.subscribe(ALINK_TOPIC_PROP_POSTRSP);
            client.subscribe(ALINK_TOPIC_PROP_SET);
            Serial.println("subscribe done");
        }
        else
        {
            Serial.print("MQTT Connect err:");
            Serial.println(client.state());
            delay(5000);
        }
    }
}


void mqttIntervalPost()
{
    char param[32];
    char jsonBuf[128];
    
    sprintf(param, "{\"MotionAlarmState\":%d}", digitalRead(13));
    sprintf(jsonBuf, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
    Serial.println(jsonBuf);
    client.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
}


void setup() 
{

    pinMode(SENSOR_PIN,  INPUT);
    /* initialize serial for debugging */
    Serial.begin(115200);
    Serial.println("Demo Start");

    wifiInit();
}

     
// the loop function runs over and over again forever
void loop()
{
    if (millis() - lastMs >= 5000)
    {
        lastMs = millis();
        mqttCheckConnect(); 
    
        /* 上报 */
        mqttIntervalPost();
    }
    
    client.loop();
    if (digitalRead(SENSOR_PIN) == HIGH){
    Serial.println("Motion detected!");
    delay(2000);
      }
    else {
    Serial.println("Motion absent!");
    delay(2000);
  }
  
}

这里有几段代码需要解释一下:

引用库

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

如果之前没有使用过arduino,这些库不是arduino自带的,需要去import一下。以ArduinoJson为例,具体操作方法见下图:
arduino01.gif

修改WiFi

#define WIFI_SSID         "yourssid"
#define WIFI_PASSWD       "yourwifipassword"

这里要输入你家的wifi SSID(即wifi名称)和密码。如下图红框内wifi,SSID即“TOM”(注意大小写),密码是“123456”
undefined

修改三元组

/* 产品的三元组信息,根据9个测试设备的三元组,每个设备都烧录不同的*/
#define PRODUCT_KEY       "yourproductKey"
#define DEVICE_NAME       "yourdeviceName"
#define DEVICE_SECRET     "yourdeviceSecret"

这里就是之前说的三元组,把不同设备的对应三元组填入即可。
undefined

修改HashMAC密钥

// TODO: MQTT连接的签名信息,哈希加密请以"clientIdtestdeviceName"+设备名称+"productKey"+设备模型标识+“timestamp123456789”前往http://tool.oschina.net/encrypt?type=2进行加密
// HMACSHA1_SRC  clientIdtestdeviceNamehuman04productKeya1rezUVs103timestamp123456789
#define CLIENT_ID         "test|securemode=3,timestamp=123456789,signmethod=hmacsha1|"
#define MQTT_PASSWD       "e0748281f8db36e12cac478801318f95ae821ba7"

Link Develop平台为了保证安全性,设备上传数据的时候需要验证身份。因此需要为每个设备配置不同的Hmac值。方法是先组合一段字段:
"clientIdtestdeviceName"+设备名称+"productKey"+设备模型标识+“timestamp123456789”
例如刚才截图的三元组,字段是
clientIdtestdeviceNamehuman01productKeya1rezUVs103timestamp123456789
写完这个字段之后,前往这里进行加密。选择HmacSHA1方法,以上面的字段为明文,deviceSecret为密钥。见下图:
hmac加密.gif

可以得到如下的密文:
e30657f36e7ded9a2781bba97b0dee79e8fa31b6
然后替换掉MQTT_PASSWD原来的字段即可。

完成代码编译之后,选择好对应的开发板和烧录线即可进行上传。通电之后可以查看串口以及Link Develop上的测试设备列表看看有否成功上线。
undefined
undefined

应用开发

点击左侧栏的Web应用开发,选择“可视化应用”并输入名称。然后就进入可视化开发Web应用的工作台了。
测试应用1.gif

然后我们需要文字组件用来表示标题等。需要指示灯用来表示当前坑位有没有人的状态。
厕所面板1.gif

接下来以坑位1为例举例如何将组件绑定设备。点击右侧面板的“数据”,选择关联设备。这里会显示出所有已经创建的测试设备。选择对应坑位的传感器,之后选择展示的数据(布尔型的红外监测状态)。这样就完成了绑定数据了。
厕所面板2.gif

可以通过模拟上线看看是否成功关联。另外有一些个性化的样式也可以自己配置。
模拟上线.gif

接下来就是发挥创造力的时候了。可以上传各种背景图,加各种小样式,做成如图的看板。最后点击右上角预览即可。
模拟上线2.gif

这样就完成了一个看板了!不用忍气吞声,直接查看厕所有没有空余坑位!
钉钉推送的教程后续会跟进同步~

部署

这是实体装机的盒子。为了更好的用户体验,我们在盒子上加了一个字条“只检测有人,没有摄像头”,以免用户产生隐私方面的担忧。
undefined
undefined

部署的时候用了树莓派+显示屏。
undefined

造福90%飞天园区一号楼四楼员工的智能厕所解决方案,完成!

欢迎使用Link Develop

Link Develop(物联网开发平台)是阿里云针对物联网领域提供的端到端一站式开发服务平台,可覆盖各个物联网行业应用场景,主要解决物联网开发领域开发链路长、技术栈复杂、协同成本高、方案移植困难的问题,提供了从硬件开发、服务编排、Web应用开发到移动APP开发全链路的开发流程、框架/引擎和调试工具,并可将成熟的开发产出物对接阿里云云市场进行售卖,为开发者实现商业收益。
这篇文章的两个作者,一位是学法律出身的运营同学,一位是学设计出身的UED同学,两位都不是专业的工程师,却能在短短一天之内基于Link Develop完成整个智能厕所的解决方案搭建。相信大家认识到了Link Develop平台的开发能力之后,会有更多更新奇的idea出现,并且借助Link Develop快速实现物联网应用开发!
欢迎访问:https://linkdevelop.aliyun.com

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
目录
相关文章
|
6月前
|
消息中间件 缓存 数据库
惊艳!Alibaba最新发布「10亿级并发系统设计文档」Git狂揽8000星
前言 每逢阿里开展大型活动,比如、双11、双12、等等,使用淘宝的用户就会瞬间飙升,为何淘宝APP从来没有崩盘?淘宝的亿级并发系统架构又是如何设计的呢?又是如何承受住亿级流量带来的并发量呢? 这份阿里最新发布的10亿并发系统设计手册希望对有困惑的小伙伴带来答案,对想在技术上得到突破的小伙伴带来福利~ 由六个部分,基础篇、数据库篇、缓存篇、消息队列篇、分布式服务篇、维护篇、实战篇共计328页 总览目录 由于文章幅篇的限制小编就用截图的方式给大家展示需要获取完整版的小伙伴点击此处​ 基础篇 高并发代表着大流量,高并发系统设计的魅力就在于我们能够凭借自己的聪明才智设计巧妙的
179 0
|
2月前
|
Go 开发工具 git
CF+hugo部署要点随记
本文介绍了使用Hugo搭建静态博客的方法,Hugo是一款用Go语言编写的静态站点生成器。文中详细描述了在Windows环境下安装Go、Git和Hugo的步骤,并提供了快速启动指南。此外,还介绍了如何通过Git子模块引入主题,以及如何在本地创建和编辑文章。最后,给出了常用Markdown语法示例,帮助用户轻松撰写博客内容。
68 5
|
4月前
|
数据库连接 数据库 Python
惊!Python 上下文管理器竟能如此 DIY,你的代码管理从此焕然一新🎉
【7月更文挑战第3天】Python的上下文管理器是资源管理的关键,保证了如文件或数据库连接的适时打开和关闭,提升代码可读性和可靠性。使用`with`语句结合`__enter__`和`__exit__`方法能简洁地处理异常和资源释放,例如在文件操作中,避免了手动关闭文件的需要。这降低了出错风险,使代码更整洁。
27 0
|
6月前
|
Dubbo Java 中间件
探寻源码宝藏:介绍开源项目"source-code-hunter"
最近处于金三银四的面试黄金期,许多同学在面试中反映现在要求非常高,阅读源码几乎是必问项。然而,阅读源码时常常觉得晦涩难懂,令人头疼。今天在浏览 GitHub 时,我发现了一个名为 source-code-hunter 的宝藏项目。这个项目从源码层面深入剖析和挖掘互联网行业主流技术的底层实现原理,为广大开发者提供了便利,助其提升技术深度。目前该项目已经涵盖了 Spring 全家桶、Mybatis、Netty、Dubbo 框架,以及 Redis、Tomcat 等中间件的内容,恰好适合最近正在面试或希望提升技术深度的同学参考学习。
769 1
探寻源码宝藏:介绍开源项目"source-code-hunter"
|
数据可视化 数据挖掘 定位技术
ChatGPT神器Code Interpreter终于开放,到底怎么用?这里有一份保姆级教程(3)
ChatGPT神器Code Interpreter终于开放,到底怎么用?这里有一份保姆级教程
190 0
|
数据挖掘 API
ChatGPT神器Code Interpreter终于开放,到底怎么用?这里有一份保姆级教程(2)
ChatGPT神器Code Interpreter终于开放,到底怎么用?这里有一份保姆级教程
173 0
|
存储 算法 Linux
34 史上最棒的 Git 交互式动画模拟学习
34 史上最棒的 Git 交互式动画模拟学习
183 0
|
数据采集 缓存 前端开发
你们的 Git 分支有几个;做 JAVA 电商的公司,哪些子系统的技术含量高;请问今年找到前端工作的应届生都是什么水平|极客观点
你们的 Git 分支有几个;做 JAVA 电商的公司,哪些子系统的技术含量高;请问今年找到前端工作的应届生都是什么水平|极客观点
|
前端开发 安全 Shell
对象准备入手前端开发,我连夜给ta准备了这篇git指南之终极奥义
对象是真的,连夜码字是真的,Git指南也是真的
250 0
对象准备入手前端开发,我连夜给ta准备了这篇git指南之终极奥义
|
机器学习/深度学习 数据可视化 数据挖掘
如何开始一项可能帮助你走向人生巅峰的“业余项目”(Side Project)?
你知道什么是side project 吗? 你知道如何开始一个side project 吗?一个业余项目,不仅可以给你带去知识、技能、满足感,也可能从此改变你的职业生涯。俗话说,万事开头难,本文作者列了5条经验,帮助你快速地、有目标的进入一个side project。
1888 0