草庐IT

专题五 在Cisco Packet Tracer中设计基于 PT 和 OneNet 的智能家居系统

史迪仔不是626 2024-03-28 原文

摘    要

        智能家居是物联网在家庭中的基础应用,随着宽带业务的普及,智能家居产品涉及到方方面面。 家中无人,可利用手机等产品客户端远程操作智能空调,调节室温,甚者还可以学习用户的使用习惯,从而实现全自动的温控操作,使用户在炎炎夏季回家就能享受到冰爽带来的惬意;通过客户端实现智能灯泡的开关、调控灯泡的亮度和颜色等等; 插座内置Wifi,可实现遥控插座定时通断电流,甚者可以监测设备用电情况,生成用电图表让你对用电情况一目了然,安排资源使用及开支预算。

        本次课程设计要求设计一个基于 PT 和 OneNet 的智能家居系统,该系统要满足日常生活所使用的智能条件。

关键词

        Python;物联网;PT;Cisco Packet Tracer

 

1.平台及软件

        本次课设需要使用Cisco Packet Tracer模拟器和OneNet物联网平台。

        Packet Tracer是一个功能强大的网络仿真程序,允许学生实验与网络行为,问“如果”的问题。随着网络技术学院的全面的学习经验的一个组成部分,包示踪提供的仿真,可视化,编辑,评估,和协作能力,有利于教学和复杂的技术概念的学习。

        OneNET-中国移动物联网开放平台是由中国移动打造的PaaS物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接,提供综合性的物联网解决方案,实现物联网设备的数据获取,数据存储,数据展现。

2.设计要求

2.1 环境参数设置

        用户地理位置:海南大学儋州校区,PT的环境参数设置为该位置的。

2.2必需实现以下功能:

        湿度大于阈值:风扇打开;否则关闭。湿度阈值的初始值为50%,可通过云平台oneNet发送控制指令,远程设置湿度阈值。

1. 光照度小于20%:台灯及LED灯打开;否则关闭。

2. 温度高于25度:空调打开;否则关闭。

3. 风速大于2KPH:关窗;否则,开窗。

        音箱播放音乐:

1. 门状态为doorstate=="1,0"时,即门打开且未上锁时(主人回家或在家),开始播放音乐。

2.  门状态为doorstate=="0,1"时,即门关闭且上锁时,停止播放音乐。

3. 门状态为doorstate=="0,0"时,即门关闭且未上锁时,可通过云平台oneNet发送控制指令,开始播放音乐或停止播放音乐。

2.3可选实现以下功能:

1.光照度小于20%且有人在家时:台灯及LED灯打开;否则关闭。

2. 温度高于25度且有人在家时:空调打开;否则关闭。无人在家时可通过云平台oneNet发送控制指令:当温度高于35度时打开空调;当温度低于35度时关闭空调。

3. 风速大于2KPH:关窗;否则,开窗。

4. 增加一个“室外花园”,当湿度小于30%时,开始“浇花”。

5. 增加你认为需要的其它功能。

3.功能实现

3.1用户地理位置

 

 3.2必备功能

 

3.2.1系统概况

        第一部分是室内传感器,有温度传感器,湿度传感器,光照传感器,这三种传感器将数据发送到MCU0进行数据分析再发送到SBC发送到云端管理。

        第二部分是室内家具,有窗户,门,空调,电扇,台灯,LED灯,音响,它们受控于MCU1听从SBC发送的指令。

        第三部分是室外花园,有浇灌系统,湿度传感器,传感器将数据发送到MCU2进行数据分析再发送到SBC发送到云端管理,浇灌系统受控于MCU2听从SBC发送的指令。

 

3.2.2联动实现

        当湿度大于阈值:风扇打开;否则关闭。湿度阈值的初始值为 50%,可通过云平台 oneNet 发送控制指令,远程设置湿度阈值。

        在MCU1中代码实现,如果获取到“fan:open”,则打开风扇,否则关闭:

if':'in data:

    cmd =data.split(':')

    if cmd[0] == "fan":

        if cmd[1]=="open":

        customWrite(3,1)

    if cmd[1]=="close":

        customWrite(3,0)

        在SBC中代码实现设置阈值,并通过云端发送指令修改阈值:

 

         如果获取到“window:open”,则打开窗户,否则关闭:

if cmd[0] == "window":			
	if cmd[1]=="open":
		customWrite(A1,1)
	if cmd[1]=="close":
		customWrite(A1,0)

         如果获取到“light:open”,则打开台灯与LED灯,否则关闭:

if cmd[0] == "light":
    if cmd[1]=="open":
		customWrite(4,1)
		analogWrite(5,1023)
	if cmd[1]=="close":
		customWrite(4,0)
		analogWrite(5,0)

 

        如果获取到“airconditioner:open”,则打开空调,否则关闭:

