手机APP远程控制基于智云物联平台的传感器

  1. 概述
    1. 课程实训概述

       主要是完成通过移动端APP控制智云物联实验平台上的传感器,本次实训实现对灯光传感器的控制或实现对自有电路板上某一元器件的控制。

    1. 主要内容

       本次实训报告的主要内容包括以下几点:

       (1)智云物联实验平台简介。

       (2)配置智云物联实验平台硬件。

       (3)基本功能的实现,美化软件界面,提高用户输入操作性和界面显示友好性。

       (4)思考总结开发过程中的问题和想法。

  1. 智云物联平台简介
    1. 智云物联平台项目系统模型

       用户通过注册模块,获取到一个账号权限。通过账号登录到开关控制界面,通过拨动按钮来控制灯的开关。

    1. ZXBee通信协议

ZXBee是一套基于JSON格式的轻量级物联网通信协议。

ZXBee协议旨在描述传感器节点与应用间的“对话”。通信协议数据格式: {[参数]=[值],{[参数]=[值],……},每条数据以“{}”作为起始字符,“{}”内参数多个条目以“,”分隔。

    1. 智云物联软件框架

通过移动端连接光照传感器,设置用户账户,用户密钥,服务器地址,光敏传感器MAC地址。

    1. 主要功能设计

       1)布局文件

       页面有2个:登录注册页面、和控制页面。其中本节点主要讲解布局设计。界面使用FrameLayout布局,页面下方是一个文字输入框和一个发送按钮,如图2-1所示。

 

图2-1 界面布局

       2)主配置文件

       由于这个应用需要调用平台的信息,所以需要特别在AndroidManifest.xml文件中注册应用访问网络的权限,如下所示:

<uses-permission android:name="android.permission.INTERNET"/>

    1. 通讯设计

public class ZApplication extends Application implements WSNRTConnectListener {

    public WSNRTConnect wRTConnect;//创建 WSNRTConnect实例

    public WSNHistory wHistory;//创建 WSNHistory实例

    public WSNRTConnect getWSNRConnect(){

        if(wRTConnect==null){

            wRTConnect = new WSNRTConnect();//初始化WSNRTConnect实例

        }

        return wRTConnect;

    }

    public WSNHistory getWSNHistory(){

        if(wHistory==null){

            wHistory = new WSNHistory();//初始化WSNHistory实例

        }

        return wHistory;

    }

    public void onCreate(){

        super.onCreate();

        wRTConnect=getWSNRConnect();

        wRTConnect.setRTConnectListener(this);//设置WSNRTConnectListener监听

    }

    //消息到达时会自动调用该方法

    public void onMessageArrive(String mac,byte[] data){

        if(data[0]=='{'&& data[data.length-1]=='}'){

    String sData =new String(data,1,data.length-2);

    String[] pDatas = sData.split(",");

    for(String pData:pDatas){

        String[] tagVal = pData.split("=");

        if(tagVal.length==2){

            for(IOnWSNDataListener li:mIOnWSNDataListeners){

                //实现了IOWSNDataListener传感器数据监听接口的类都会自动调用onMessageArrive()方法

                li.onMessageArrive(mac,tagVal[0],tagVal[1]);

            }

        }

    }

        }

    }

    //连接失败

    public void onConnectLost(Throwable arg0){

        Toast.makeText(ZApplication.this,"断开连接",Toast.LENGTH_SHORT).show();

        for(IOnWSNDataListener li:mIOnWSNDataListeners){

            //实现了IOWSNDataListener传感器数据监听接口的类都会自动调用onConnectLost()方法

            li.onConnectLost();

        }

    }

    //连接成功

    @Override

    public void onConnect() {

        Toast.makeText(ZApplication.this,"连接网关成功",Toast.LENGTH_SHORT).show();

        for(IOnWSNDataListener li:mIOnWSNDataListeners){

            //实现了IOWSNDataListener传感器数据监听接口的类都会自动调用onConnect()方法

            li.onConnect();

        }

    }

    //传感器数据监听器数组

    public ArrayList<IOnWSNDataListener>mIOnWSNDataListeners = new ArrayList<>();

    //注册传感器数据监听器

    public void registerOnWSNDataListener(IOnWSNDataListener li){mIOnWSNDataListeners.add(li);}

    //取消注册传感器数据监听器

    public void unregisterOnWSNDataListener(IOnWSNDataListener li){

        mIOnWSNDataListeners.remove(li);

    }

}

  1. 系统实现
    1. 系统界面
    2. 系统程序实现
      1. Android客户端程序实现

 

