公司开始公布他们的远程员工重返工作岗位的政策。重返办公室必然会增加新的 COVID-19 病例数。但是,可能有一种方法可以减少办公室内 COVID-19 病毒的传播。一般来说,办公室都有隔间,有助于隔离直接的人际传播,但仍然存在传播热点,尤其是在共享空间。会议室是最糟糕的罪魁祸首之一,因为会议室不仅受到限制并在不同群体之间快速共享,而且仅在一天结束时才进行清洁。将责任留给任何共同行动,例如给办公室植物浇水,让会议室里的任何人承担责任,即使曾经得到维护,也很少得到支持。甚至白板的标记也很少被替换。此外,每天/每周消耗多个消毒湿巾/罐是非常浪费的,并且不会随着会议次数而增加。因此,我提出了一种会议集成可再填充物联网设备的解决方案,该设备对已发生会议的会议室进行消毒。
我的解决方案包括一个全栈应用程序以及一个嵌入式设备。有几个工作部分,所以我将首先对系统流程进行高级概述,然后详细解释。这样,那些关注下一节标题为“我是如何构建它的?可以理解为什么我做了我所做的。
以下是该系统的高级概述:
我的解决方案从一个全栈应用开始。我有一个显示 GUI 的前端:
设置参数并切换“检查可用性”按钮后,后端会查看所选会议间隔的 AWS DynamoDB 表,并返回可用会议列表以及会议间隔可用的房间. 下面是表格的示例:
为了简化开发过程,设置了一些注意事项。会议仅每一刻钟开始,持续时间是一刻钟的倍数,并且 Room 1 被硬编码以对应于我的 Core2ForAWS 设备。选择房间 1 的会议后,Core2ForAWS 元素的设备影子将更新为所选会议间隔。设备影子(稍后解释)将如下所示:
设备逻辑
core2ForAWS 元素将解析来自设备影子的会议间隔信息,并填充大小为 96 的会议间隔数组。数组中的每个索引对应于该索引对应的 15 分钟间隔的会议状态。由于 1 天是 24 小时,因此有 96 个间隔,每个间隔为 15 分钟。15 分钟间隔参考从上午 12:00 开始。12:00 AM 被认为相当于 0000 分钟,第 0 个 15 分钟间隔。因此,15 分钟间隔数组的索引 0 对应于从 12:00 AM 到 12:15 AM 的会议间隔的会议状态。如果安排了从上午 12:00 到上午 12:15 的会议,则数组的索引 0 将标记为“1”以表示会议间隔,如果没有安排在上午 12:00 的会议,则将标记为“0”到上午 12:15 会议间隔。
现在,我创造了“先生”的嵌入式设备(它是整个设备,包括 core2ForAWS 元素)接管了。Mister 会检查每个 15 分钟间隔边缘,并且仅当边缘出现在刚刚结束的会议和没有会议的 15 分钟间隔之间时才会激活。会议间隔边缘是两个会议间隔之间的边界。例如上午 12:00->12:15 会议间隔和 12:15->12:30 会议间隔之间的边界。因此,例如,如果先生在 12:15 检查并注意到从 12:00 AM -> 12:15 AM 有一个会议,并且从 12:15 AM -> 12:30 AM 会议没有即将召开的会议,则会出现激活条件间隔。就索引而言,我们可以将其表示为从任何 array[j] = 1 到 array[j+1] = 0 的任何转换,对于所有 j >= 0 &
一旦找到这样的 1->0 边缘,先生的 PIR 传感器就会被激活,并每 2 分钟检查一次移动,以防刚刚发生的会议进入另一个会议间隔。如果在下一个会议间隔之前检测到活动,则在检查即将到来的会议间隔边缘之前将当前会议间隔标记为“1”,因为存在会议间隔的活动价值。这张图可以阐明这个想法:
假设目前,某个时间 > 8:00 am 和 < 8:15 am,由 1 表示。没有安排在上午 8:00 举行的实际会议,所以先生对会议间隔的内部表示是数组索引:32(上午 8:00 是从上午 12:00 开始的 8 小时,8 * 4 = 32 = 上午 8:00 的数组索引)是“0”。如果 PIR 一直持续到上午 8:15(由 2 表示),则索引 32 处的间隔被标记为“1”。索引 32 被标记为“1”,因为 15 分钟的会议间隔(上午 8:00)不打算主持会议,但仍然主持了 15 分钟的活动。
如果 PIR 传感器在 2 分钟内未检测到活动,则会启动辅助检查。首先,会出现提示音,以提醒房间内的任何人即将喷水,然后显示一个设备屏幕,显示从 30 秒开始的倒计时,并带有确认按钮(视频演示将显示这一点)。如果确认屏幕在整个持续时间内都被忽略,则先生启动伺服系统并喷洒房间,并等待下一个 15 分钟间隔。如果确实确认了活动,则先生将返回以返回 PIR 逻辑。
我开始花一些时间学习 JS,reactJS:https ://reactjs.org/docs/getting-started.html和 nodeJS:https ://nodejs.org/en/docs/ 。我将在下面解释 AWS DynamoDB 和 AWS IoT Core 集成并链接我的全栈应用程序存储库。
我首先在这里设置我的 Core2ForAWS:https ://edukit.workshop.aws/en/getting-started.html ,只需完成这些步骤。然后,我按照以下说明设置 AWS IoT Core:https ://edukit.workshop.aws/en/blinky-hello-world/prerequisites.html 。到此阶段,您应该能够获取 AWS IoT 终端节点,并且您创建的 IAM 用户应该具有以下策略:
如果您找不到添加此策略的位置,请使用您的根电子邮件登录 AWS 控制台,然后单击“IAM”。你应该在左边看到这个:
单击“用户”,然后单击您创建的用户。你会看到这样的东西:
添加 AWSIoTFullAccess 策略。
这是我对正在发生的事情的解释。您创建的 AWS 账户包含所有资源,例如 AWS IoT Core、DynamoDB、IAM 等。您创建的 IAM 用户是经过身份验证的实体,可以根据 IAM 用户的策略访问 AWS 账户的资源。当使用 IAM 用户密钥在 CLI 上运行命令“ aws configure”时,会创建一个配置文件并将其与用户密钥一起存储在您的笔记本电脑上。调用 AWS 开发工具包 API 时,会找到配置文件。然后会发生一些调解,以便被调用的 API 具有与使用“ aws configure”命令配置密钥的 IAM 用户的策略相同的权限。
现在,将 AmazonDynamoDBFullAccess 策略也添加到您的 IAM 用户。它应该如下所示:
以下是与 AWS 交互并带有注释的相关代码片段:
AWS.config.dynamodb = {
region: "us-west-2",
//replace endpoint with own endpoint
endpoint: "https://dynamodb.us-west-2.amazonaws.com",
};
AWS.config.iotdata = {
region: "us-west-2",
//replace endpoint with own endpoint
endpoint: "a36ozlrpzvmdr4-ats.iot.us-west-2.amazonaws.com",
};
// setting up the necessary AWS SDK objects
let dynamodb = new AWS.DynamoDB();
let docClient = new AWS.DynamoDB.DocumentClient();
let iotdata = new AWS.IotData();
// parameters for the DynamoDB table to be created
// replace TABLE_NAME with own table name
// replace PRIMARY_KEY with own primary key name
// replace SECONDARY_KEY with own secondary key name
let params = {
TableName: TABLE_NAME,
KeySchema: [
{ AttributeName: PRIMARY_KEY, KeyType: "HASH" },
{ AttributeName: SECONDARY_KEY, KeyType: "RANGE" },
],
AttributeDefinitions: [
{ AttributeName: PRIMARY_KEY, AttributeType: "S" },
{ AttributeName: SECONDARY_KEY, AttributeType: "S" },
],
ProvisionedThroughput: {
ReadCapacityUnits: 10,
WriteCapacityUnits: 10,
},
};
// the API that creates the DynamoDB table
dynamodb.createTable(params, function (err, data) {
if (err) {
console.error(
"Unable to create table. Error JSON:",
JSON.stringify(err, null, 2)
);
} else {
console.log(
"Created table. Table description JSON:",
JSON.stringify(data, null, 2)
);
}
});
// parameters for shadow
// payload is what to update the shadow with
// thingName is the name of the thing that you registered with AWS IoT Core
let shadowParams = {
// core2IoTPayload should be a JSON of your own choice
payload: JSON.stringify(core2IoTPayload),
// replace thingName with the thing name of own device
thingName: "01231bd1cbac971101"
};
// API to update shadow
iotdata.updateThingShadow(shadowParams, function (err, data) {
if (err) {
console.error("Unable to send to core2", JSON.stringify(err, null, 2));
} else {
console.log("send to core2 succeeded:");
}
});
// API to update DynamoDB table
docClient.put(putParams, function (err, data) {
if (err) {
res.send(JSON.stringify("error"));
} else {
res.send(JSON.stringify("success"));
}
});
下一步是创建先生设备。我想要一个可以用晶体管激活的电动水泵,所以我买了其中一个:
我把它拆开,它看起来像这样:
事实证明,只需用开关短接两个端子即可打开(您可以在原理图部分看到这一点)。我将电子设备与伺服器和 PIR 传感器一起粘在一些纸板上,然后向前跳了几步(我忘了拍中间照片),我最终得到了这个:
电动泵机构位于中间部分,就在空透明罐的正上方。四根柱子中心的弯曲“向后 r”部分使雾气输出偏转。最重要的是,我有 PIR 传感器、控制泵机制的晶体管和 Core2ForAWS 设备。一旦雾气打开,电动泵机构就会从罐中直接向上喷射雾状消毒剂。伺服器开始动作,弯曲的“向后 r”段以 360 度的方式偏转薄雾。如果我有一台 3D 打印机,这个设备的设计会大不相同,而且效率更高(雾偏转应该旋转雾输出的喷嘴,而不是雾本身)。对于 PIR,我将其设置为像这样的非重新触发模式,因此每次移动都会导致边缘触发中断:
!!!!笔记 !!!!原理图中的电路图需要澄清一下,舵机的5V和GND线应该连接到外部电池或输入电缆到 core2ForAWS !如果您连接到外部电池,请确保电池的接地连接到 core2ForAWS 的接地。从 core2ForAWS 连接到晶体管基极的导线是 core2ForAWS 上的 PIN26。在进行更改之前,我用完了 CircuitLab 免费试用版。
下面的代码部分列出了启动和运行 core2ForAWS 组件以及全栈应用程序的确切步骤。
之前,我提到了一个设备影子,我想首先邀请您在这里查看此链接:解释什么是设备影子。您可以将设备影子视为 AWS IoT“事物”与外部影响(即全栈应用程序)之间的通信媒介。实际上,它更复杂,但它超出了本文的范围。从本质上讲,发生的事情是全栈应用程序写入此设备影子,并且预置并连接到 AWS IoT Core 的 core2ForAWS 收到刚刚写入设备影子的更改的通知。
要开始使用全栈应用程序,请遵循此处的 README:https ://github.com/daxlar/mister-frontend和此处:https : //github.com/daxlar/mister-backend上面的解释可能比在整个文章中插入代码块更好地解释了代码。
设备的接线将在“原理图”部分列出,所有代码将在“代码”部分。进入演示!
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !