资讯专栏INFORMATION COLUMN

Qt智能家居应用开发:硬件设备实现智能网络配置时候,如何使用第三方smart config 库

kuangcaibao / 852人阅读

摘要:串口配置大部分芯片都支持串口命令控制芯片的所有功能。是一个面向软件开发者的智能网络配置功能。电路设计按情况,留出串口和复位键,就可以当作官方评估版使用了。

背景

阅读前预备知识:

学习安晓辉老师的qt for android 核心编程(了解怎么在Qt 里边c++ 调用java,java库怎么加进qt工程中)

qt android wifi 开发篇

现在做智能硬件设备,都是使用模块化的流行wifi芯片来接入云端,实现实时通讯和数据交互的工作.以前使用wifi芯片我们经常会遇到一个问题:在wifi设备初始化过程中,我们要手动从ap模式配置连接路由器,这个操作流程对于我们开发人员来说看起来很简单,当换路由器的时候,按复位键然后手动配置就好了.甚至现在我看到许多这样的产品比如网络摄像头,一些远程控制设备都是这个模式.甚至我在学校工作室的时候老师买了一套智能家居设备,我们要看着一本说明书按着流程来手动配置网络.也就是现在大部分智能设备还是存在这个问题(其实已经有解决方案了,也许开发商还没有留意到现在流行的智能网络配置功能,这个有没缺点漏洞我不知道,毕竟我也是新手,只用这个技术做过简单的智能家居系统).

wifi设备实现网络配置方式之间差异

比起传统的ap模式网页配置wif芯片网络或者串口配置网络,smartconfig是一种新型的智能网络配置功能,操作起来更智能方便,时物联网芯片产品的一大趋向。
区别:

ap模式下的网页形式配置