(1)项目整体框架

 

(2)Register中的登录按钮点击事件

public class Register extends AppCompatActivity {



    private SQlite mSQlite;

    private EditText username;

    private EditText userpassword;

    private Button reday;

    private Button back;



    String name;







    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.start);

        reday = findViewById(R.id.reday);

        back = findViewById(R.id.back);

        username = findViewById(R.id.userName);

        userpassword =findViewById( R.id.userpassword);



        reday.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                 name = username.getText().toString().trim();

                String password = userpassword.getText().toString().trim();

                if(!TextUtils.isEmpty(name)&&!TextUtils.isEmpty(password)){

                    mSQlite.add(name,password);

                    Intent intent1 = new Intent(Register.this,MainActivity.class);

                    startActivity(intent1);

                    finish();

                    Toast.makeText(Register.this,"注册成功",Toast.LENGTH_SHORT).show();

                }else {Toast.makeText(Register.this,"信息不完备,注册失败",Toast.LENGTH_SHORT).show();}

            }

        });

        mSQlite = new SQlite(Register.this);

        back.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                String name = username.getText().toString().trim();

                String password = userpassword.getText().toString().trim();

                try {

                    // 当用户按下发送按钮后,将用户输入的数据封装成

                    //Message

                    // 然后发送给子线程的 Handler





                    // 清空 input 文本框

                    // input.setText("");

                } catch (Exception e) {

                    e.printStackTrace();

                }



                if (!TextUtils.isEmpty( name ) && !TextUtils.isEmpty( password )) {

                    ArrayList<User> data = mSQlite.getAllDATA();

                    boolean user = false;

                    for (int i = 0; i < data.size(); i++) {

                        User userdata = data.get( i );   //可存储账号数量

                        if (name.equals( userdata.getName() ) && password.equals( userdata.getPassword() )) {

                            user = true;

                            break;

                        } else {

                            user = false;

                        }

                    }

                    if (user) {

                        baocun.name= username.getText().toString();

                        baocun.password= userpassword.getText().toString();

                        Toast.makeText( Register.this, "登录成功", Toast.LENGTH_SHORT ).show();

                        Intent intent = new Intent( Register.this, MainActivity.class );

                        intent.putExtra( "username", name );

                        intent.putExtra( "password", password );  //展示账号密码功能

                        startActivity( intent );

                        finish();

                    } else {

                        Toast.makeText( Register.this, "用户名或密码不正确", Toast.LENGTH_SHORT ).show();

                    }

                } else {

                    Toast.makeText( Register.this, "用户名或密码不能为空", Toast.LENGTH_SHORT ).show();

                }

            }

        });





    }

}

(3)MainActivity中的发送按钮点击事件

public class MainActivity extends AppCompatActivity implements  IOnWSNDataListener{

    private ZApplication mApplication;//创建 ZApplication实例

    private WSNRTConnect wRTConnect;//创建WSNRTConnect实例



    //配置信息

    private String ID = "837958346782";//用户账户

    private String KEY = "CQUEAAwOBwUABAgKQxFBWFlRV11CFQISCQoCDAYKBwUDDhQSGl1WVFAaCRQUT01IUEoVRA8";//用户密钥

    private String server = "zhiyun360.com";//服务器地址

    private String mMac = "00:12:4b:00:07:5E:23:D2";//光敏传感器IEEE地址



    private TextView tv1;

    private TextView tv2;

    private ImageView btn;

    int[] ic=new int[]{R.mipmap.btn0,R.mipmap.btn1};

