钉钉机器人调用函数计算实现serverless web服务:传统门禁的简单改造,懒惰癌的福音

简介: 本文通过钉钉机器人调用函数计算实现的serverless web服务,打通物联网平台,和树莓派实时通讯。实现了将原有传统的磁吸门禁,改造成可以由钉钉来控制开门的简单应用。

本文通过钉钉机器人调用函数计算实现的serverless web服务,打通物联网平台,和树莓派实时通讯。实现了将原有传统的磁吸门禁,改造成可以由钉钉来控制开门的简单应用。

场景

由于本部门拥有独立封闭的空间,在大门口配置了磁吸玻璃门,因此规定在工作期间出入需要随手关门,以保证工作环境的私密性和安全性。但前台并没有小妹,这样对于来访客人就不是特别方便,往往需要电话通知接待者到大门口来接,要么接待者向管理员要来无线遥控器来开门(tuo ku zi fang pi)。这对于我这种重度懒惰病患者来说,简直是种折磨。So...

思路

是否可以由树莓派模拟按动无线门禁遥控器的按钮来开门?
经过对无线遥控器的暴力拆解,发现遥控器的开门按钮是由一个有4个引脚的贴片按钮构成。经过试验,只需把这2个接口短路,就相当于按下按钮的动作。因此可以在上面接驳一个继电器,由树莓派控制继电器来实现遥控器的按钮接通。图参考3.1节

目标: 将有经常需要接待的人(重度懒惰病患者)加入到公司某个内部钉钉群中,有来访者需要开门时,直接向群机器人发送"开门",门禁就会打开。

实现方式: 在钉钉群加入一个自定义的outgoing机器人,向机器人发送指令后,远程HTTP POST调用函数计算服务,函数计算向物联网平台的Topic上送消息,而订阅此Topic的树莓派会在收到消息后打开继电器开关,让无线遥控器的按钮短路,发送无线信号让门禁开启。

成本估算

物联网平台:
使用基础版产品免费
函数计算:
调用次数:每月前 100 万次函数调用免费。
执行时间:每月前 400000(GB*秒) 费用免费。
唯一可能产生费用的就是极少量的网络使用费

准备

物料准备

  • 树莓派
  • 一路继电器
  • 门禁无线遥控器
  • 母对母杜邦线3根
  • 公对公杜邦线2根

阿里云环境准备

  • 物联网平台
  • 函数计算
  • 日志服务(可选)

操作步骤

1 云端开发

1.1 物联网平台

登录阿里云控制台,进入物联网平台控制面板

1.1.1 新建产品

进入设备管理,创建产品,选择基础版或高级版都可以,本实例使用基础版就可以满足基本要求。

系统会自动创建3个Topic,我们需要使用 /ProductName/${deviceName}/get,作为设备订阅消息的Topic。

1.1.2 设备管理

在产品中新增设备,并获得设备的3元组,在2.3节的设备代码的编写时需要使用此3元组。设备三元组是设备的唯一标示
设备3元组

1.2 函数计算

函数计算可以通过flask web工程来实现serverless,我们可以直接使用url去访问和调用函数。好处在于,直接在函数计算里编写代码即可,而省去了购买ECS及搭建相应的运行环境,使用起来非常方便。
通过使用http触发器,函数计算可提供
http://${account-id}.${region}.fc.aliyuncs.com/2016-08-15/proxy/$(serviceName)/$(functionName)/
来访问调用函数。

1.2.1 新建服务

新建服务 iot-demo,如果需要记录和回溯函数执行的日志,则需要开通日志服务,并配置好日志仓库。

1.2.2 新建函数

新建函数,使用模版 flask-web,函数名和触发器填写 officegate,运行环境选择python2.7

1.2.3 函数代码
# -*- coding: utf-8 -*-

from flask import Flask
from flask import request
from flask import make_response
import logging
from aliyunsdkcore import client
from aliyunsdkcore.request import RpcRequest
import base64

try:
  from urllib.parse import urlparse
except:
  from urlparse import urlparse

app = Flask(__name__)

base_path = ''

return_string='''{
     "msgtype": "text",
     "text": {
         "content": "%s"
     }
 }'''

# 参数定义
options = {
    'productKey': '',  # 设备标识三元组
    'deviceName': '',  # 设备标识三元组
    'accessKeyId': '',
    'accessKeySecret': '',
    'token': '12345678',  # Dingding Outgoing token
}

clt = client.AcsClient(options['accessKeyId'], options['accessKeySecret'], 'cn-shanghai')

# 推送消息到IoT Hub Topic
def pushMsg(msg):
    request = RpcRequest('Iot', '2018-01-20', 'Pub')
    request.set_accept_format('json')
    request.add_query_param('ProductKey',options['productKey'])
    request.add_query_param('TopicFullName','/' + options['productKey'] + '/' + options['deviceName'] +'/get')  #消息发送到的Topic全名
    request.add_query_param('MessageContent',base64.b64encode(msg))  #Base64
    request.add_query_param('Qos',0)
    result = clt.do_action_with_exception(request)
    logging.info('result : ' + result)