ap (所谓ap模式就是把wifi芯片启动成像路由器一样,可以让其他wifi终端连接到这个wifi芯片)模式下的网页形式是通过wifi终端手动搜索wifi芯片开的ap服务,然后连接该wifi芯片。接着在wifi终端打开浏览器,访问wifi芯片的地址(比如: http://192.168.0.1 ),由于wifi芯片本来支持ap模式,它已经是一个简单的网站服务,通过这网页去获取权限设置wifi芯片提供的设置项服务,比如重启连接到路由器等等。

串口配置

大部分wifi芯片都支持串口命令控制wifi芯片的所有功能。这时候就需要通过串口命令区控制wifi芯片了。

smartconfig

smartconfig 是一个面向软件开发者的智能网络配置功能。硬件开发商无需关系自己的wifi芯片怎么连接到路由器,也无需知道动态的路由怎么被切换。因为smartconfig时通过终端软件去让wifi芯片连接到路由器的。具体实现原理参考:智能硬件接入云平台解决方案


微信硬件平台

微信硬件平台里边有一个叫做airkiss 技术,下面的两个产品都支持这个技术,对于实现智能网络配置功能,它是一个相对完美的平台和方案.详细的学习请自行进平台官网看文档.


hi-fly系列wifi芯片(笔者的项目就是用这个芯片) esp8266 wifi 芯片

hi-fly和esp系列芯片看起来大同小异,知识esp8266芯片实现智能网络配置比较麻烦,它里边只有实现源码,并没有封装成java库来使用,hi-fly产品就产商提供了一个java库,后边着重介绍怎么在qt里边使用这个库.

wifi芯片学习:

如果有官方评估版可以完全参考HF-LPT220wifi模块评估版使用指南学习搭建完整的调试环境,如果没有的话请参考HF-LPT220wifi模块用户手册这份文档做一个调试板子。

这个板子是自己做的,使用的时HF-LPT220芯片。电路设计按情况,留出串口和复位键,就可以当作官方评估版使用了。

前期硬件开发要了解wifi芯片的操作:

监听wifi芯片串口传来的数据

了解透传模式

了解串口数据传输和wifi串口控制命令。

软件实现smartconfig

就拿我的项目来作分析:

我们在创建qt android项目的时候要把hi-flying 提供的hiflying-iots-android-smartlink7.0.2.jar 拷贝到android/libs目录下

然后写给c++调用的java接口类:
SmartLinkManager.java

package com.tommego;

//hifly smart link libs
import com.hiflying.smartlink.ISmartLinker;
import com.hiflying.smartlink.OnSmartLinkListener;
import com.hiflying.smartlink.SmartLinkedModule;
import com.hiflying.smartlink.v3.SnifferSmartLinker;
import com.hiflying.smartlink.v7.MulticastSmartLinker;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

//屏幕像素密度
import android.util.DisplayMetrics;

public class SmartLinkManager extends org.qtproject.qt5.android.bindings.QtActivity implements OnSmartLinkListener{

    private static SmartLinkManager m_instance;


    //smart link
    protected static ISmartLinker mSnifferSmartLinker;
    private static boolean  mIsConncting = false;
    protected static Handler mViewHandler = new Handler();
//    protected static ProgressDialog mWaitingDialog;
    private static BroadcastReceiver mWifiChangedReceiver;
    private static String mSSID;


    public SmartLinkManager(){
        m_instance = this;

        //smart linker initialization
        mSnifferSmartLinker = MulticastSmartLinker.getInstance();
    }

    public static void startSmartLink(String ssid,String pwd){
        // TODO Auto-generated method stub
        if(!mIsConncting){

                //设置要配置的ssid 和pswd
                try {

                        mViewHandler.post(new Runnable() {

                            @Override
                            public void run() {
                                    // TODO Auto-generated method stub

                                    Toast.makeText(m_instance.getApplicationContext(), "正在后台配置wifi,请稍后",
                                                    Toast.LENGTH_LONG).show();
                            }
                        });

                        mSnifferSmartLinker.setOnSmartLinkListener(m_instance);

//                        showDialog();
                        //开始 smartLink
                        mSnifferSmartLinker.start(m_instance.getApplicationContext(), pwd.trim(),
                                        ssid.trim());
                        mIsConncting = true;
//                        mWaitingDialog.show();
                } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
        }
    }

    public static void stopSmartLink(){
        mSnifferSmartLinker.stop();
        mIsConncting = false;
//        closeDialog();
    }


    public static String getSSID(){
        WifiManager conMan = (WifiManager) m_instance.getSystemService(Context.WIFI_SERVICE);
        return conMan.getConnectionInfo().getSSID();
    }

    @Override
    public void onLinked(final SmartLinkedModule module) {
            // TODO Auto-generated method stub

//            Log.w(TAG, "onLinked");
            mViewHandler.post(new Runnable() {

                    @Override
                    public void run() {
                            Toast.makeText(m_instance.getApplicationContext(), "发现新wifi模块"+
                             "
 mac:"+module.getMac()+ "
 ip:"+module.getModuleIP(),
                                            Toast.LENGTH_SHORT).show();
                    }
            });
    }

    @Override
    public void onCompleted() {

//            Log.w(TAG, "onCompleted");
            mViewHandler.post(new Runnable() {

                    @Override
                    public void run() {
                            // TODO Auto-generated method stub
                            Toast.makeText(m_instance.getApplicationContext(), "智能配置完成!",
                                            Toast.LENGTH_SHORT).show();
//                            mWaitingDialog.dismiss();
                            mIsConncting = false;
//                            closeDialog();
                    }
            });
    }

    @Override
    public void onTimeOut() {

//            Log.w(TAG, "onTimeOut");
            mViewHandler.post(new Runnable() {

                    @Override
                    public void run() {
                            // TODO Auto-generated method stub
                            Toast.makeText(m_instance.getApplicationContext(), "配置超时!",
                                            Toast.LENGTH_SHORT).show();
//                            mWaitingDialog.dismiss();
                            mIsConncting = false;
                    }
            });
    }

    //获取屏幕像素密度
    public static double getDentisy(){
        DisplayMetrics metrics=new DisplayMetrics();
        m_instance.getWindowManager().getDefaultDisplay().getMetrics(metrics);
        return metrics.density;
    }


//    public static native void showDialog();
//    public static native void closeDialog();





}

然后c++ 就可以调度这个库了:
wifidevicemanager.h

#ifndef WIFIDEVICEMANAGER_H
#define WIFIDEVICEMANAGER_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

struct WifiDevice{
    QString ip,mac;
};

class WifiDeviceManager : public QObject
{
    Q_OBJECT
public:
    explicit WifiDeviceManager(QObject *parent = 0);
    //device list
    Q_PROPERTY(QString deviceList READ deviceList NOTIFY deviceListChanged)
    QString deviceList();
    Q_PROPERTY(QString revDatas READ revDatas NOTIFY revDatasChanged)
    QString revDatas();
    Q_PROPERTY(QString revTcpDatas READ revTcpDatas NOTIFY revTcpDatasChanged)
    QString revTcpDatas();

    //tcp socket properties
    Q_PROPERTY(QString tcpState READ tcpState NOTIFY tcpStateChanged)
    QString tcpState();
    //tcp con
    Q_INVOKABLE void connectTcp(QString ip);
    Q_INVOKABLE void sendDatasTcp(QString data);

    //smart config
    Q_INVOKABLE void startSmartLink(QString SSID,QString pwd);
    Q_PROPERTY(QString ssID READ ssID NOTIFY ssIDChanged)
    QString ssID(){
        return mssid;
    }

    //send udp datas
    Q_INVOKABLE void searchDevice();

    //send datas
    Q_INVOKABLE void sendDatas(QString datas);
    Q_INVOKABLE void sendDatas(QString datas,int port);
    Q_INVOKABLE void setDAddress(QString ad){
        this->dAddress=ad;
    }

signals:
    void deviceListChanged();
    void ssIDChanged();
    void revDatasChanged();
    void tcpStateChanged();
    void revTcpDatasChanged();

public slots:
    void readDatas();
    void readTcpDatas();

private:
    QString             myAddress;

    QList   mdeviceList;
    QUdpSocket          *socket;
    QTcpSocket          *tcpSocket;

    int                 port;

    QString             mssid;
    QString             mrevDatas;
    QString             mRevTcpDatas;
    QString             dAddress;
    QString             m_tcpState;

};

#endif // WIFIDEVICEMANAGER_H

wifidevicemanager.cpp

#include "wifidevicemanager.h"

WifiDeviceManager::WifiDeviceManager(QObject *parent) : QObject(parent)
{
    //init socket
    port=48899;
    socket=new QUdpSocket(this);
    socket->bind(QHostAddress::Broadcast,port);

    tcpSocket=new QTcpSocket();
    tcpSocket->bind (8899);
    connect(socket,SIGNAL(readyRead()),this,SLOT(readDatas()));
    connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readTcpDatas()));

    this->m_tcpState="unConnected";
    tcpStateChanged();

    //init ssid
    QAndroidJniObject str=QAndroidJniObject::callStaticObjectMethod("com/tommego/SmartLinkManager",
                                                                             "getSSID",
                                                                             "()Ljava/lang/String;");
    this->mssid=str.toString();
    ssIDChanged();

    //init address
    QHostAddress address;
    myAddress=address.toString();
}