    private int setCount = 0;



    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);



        mApplication = (ZApplication) getApplication();

        wRTConnect = mApplication.getWSNRConnect();

        wRTConnect.setIdKey(ID, KEY);//设置ID,KEY

        wRTConnect.setServerAddr(server);//设置服务器地址

        mApplication.registerOnWSNDataListener((IOnWSNDataListener) MainActivity.this);

        wRTConnect.connect();//建立实时连接



        tv1 = findViewById(R.id.textView1);

        tv2 = findViewById(R.id.textView1);

        btn = findViewById(R.id.button1);

        btn.setOnClickListener(new View.OnClickListener() {

            public void onClick(View x) {

               if (setCount % 2 == 1) {

                   setCount++;

                    new Thread(new Runnable() {

                        @Override

                        public void run() {

                            wRTConnect.sendMessage(mMac, "{OD1=3,D1=1}".getBytes());//查询关照强度值

                            tv1.setText("智能LED灯状态:关闭");





                        }

                    }).start();

                   btn.setImageResource(R.drawable.btn0);

                    Toast.makeText(MainActivity.this, "{OD1=3,D1=1}", Toast.LENGTH_SHORT).show();

                } else {

                   setCount++;

                    new Thread(new Runnable() {

                        @Override

                        public void run() {

                            wRTConnect.sendMessage(mMac, "{CD1=1,D1=1}".getBytes());//查询关照强度

                            tv1.setText("智能LED灯状态:开启");



                        }

                    }).start();

                   btn.setImageResource(R.drawable.btn1);



                    Toast.makeText(MainActivity.this, "{OD1=1,D1=1}", Toast.LENGTH_SHORT).show();

                }

            }

        });

    }







    @Override

    public void onMessageArrive(String mac, String tag, String val) {



    }



    public void onConnectLost() {//连接失败

        tv2.setText("数据连接掉线!");



    }



    public void onConnect() {//连接成功

        Thread thread = new Thread(new Runnable() {

            @Override

            public void run() {

                try {

                    Looper.prepare();

                    wRTConnect.sendMessage(mMac, "D1=?".getBytes());

                    Toast.makeText(MainActivity.this, "D1=?", Toast.LENGTH_SHORT).show();

                    runOnUiThread(new Runnable() {

                        @Override

                        public void run() {

                            tv2.setText("数据服务连接成功");

                        }

                    });

                    Looper.loop();

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        });

        thread.start();

    }

   protected  void onDestory()

    {

        wRTConnect.disconnect();//断开连接

    }



}

  1. 系统测试
    1. 登录功能测试

表4-1 登录功能测试用例

测试项目

登录功能

测试编号

01

测试目的

登录信息的验证及容错处理

序号

测试内容

测试结果

测试结果是否合格

1

不输入任何内容

提示:请输入账号或密码

合格

2

只输入账号、不输入密码

提示:请输入账号或密码

合格

3

输入错误的账号密码

提示:账号或密码错误

合格

4

输入正确的账号密码

成功登录到聊天界面

合格

5

输入中文账号和密码

成功登录到聊天界面

合格

    1. 注册功能测试

表4-2 注册功能测试用例

测试项目

注册功能

测试编号

02

测试目的

注册信息的验证及容错处理

序号

测试内容

测试结果

测试结果是否合格

1

不输入任何内容

提示:请输入完整信息!

合格

2

只输入账号

提示:请输入完整信息!

合格

3

两次密码输入不一致

提示:两次密码不一致!

合格

4

注册已有账号

提示:请勿重复注册!

合格

5

注册新账号

提示:注册成功!

合格

    1. 控制功能测试

表4-3 控制功能测试用例

测试项目

控制功能

测试编号

03

测试目的

拨动按钮能否开关灯

序号

测试内容

测试结果

测试结果是否合格

1

拨动一次按钮

软件无异常,正常显示

合格

2

拨动两次按钮

软件无异常,正常显示

合格

3

拨动三次按钮

软件无异常,正常显示

合格

4

拨动四次按钮

软件无异常,正常显示

合格

  1. 项目总结

项目总结:

1、  btn.setImageResource(R.drawable.btn0);

Toast.makeText(MainActivity.this, "{OD1=3,D1=1}", Toast.LENGTH_SHORT).show();

要写在}}).start();的下一行,不能写在if里面,不然会出现闪退的情况。

2、setCount++;是实现判断灯光是开启还是关闭的全局变量,通过setCount++来自加一,判断setCount是偶数还是奇数来决策开关灯。一开始我是放在if之前进行setCount++,但是这会出现只能开关一次,第三次就不能进行控制了,之后放在if和else里面第一句,就可以解决这个问题了。

Application常见的用途如下:

初始化资源,App启动时会在Application的onCreate()方法中初始化一些全局资源,系统配置,三方sdk等。

此处需要注意一点,App可能会有多个进程:主进程、三方sdk的一些进程,初始sdk的时候需要注意在相应的进程中去初始化,避免浪费资源。

数据共享,由于Application对象是全局唯一的,所以可以用来缓存一些全局变量,这些变量在任何地方都可以调用,达到共享目的。

监听App所处状态。

实时连接(WSNRTConnect)

new WSNRTConnect(myZCloudID, myZCloudKey); 建立实时数据实例,并初始化智云ID及密钥

connect();建立实时数据服务连接

sendMessage(mac, dat); 发送消息

mac:传感器的MAC地址,dat:发送的消息内容