# 健康检查
@app.route('/', methods=['GET', 'POST'])
def home():
    resp = make_response('I am ok!', 200)
    return resp

# 对应 DingDing outgoing URL
@app.route('/dingbot',methods=['POST'])
def bot_receive() :
    token=request.headers.get('token')
    data=request.get_json()
    logging.debug("token="+token+"\nmessage:"+str(data))
    msgtype=data.get("msgtype")

    if token != options['token'] and msgtype != "text" :
        return make_response("error",403)

    content=str(data["text"]["content"])
    senderId=data["senderId"]
    senderNick=data["senderNick"]
    logging.info('%s(%s) talk: %s' % (senderNick,senderId,content))
    pushMsg(content.strip())
    ret = return_string % "门开了"
    resp = make_response(ret,200)
    resp.headers['Content-Type']="application/json; charset=utf-8"
    return resp

# 函数计算主入口
def handler(environ, start_response):
    parsed_tuple = urlparse(environ['fc.request_uri'])
    li = parsed_tuple.path.split('/')
    global base_path
    if not base_path:
        base_path = "/".join(li[0:5])
    return app(environ, start_response)

代码创建完成后,在代码编辑框下方的调试Http触发器,可以获得调用的url。

注意,我们代码里路由入口是/dingbot因此,实际的访问网址应该是:
https://$(account-id).cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/iot-demo/officegate/dingbot

2 钉钉机器人的配置

如图所示,添加自定义机器人时,需要勾选中 是否开启Outgoing机制,在POST地址里,把上一节中的url粘贴进来,而Token必须和函数计算代码里参数配置的一致,本例中是12345678

添加成功后,尝试着给钉钉机器人发指令“开门”,如果机器人能回应“门开了”,那说明函数计算已经可以正常提供服务。

3 设备端开发

3.1 硬件安装

  1. 首先把门禁遥控器的外壳拆开(大卸八块)
  2. 用电烙铁把开门按钮的4个引脚从电路板上取下来
  3. 把2根公杜邦线的引脚焊接在电路板的2个焊点上,并把另一头分别接在继电器A、B端上
  4. 再拿3根母杜邦线,VCC、GND、IN分别接到树莓派GPIO接口的4、6、16引脚上。

3.2 环境准备

我们在树莓派上使用python2.7作为开发语言。安装阿里云物联网的SDK:

pip install aliyun-python-sdk-iot-client

3.3 代码开发

gate-demo.py 内容如下:

# -*- coding: utf-8 -*-

import json
from time import sleep
import RPi.GPIO as GPIO
import aliyunsdkiotclient.AliyunIotMqttClient as iot

# 参数配置
options = {
    'productKey':'', # 设备三元组
    'deviceName':'', # 设备三元组
    'deviceSecret':'', # 设备三元组
    'port':1883,
    'host':'iot-as-mqtt.cn-shanghai.aliyuncs.com',
    'gate_pin':23 #in 接GPIO 23针脚
}

# 订阅的IoT Hub Topic
SUBSCRIBE_TOPIC = '/'+options['productKey']+'/'+options['deviceName']+'/user/get'

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
# 设置GPIO接口是输出,默认低电平
GPIO.setup(options['gate_pin'],GPIO.OUT,initial=GPIO.LOW)

# 开门
def openGate() :
    GPIO.output(options['gate_pin'],GPIO.HIGH)  # 打开高电平
    sleep(0.8)
    GPIO.output(options['gate_pin'],GPIO.LOW) # 恢复低电平

# 收到发布的消息回调
def on_message(client, userdata, msg):
    print(msg.payload)
    if msg.payload=='开门':
        openGate()

def on_connect(client, userdata, flags_dict, rc):
    print("Connected with result code " + str(rc))
    # 订阅消息
    client.subscribe(topic=SUBSCRIBE_TOPIC)
    
def on_disconnect(client, userdata, flags_dict, rc):
    print("Disconnected.")
        
if __name__ == '__main__':

    # IoT 初始化
    client = iot.getAliyunIotMqttClient(options['productKey'], options['deviceName'], options['deviceSecret'], secure_mode=3)
    client.on_connect = on_connect
    client.on_message = on_message
    client.connect(host=options['productKey'] + '.' + options['host'], port=options['port'], keepalive=60)

    client.loop_forever()

4 测试运行

4.1 设备端运行

在py-demo文件夹下运行

python gate-demo.py

4.2 钉钉发送消息

在钉钉群上 @机器人,发送“开门”指令,如果函数计算运行正常,则应能收到机器人“门开了”的应答。

4.3 云端查看上送消息

在函数计算里的日志查询界面中,可以看到程序运行时记录的日志:

在物联网平台的设备的Topic列表中,可以看到收到了函数计算发布的消息:

4.4 测试结果

树莓派的python程序打印出日志,继电器的信号灯闪动,同时遥控器发出无线指令,大门磁吸门禁收到信号后开启。

后续

本例只是一个基于物联网的简单用例,并未考虑过多的安全问题。下一步可以对安全性进一步完善,例如,授权和控制谁能够进行开门等。此外,提高系统的安全性,还引入API网关,便于进行访问、流量控制等。

总结