QString WifiDeviceManager::deviceList(){
    return "";
}
void WifiDeviceManager::readDatas(){
    socket->waitForReadyRead(100);
//    qDebug()<<"&&&&&&&&&&&&&&&&&&&&&datas:"<readAll();
    this->mrevDatas=socket->readAll();
    while (socket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(socket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
//        currentDatas="aa";
//        mdataChanged();

        socket->readDatagram(datagram.data(), datagram.size(),
                                &sender, &senderPort);
        mrevDatas=datagram.data();
        revDatasChanged();
//        mdataChanged();
    }
    revDatasChanged();


}

void WifiDeviceManager::startSmartLink(QString SSID, QString pwd){
    QAndroidJniObject cssid=QAndroidJniObject::fromString(SSID);
    QAndroidJniObject cpwd=QAndroidJniObject::fromString(pwd);
    QAndroidJniObject::callStaticMethod("com/tommego/SmartLinkManager",
                                                                                 "startSmartLink",
                                                                                 "(Ljava/lang/String;Ljava/lang/String;)V",
                                                     cssid.object(),
                                                     cpwd.object());

}

void WifiDeviceManager::searchDevice(){
    QByteArray cmd;
    cmd.append("HF-A11ASSISTHREAD");
    QString address="192.168.0.255";
    QHostAddress ad(address);
    socket->writeDatagram(cmd,ad,port);
//    socket->writeDatagram(cmd,"192.168.1.255",port);
}
void WifiDeviceManager::sendDatas(QString datas){
    QByteArray cmd;
    cmd.append(datas);
    QString address="192.168.0.255";
    QHostAddress ad(address);
    socket->writeDatagram(cmd,ad,port);
//    socket->writeDatagram(cmd,"192.168.1.255",port);
}
QString WifiDeviceManager::revDatas(){
    return this->mrevDatas;
}
void WifiDeviceManager::sendDatas(QString datas, int mport){
    QByteArray cmd;
    cmd.append(datas);
    QString address="192.168.0.255";
    QHostAddress ad(address);
    socket->writeDatagram(cmd,ad,mport);
}

QString WifiDeviceManager::tcpState (){
    return this->m_tcpState;
}
void WifiDeviceManager::connectTcp (QString ip){
    if(tcpSocket->state()==QTcpSocket::ConnectedState)
        return ;
    QHostAddress address(ip);
    tcpSocket->connectToHost(address,8899);
    if(tcpSocket->state()==QTcpSocket::ConnectedState)
        this->m_tcpState="connected";
    else
        this->m_tcpState="unConnected";
    tcpStateChanged();


}

void WifiDeviceManager::sendDatasTcp (QString data){
    if(tcpSocket->state()==QTcpSocket::ConnectedState){
        QByteArray mdata;
        mdata.append(data);
        this->tcpSocket->write (mdata);
    }
}

void WifiDeviceManager::readTcpDatas(){
    tcpSocket->waitForReadyRead(500);
    mRevTcpDatas=tcpSocket->readAll();
    revTcpDatasChanged();
}
QString WifiDeviceManager::revTcpDatas(){
    return this->mRevTcpDatas;
}

这里是调用smartlink库核心实现部分,在实现这个功能过程,遇到了很多java接口的坑.不过还好,整个源码实现完美在qt中跑起来了.这时候我们的app,就可以通过smartlink实现对为初始化的wifi设备进行一键配置网络了!(就算是有几十台wifi设备,都能直接在app中一键配置并且搜到wifi设备哈哈!)
功能截图:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/13525.html

相关文章

  • 2021爱智先行者——EdgerOS Spirit 1深度使用体验与EdgerOS应用开发实践

    摘要:是下一代面向物联网和边缘计算的智能操作系统,可广泛应用于面向个人家庭和行业的物联网产品和解决方案,有效降低开发门槛缩短开发周期。 一、前言 ① 智能边缘计算操作系统...

    spacewander 评论0 收藏0
  • 爆肝一周,用Python在物联网设备上写了个智能语音助手

    摘要:背景介绍智能语音助手作为物联网领域的一个重要生态成员,是一种全新的交互方式,它能够解放双手,随时提供服务,无须借助任何按键。学完该案例让你对智能语音助手有一个全新的认识。快来打造你的智能语音助手吧 1. 背景介绍 智能语音助手作为物联网领域的一个重要生态成员,是一种全新的交互方式,它能够解...

    I_Am 评论0 收藏0
  • 边缘计算的七项核心技术

    摘要:与云计算中心不同,广域网的网络情况更为复杂,带宽可能存在一定的限制因此,如何从设备层支持服务的快速配置,是边缘计算中的一个核心问题。边缘计算可汲取云计算发展的经验,研究适合边缘计算场景下的隔离技术。 作者:施巍松团队(张星洲、王一帆、张庆阳) 计算模型的创新带来的是技术的升级换代,而边缘计算的迅速发展也得益于技术的进步。本节总结了推动边缘计算发展的7项核心技术,它们包括网络、隔离技术、...

    leanote 评论0 收藏0
  • 2021爱智先行者—设备到来之前的先导篇

    摘要:一个物联网操作系统是否能够流行,其与其他设备的友好连接性会是一个非常重要的衡量指标。内置了众多安全存储与安全通讯技术,能够鉴别可信硬件,识别并拒绝未经授权的设备或用户访问系统应用和数据,把安全措施不足的普通物联网设备置于强大的保护之下。 ...

    Warren 评论0 收藏0
  • 首次披露!阿里线下智能方案进化史

    摘要:前言阿里巴巴机器智能实验室线下智能团队从年底开始涉及线下智能领域,从算法工程产品化业务落地多个方面入手,与合作伙伴们一起取得了一些小小的成绩。目前,该套工具作为推荐的量化工具广泛应用在阿里集团内多个线下业务场景中。 showImg(https://segmentfault.com/img/remote/1460000019246850); 阿里妹导读:AI 技术已经从互联网走向零售、...

    keelii 评论0 收藏0

发表评论

0条评论

kuangcaibao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<