if cmd[0] == "airconditioner":

    if cmd[1]=="open":
    
        digitalWrite(2, HIGH)

    if cmd[1]=="close":

        digitalWrite(2, LOW)

 

        如果获取到“music:open”,则打开音响,否则关闭:

if cmd[0] == "music":

    if cmd[1]=="open":

        digitalWrite(A0, HIGH)

    if cmd[1]=="close":

        digitalWrite(A0,LOW)

 

        如果室外湿度小于30%,则开始浇花,否则关闭:

def check(shidu):

    if shidu < 30:

        customWrite(0,1)

    else:

        customWrite(0,0)

         在SBC中进行本地数据与阈值比较判断,是否满足开启条件,代码实现如下:

def hum():
	
	if (sensor_humitidy >= humitidy_threshold):#fan
		for _client in clients:
			_client.send("fan:open")
	else: 
		for _client in clients:
			_client.send("fan:close")
	sleep(1)
	
	if (sensor_sunlight < sunlight_threshold):#light and led
		for _client in clients:
			_client.send("light:open")
	else: 
		for _client in clients:
			_client.send("light:close")
	sleep(1)		
	
	if (sensor_temperature > temperature_threshold):#air conditioner
		for _client in clients:
			_client.send("airconditioner:open")
	else: 
		for _client in clients:
			_client.send("airconditioner:close")
	sleep(1)
	if (sensor_door == 0 and music_threshold == 1):
		for _client in clients:
			_client.send("music:open")
	elif(sensor_door == 0 and music_threshold == 0):
		for _client in clients:
			_client.send("music:close")
	sleep(1)	
	
	if (sensor_wind >= wind_threshold):
		for _client in clients:
			_client.send("window:close")#window
	else: 
		for _client in clients:
			_client.send("window:open")
			
	sleep(1)

        本段代码分析:

        在hum函数中,有sensor_和threshold两类值,前者是传感器获取的本地数据,后者是默认阈值(可以通过云端下发命令进行更改),再结合设计书要求对数据进行比较再由服务端向客户端发送命令即可。

3.2.3通信实现

        在各开发板上创建客户端,在SBC上创建服务端,在云端创建对应的设备并在SBC上配置好对应的接收方法,代码如下:

        SBC:


serverIP = "183.230.40.40"
serverPort = 1811
###
auth1 = '*556835#humidty#Lab1*' #产品 ID#设备鉴权信息#脚本名称
auth2 = '*556835#sunlight#Lab1*'
auth3 = '*556835#temperature#Lab1*'
auth4 = '*556835#wind#Lab1*'
auth5 = '*556835#door#Lab1*'
###
oneNetclient = RealTCPClient()
oneNetclient2 = RealTCPClient()
oneNetclient3 = RealTCPClient()
oneNetclient4 = RealTCPClient()
oneNetclient5 = RealTCPClient()
###
def on1oneNet_TCPConnectionChange(type):
	if type == 3:
		oneNetclient.send(auth1)
def on1oneNet_TCPConnectionChange2(type):	
	if type == 3:
		oneNetclient2.send(auth2)
def on1oneNet_TCPConnectionChange3(type):
	if type == 3:
		oneNetclient3.send(auth3)
def on1oneNet_TCPConnectionChange4(type):
	if type == 3:
		oneNetclient4.send(auth4)
def on1oneNet_TCPConnectionChange5(type):
	if type == 3:
		oneNetclient5.send(auth5)

####
def on1oneNet_TCPReceive(data):
	print("received threshold from oneNet: " + data);
	if ':' in data:
		value = data.split(':')
		if value[0]=="humidity":
			global humitidy_threshold
			humitidy_threshold = value[1]
		if value[0]=="sunlight":
			global sunlight_threshold
			sunlight_threshold = value[1]
		if value[0]=="temperature":
			global temperature_threshold
			temperature_threshold = value[1]
		if value[0]=="wind":
			global wind_threshold
			wind_threshold = value[1]