阿里云提供的一系列产品和服务,就像拧开水龙头一样,打开即用。通过物联网平台,使用者可以快速地将原有传统硬件产品迅速地进行升级改造,实现设备迅速上云。

相关实践学习
【AI破次元壁合照】少年白马醉春风,函数计算一键部署AI绘画平台
本次实验基于阿里云函数计算产品能力开发AI绘画平台,可让您实现“破次元壁”与角色合照,为角色换背景效果,用AI绘图技术绘出属于自己的少年江湖。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
目录
相关文章
|
存储 Serverless 数据库
科普文:云计算服务类型IaaS, PaaS, SaaS, BaaS, Faas说明
本文介绍了云计算服务的几种主要类型,包括IaaS(基础设施即服务)、PaaS(平台即服务)、SaaS(软件即服务)、BaaS(后端即服务)和FaaS(函数即服务)。每种服务模式提供了不同的服务层次和功能,从基础设施的提供到应用的开发和运行,再到软件的交付使用,满足了企业和个人用户在不同场景下的需求。文章详细阐述了每种服务模式的特点、优势和缺点,并列举了相应的示例。云计算服务的发展始于21世纪初,随着互联网技术的普及,这些服务模式不断演进,为企业和个人带来了高效、灵活的解决方案。然而,使用这些服务时也需要注意服务的稳定性、数据安全性和成本等问题。
12557 5
|
10月前
|
Serverless Python
借助 serverless 将 MCP 服务部署到云端
本文介绍了如何将 MCP 服务通过 SSE 协议部署到云端,避免本地下载和启动的麻烦。首先,使用 Python 实现了一个基于 FastMCP 的网络搜索工具,并通过设置 `transport='sse'` 启用 SSE 协议。接着,编写客户端代码测试服务功能,确保其正常运行。随后,利用阿里云函数计算服务(FC 3.0)以 Serverless 方式部署该服务,包括创建函数、配置环境变量、添加依赖层以及部署代码。最后,提供了客户端测试方法和日志排查技巧,并展示了如何在不同工具(如 Cherry-Studio、Cline 和 Cursor)中配置云端 MCP 服务。
1562 10
借助 serverless 将 MCP 服务部署到云端
|
12月前
|
Cloud Native 安全 Serverless
云原生应用实战:基于阿里云Serverless的API服务开发与部署
随着云计算的发展,Serverless架构日益流行。阿里云函数计算(Function Compute)作为Serverless服务,让开发者无需管理服务器即可运行代码,按需付费,简化开发运维流程。本文从零开始,介绍如何使用阿里云函数计算开发简单的API服务,并探讨其核心优势与最佳实践。通过Python示例,演示创建、部署及优化API的过程,涵盖环境准备、代码实现、性能优化和安全管理等内容,帮助读者快速上手Serverless开发。
|
弹性计算 人工智能 自然语言处理
魔搭社区与函数计算:高效部署开源大模型的文本生成服务体验
在数字化时代,人工智能技术迅速发展,开源大模型成为重要成果。魔搭社区(ModelScope)作为开源大模型的聚集地,结合阿里云函数计算,提供了一种高效、便捷的部署方式。通过按需付费和弹性伸缩,开发者可以快速部署和使用大模型,享受云计算的便利。本文介绍了魔搭社区与函数计算的结合使用体验,包括环境准备、部署应用、体验使用和资源清理等步骤,并提出了改进建议。
|
机器学习/深度学习 监控 物联网
函数即服务(FaaS)
函数即服务(FaaS)
844 6
|
前端开发 JavaScript 大数据
React与Web Workers:开启前端多线程时代的钥匙——深入探索计算密集型任务的优化策略与最佳实践
【8月更文挑战第31天】随着Web应用复杂性的提升,单线程JavaScript已难以胜任高计算量任务。Web Workers通过多线程编程解决了这一问题,使耗时任务独立运行而不阻塞主线程。结合React的组件化与虚拟DOM优势,可将大数据处理等任务交由Web Workers完成,确保UI流畅。最佳实践包括定义清晰接口、加强错误处理及合理评估任务特性。这一结合不仅提升了用户体验,更为前端开发带来多线程时代的全新可能。
459 1
|
消息中间件 关系型数据库 Serverless
【阿里云】一键部署创建函数计算服务以处理多媒体文件
通过阿里云的一键部署功能,轻松创建函数计算服务以处理多媒体文件。首先选择地域并配置资源栈名称及其他必要参数,如登录凭证、实例类型及数据库配置。过程中可能需开通相关服务如消息服务MNS,并确保账户有足够的余额。完成配置后,系统自动创建资源栈。当状态显示“创建成功”即部署完毕。最后,通过提供的URL及凭据访问应用,上传PPTX文件进行处理,并下载处理后的结果。
259 5
|
存储 运维 安全
函数计算产品使用问题之如何获取到访问其他阿里云服务所需的AccessKey、SecretKey或STS Token
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
Kubernetes 安全 Serverless
Kubernetes 的架构问题之Serverless Container中提供对外服务如何解决
Kubernetes 的架构问题之Serverless Container中提供对外服务如何解决
198 6

相关产品

  • 函数计算