本次的移动平台应用程序设计课程报告基本完成了智能灯的功能开发,同时也得到了很多启示。

这个智能灯只是一个最基础的版本,没有实现更多的可交互和深入挖掘的功能,还有很大的改进空间。比如:可以在移动端设置光照传感器的MAC,不需要在电脑上线设置好配置信息了。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智能云插座 使用机智云开源APP之前,需要先在机智云开发平台创建您自己的产品和应用。 开源App需要使用您申请的AppId、AppSecret以及您自己的产品ProductKey才能正常运行。 具体申请流程请参见:http://docs.gizwits.com/hc/。 上述信息申请好之后,在代码中请找到"your_app_id"、"your_app_secret"、"your_product_key"字符串做相应的替换。 Gizwits Power Socket Android Demo App XPGWifiSDK 版本号 1.6.1.15123015 功能介绍 这是一款使用XPGWifiSDK的开源代码示例APP,可以帮助开发者快速入手,使用XPGWifiSDK开发连接机智云的物联APP。该APP针对的是智能家电中的插座类产品。包括了以下几点插座常用功能: ▪ 插座电源的开关 ▪ 插座定时开关 ▪ 插座倒计时开关 ▪ 定时周重复 如果开发者希望开发的设备与以上功能类似,可参考或直接使用该APP进行修改进行快速开发自己的智能家电App。 以下功能是机智云开源App的几个通用功能,除UI有些许差异外,流程和代码都几乎一致: ▪ 机智云账户系统的注册、登陆、修改密码、注销等功能 ▪ 机智云设备管理系统的AirLink配置入网、SoftAP配置入网,设备与账号绑定、解绑定,修改设备别名等功能 ▪ 机智云设备的登陆,控制指令发送,状态接收,设备连接断开等功能 另外,因为该项目并没有相对应的实体硬件设备供开发者使用,因此还提供了扫描虚拟设备功能,通过扫描机智云实验室内相对应的虚拟设备,可进行设备的绑定和控制等功能。同时可免费申请gokit进行设备的配置入网和绑定等流程。 项目依赖和安装 ▪ XPGWifiSDK的jar包和支持库 登录机智云官方网站http://gizwits.com的开发者中心,下载并解压最新版本的SDK。 下载后,将解压后的目录拷贝到复制到 Android 项目 libs 目录即可。 ▪ Gokit设备 使用机智云开发的Gokit设备并烧写相对应的产品标识码,可以体验设备配置上线等功能。 ▪ 虚拟设备 使用机智云实验室的相对应虚拟设备,可以体验设备指令收发,状态的获取等功能。 项目工程结构 ▪ 包结构说明 com.gizwits.powersocket -智能云插座独有代码,包含控制部分和侧边栏部分 com.gizwits.powersocket.activity.control -智能云插座控制界面activity com.gizwits.powersocket.activity.slipbar -智能云插座侧边栏activity com.gizwits.framework -机智云设备开源APP框架,包含除控制界面Activity外的代码,暂时机智云实验室中的其他开源APP所用框架一致 com.gizwits.framework.activity -机智云设备开源APP框架相关activity com.gizwits.framework.adapter -机智云设备开源APP框架相关数据适配器 com.gizwits.framework.config -机智云设备开源APP框架配置类 com.gizwits.framework.entity -机智云设备开源APP框架实体类 com.gizwits.framework.sdk -机智云设备开源APP框架操作SDK相关类 com.gizwits.framework.utils -机智云设备开源APP框架工具类 com.gizwits.framework.widget -机智云设备开源APP框架自定义控件 com.gizwits.framework.XpgApplication -机智云设备开源APP框架自定义Application com.xpg.XXX -机智云通用开发API zxing -第三方二维码扫描控件 使用流程 ▪ 虚拟设备+app使用流程(体验指令发、状态获取等流程) 1.在机智云官网上注册并登录帐号 2.使用机智云实验室里面的智能云插座启动虚拟设备 3.在app上注册并登录帐号 4.通过扫描网页上的二维码添加虚拟设备 5.进入控制界面与虚拟设备进行交互 ▪ gokit+app使用流程(体验配置、绑定实体设备等流程) 1.免费申请gokit,http://gizwits.com/zh-cn/gokit 2.下载gokit开源代码并按说明替换为智能云插座的产品标识码 3.在app上注册并登录帐号 4.通过我要配置gokit按钮,使用Airlink或SoftAP模式配置gokit入网 5.绑定gokit 6.进入控制界面

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值