def main():
	server.listen(port)
	server.onNewClient(onTCPNewClient)
	
	#1
	oneNetclient.onConnectionChange(on1oneNet_TCPConnectionChange) #add 3 lines
	oneNetclient.onReceive(on1oneNet_TCPReceive)
	oneNetclient.connect(serverIP, serverPort)
	#2
	oneNetclient2.onConnectionChange(on1oneNet_TCPConnectionChange2) #add 3 lines
	oneNetclient2.onReceive(on1oneNet_TCPReceive)
	oneNetclient2.connect(serverIP, serverPort)
	#3
	oneNetclient3.onConnectionChange(on1oneNet_TCPConnectionChange3) #add 3 lines
	oneNetclient3.onReceive(on1oneNet_TCPReceive)
	oneNetclient3.connect(serverIP, serverPort)
	#4
	oneNetclient4.onConnectionChange(on1oneNet_TCPConnectionChange4) #add 3 lines
	oneNetclient4.onReceive(on1oneNet_TCPReceive)
	oneNetclient4.connect(serverIP, serverPort)
	#5
	oneNetclient5.onConnectionChange(on1oneNet_TCPConnectionChange5) #add 3 lines
	oneNetclient5.onReceive(on1oneNet_TCPReceive)
	oneNetclient5.connect(serverIP, serverPort)	
	sleep(1)
	while True:
		oneNetclient.send(sensor_humitidy)
		oneNetclient2.send(sensor_sunlight)
		oneNetclient3.send(sensor_temperature)
		oneNetclient4.send(sensor_wind)
		oneNetclient4.send(sensor_door)

MCU0:

serverIP = "192.16.1.250"
serverPort = 1234

###
client = TCPClient()

def onTCPConnectionChange(type):
	print("connection to " + client.remoteIP() + " changed to state " + str(type))

def onTCPReceive(data):
	print("received from " + client.remoteIP() + " with: " + data)
def main():
	
	client.connect(serverIP, serverPort)
	client.onConnectionChange(onTCPConnectionChange)
	client.onReceive(onTCPReceive)

	while True:
		client.send(gethumidity())
		sleep(1)
		client.send(getsunlight())
		sleep(1)
		client.send(gettemperature())

MCU1:

serverIP = "192.16.1.250"
serverPort = 1234
client = TCPClient()

def onTCPConnectionChange(type):
	print("connection to " + client.remoteIP() + " changed to state " + str(type))

def onTCPReceive(data):
	global cmd
	print("received from " + client.remoteIP() + " with " + data)
def main():
	client.onConnectionChange(onTCPConnectionChange)
	client.onReceive(onTCPReceive)
	client.connect(serverIP, serverPort)
	
	while True:
		client.send(door())

本段代码解析:

        在SBC与MCU上分别设置客户端和服务端,多看两遍代码就可以看出来固定格式。

        首先,关键的是设置好云端的设备然后再SBC上将产品和设备进行绑定,auth设置好,然后将接收函数与发送函数的对应关系找到,做到一收一发完美对接。

        值得注意的是,传参过程中你看到的数字有可能并不是数字,可能是字符,因此,要将传出的值格式化,转换成 int 类型或者 float 类型都可。

运行如下:

 完整工程文件 pkt 链接如下:

智能家居系统(密码请关注公众号:玹之空间 -->资料获取)

 

 

 

有关专题五 在Cisco Packet Tracer中设计基于 PT 和 OneNet 的智能家居系统的更多相关文章

  1. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  2. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  3. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  4. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  5. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

  6. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

  7. ruby-on-rails - 如何在回形针 ruby​​ on rails 中设置默认图像 - 2

    最近我安装了Paperclipgem,我正在努力让默认图像在我的系统上工作,我将图像文件放在assets/images/pic.png中。这是我的模型User中的代码:has_attached_file:pic,:styles=>{:medium=>"300x300>",:thumb=>"100x100>"},:default_url=>'missing_:avatar.png'#:default_url=>'assets/images/avatar.png'has_attached_file:attach这是我的AddPicPaperClip迁移中的代码:defself.upadd_

  8. ruby-on-rails - Rails 中的类实例变量应该在互斥体中设置吗? - 2

    假设我的Rails项目中有一个设置实例变量的Ruby类。classSomethingdefself.objects@objects||=begin#somelogicthatbuildsanarray,whichisultimatelystoredin@objectsendendend是否可以多次设置@objects?是否有可能在一个请求期间,在上面的begin/end之间执行代码时,可以在第二个请求期间调用此方法?我想这实际上归结为Rails服务器实例如何fork的问题。我应该改用Mutex还是线程同步?例如:classSomethingdefself.objectsreturn@o

  9. ruby - 在 Rakefile 中动态生成 Rake 测试任务(基于现有的测试文件) - 2

    我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n

  10. ruby-on-rails - 如何在 ActionController::TestCase 请求中设置内容类型 - 2

    我试图像这样在我的测试用例中执行获取:request.env['CONTENT_TYPE']='application/json'get:index,:application_name=>"Heka"虽然,它失败了:ActionView::MissingTemplate:Missingtemplatealarm_events/indexwith{:handlers=>[:builder,:haml,:erb,:rjs,:rhtml,:rxml],:locale=>[:en,:en],:formats=>[:html]尽管在我的Controller中我有:respond_to:html,

随机推荐