我们提供以下智慧化平台一站式采购:

智慧社区、社区治理
智慧物业、物业管理
智慧化工园区
智慧园区
智慧园林、智慧公园
考试培训
养老、医养一体
垃圾分类监管
垃圾分类智能称及平台
智慧路灯硬件及平台
智慧消防队务管理
资产管理
供应链管理
ERP
智慧校园
智慧工地
智慧建筑云监管平台、智慧住建
工业互联网
智慧食品安全云
智慧商场营销平台
充电桩平台
智慧健康
志愿者
政务、一网通办
智慧水利
智慧农业
无人售货机及平台
智慧环保、环境监测
智慧停车
智慧物流平台
巡查系统
场馆管理系统
智能柜
文档管理、数字档案管理
商家收款、营销平台
智慧食堂
智慧井盖、垃圾房
各类机器人
智慧消防

之前买了两个贝壳物联的WIFI继电器,自己改造成了智能插座,贝壳物联可以轻松接入天猫精灵来语言控制 ,但不能连入米家,用小爱来控制,并实现与米家智能设备的场景联动,于是研究了一番,实现了目标。

解决方案:采用巴法云MQTT+服务器端PYTHON脚本的方式。

巴法云MQTT可以轻松接入天猫、小爱、HOMEASSISTANT,很赞的平台。我们在巴法云创建一个MQTT主题 命名为 dataideng002,昵称为大台灯,然后用PYTHON来订阅MQTT主题 ,在收到消息后,处理并转发指令到贝壳物联的TCP服务器。代码很简单,参考如下:

需要注意的是,贝壳物联需要用一个不在线的设备进行登录,然后用指令控制在线的设备。音箱发送的开关指令分别是on,off,需要转换成贝壳物联的play,stop。

 #!/usr/bin/python
# -*- coding:utf-8 -*

import sys
import importlib
importlib.reload(sys)


import paho.mqtt.client as mqtt
import socket
import time
import json

#bemfa
HOST = "bemfa.com"
PORT = 9501
client_id = "你的ID"

#bigiot
#must be modified===
DEVICEID='21910'
APIKEY='85727e700'
#modify end=========
host="www.bigiot.net"
port=8181

#bemfa
#连接并订阅
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe("dataideng002")         # 订阅消息

#消息接收
def on_message(client, userdata, msg):
    #转发到beike
    message = str(msg.payload.decode('utf-8'))
    if message == "on":
        message = "play"
    if message == "off":
        message = "stop"    
    if msg.topic == "dataideng002":
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(2)

        # connect to remote host
        try:
            s.connect((host, port))
        except:
            print ('Unable to connect')

        print ('Connected to remote host. Start sending messages')
        checkinBytes = bytes('{\"M\":\"checkin\",\"ID\":\"27716\",\"K\":\"1111111\"}\n', encoding='utf8')
        s.sendall(checkinBytes)
        time.sleep(1)
        #play stop
        checkinBytes = bytes('{\"M\":\"say\",\"ID\":\"D21910\",\"C\":\"' + message + '\"}\n', encoding='utf8')
        s.sendall(checkinBytes)
        time.sleep(1)
        s.close()


#订阅成功
def on_subscribe(client, userdata, mid, granted_qos):
    print("On Subscribed: qos = %d" % granted_qos)

# 失去连接
def on_disconnect(client, userdata, rc):
    if rc != 0:
        print("Unexpected disconnection %s" % rc)

#bemfa
client = mqtt.Client(client_id)
client.username_pw_set("userName", "passwd")
client.on_connect = on_connect
client.on_message = on_message
client.on_subscribe = on_subscribe
client.on_disconnect = on_disconnect
client.connect(HOST, PORT, 60)
client.loop_forever()

#bigiot
#connect bigiot

另外的解决方案,1.购买现成的米家断路器、插座等产品 2.自己编写WIFI模块的程序不连入贝壳物联,直接用MQTT对接巴法云,就不需要在服务器上常驻一个中间PYTHON脚本。可以在HOMEASSISTANT中建立MQTT LIGHT实体,在HOMEASSISTANT中实现控制、联动等更高级更灵活的应用。

关于米家联动

现在已经支持在米家app里通过“第三方设备”功能巴法云来接入,可以通过小爱AI音箱声控开关灯,但是,因为这个是第三方设备,无法物理接入米家app,没办法与智能锁联动,实现晚上进门自动开灯。
办法总比困难多,小爱音箱新增的“自定义指令”使得梦想成为现实,可以完美把第三方设备接入米家App实现联动,具体如下:
1、利用小爱音箱的的“自定义指令”‘’功能实现“曲线救国”
2、智能场景如下:

条件:

1)智能门锁正常打开
2)多功能网关亮度暗

执行:

1)小爱音箱自定义指令:打开大台灯
原理解析:
“自定义指令”的效果和对着小爱AI音箱说是完全一致的,因此,通过这这个“自定义指令”功能,可以实现对任何第三方设备的联动。这个功能可以说是一个“万金油”,可以把所有第三方设备都接入到米家app。

//    导入图片  参数 暂存目录  保存目录   分类
    public function importpro()
    {
        $save_path = DOC_PATH;

        exit();
        set_time_limit(0);
        // 定义主存储路径


        //windows下目录有中文需要转码
        $source = iconv("UTF-8",'gb2312','E:\web\centuryceramic\新网站--2014年以前图片');
        $dest = ROOT_PATH . '';
        $class = '6';


        foreach (file_list($source) as $file)
        {
            //是否为图片文件
            if(is_image($source . '\\'.$file))
            {
                $ico =   STATIC_DIR . '/upload' .'/image/product/' . time() . mt_rand(100000, 999999) . '.jpg';
                $file_path = $save_path . $ico;
                //缩放并复制图片
                resize_img($source . '\\'.$file,$file_path,500,500);
                //插入产品记录
                unset($info);
                $info = [
                    'title' => 'ceramic mug ' . $this->i,
                    'ico' => $ico,
                    'class' => $class,
                ];
                $this->save_pro($info);
            }


        }


    }


    //保存产品

    private function save_pro($info){
        //产品信息结构
        $data = json_decode('{"acode":"cn","scode":"16","subscode":"","title":"\u6807\u9898","titlecolor":"#333333","subtitle":"","filename":"","author":"admin","source":"\u672c\u7ad9","outlink":"","date":"2018-12-30 10:45:46","ico":"\/static\/upload\/image\/20181230\/1546137994102175.png","pics":"\/static\/upload\/image\/20181230\/1546138005227320.png,\/static\/upload\/image\/20181230\/1546138006814526.png","content":"<p>\u5185\u5bb9<\/p>","enclosure":"","keywords":"","description":"\u5185\u5bb9","sorting":255,"status":"1","istop":0,"isrecommend":0,"isheadline":0,"visits":0,"likes":0,"oppose":0,"create_user":"admin","update_user":"admin"}',true);
        //var_dump($info);die();

        $data['scode'] = $info['class'];
        $data['pics'] = "";
        $data['ico'] = $info['ico'];

        //重置这些内容 以免下一个

        $data['title'] =  $info['title'];
        $data['content'] = $info['title'];
        $data['description'] = "";
        $data['date'] = date('Y-m-d H:i:s');
        //var_dump($data);
        //exit();
        if (! ! $id = $this->model->addContent($data)) {
            //添加扩展内容 addContentExt

            unset($ext);
            $ext = [
                'contentid' => $id,
                'ext_ext_country' => 'china',
                'ext_color' => $this->i,//编号
                'ext_type' => 'CenturyCeramic',
            ];

            if (! $this->model->addContentExt($ext)) {
                $this->model->delContent($id);
                echo "导入失败" . $info['title']  .   '<br />';
            }
            else{
                echo "成功导入数据" . $info['title']  .   '<br />';
                $this->i += 1;//编号累加
            }


        }

    }

//    导入图片  参数 暂存目录  保存目录   分类
    public function importpro()
    {
        $save_path = DOC_PATH;

        exit();
        set_time_limit(0);
        // 定义主存储路径


        //windows下目录有中文需要转码
        $source = iconv("UTF-8",'gb2312','E:\web\centuryceramic\新网站--2014年以前图片');
        $dest = ROOT_PATH . '';
        $class = '6';


        foreach (file_list($source) as $file)
        {
            //是否为图片文件
            if(is_image($source . '\\'.$file))
            {
                $ico =   STATIC_DIR . '/upload' .'/image/product/' . time() . mt_rand(100000, 999999) . '.jpg';
                $file_path = $save_path . $ico;
                //缩放并复制图片
                resize_img($source . '\\'.$file,$file_path,500,500);
                //插入产品记录
                unset($info);
                $info = [
                    'title' => 'ceramic mug ' . $this->i,
                    'ico' => $ico,
                    'class' => $class,
                ];
                $this->save_pro($info);
            }


        }


    }


    //保存产品

    private function save_pro($info){
        //产品信息结构
        $data = json_decode('{"acode":"cn","scode":"16","subscode":"","title":"\u6807\u9898","titlecolor":"#333333","subtitle":"","filename":"","author":"admin","source":"\u672c\u7ad9","outlink":"","date":"2018-12-30 10:45:46","ico":"\/static\/upload\/image\/20181230\/1546137994102175.png","pics":"\/static\/upload\/image\/20181230\/1546138005227320.png,\/static\/upload\/image\/20181230\/1546138006814526.png","content":"<p>\u5185\u5bb9<\/p>","enclosure":"","keywords":"","description":"\u5185\u5bb9","sorting":255,"status":"1","istop":0,"isrecommend":0,"isheadline":0,"visits":0,"likes":0,"oppose":0,"create_user":"admin","update_user":"admin"}',true);
        //var_dump($info);die();

        $data['scode'] = $info['class'];
        $data['pics'] = "";
        $data['ico'] = $info['ico'];

        //重置这些内容 以免下一个

        $data['title'] =  $info['title'];
        $data['content'] = $info['title'];
        $data['description'] = "";
        $data['date'] = date('Y-m-d H:i:s');
        //var_dump($data);
        //exit();
        if (! ! $id = $this->model->addContent($data)) {
            //添加扩展内容 addContentExt

            unset($ext);
            $ext = [
                'contentid' => $id,
                'ext_ext_country' => 'china',
                'ext_color' => $this->i,//编号
                'ext_type' => 'CenturyCeramic',
            ];

            if (! $this->model->addContentExt($ext)) {
                $this->model->delContent($id);
                echo "导入失败" . $info['title']  .   '<br />';
            }
            else{
                echo "成功导入数据" . $info['title']  .   '<br />';
                $this->i += 1;//编号累加
            }


        }

    }

物联网云平台一般都带有API接口可以实现设备及数据的自有服务器的存储以及支持对自身业务实现的更好扩展,笔者前段时间接触比较多的是有人云、TLINK,以及阿里云,ONENET,通过TASKPHP实现TLINK平台数据的抓取,定时任务,以前有人云的数据抓取、业务扩展。

  1. TASKPHP的composer安装
  2. command.php的修改
  3. taskphp的任务配置,crontab表达式的编写
  4. 具体任务操作逻辑的编写
  5. php think start 定时任务的启动

注意事项:

  1. worker_memory任务进程的最大内存配置,如果抓取任务中数据量比较大需要配置比较大的内存,不然会出错
  2. 采用supervisor来管理进程,重启容易有重复的worker进程,造成数据抓取的重复
  3. 后台任务运行 nohup php think start getdata &
  4. API接口TOKEN的获取、超时重取等
  5. 在TP5的command中可以直接采用TP的数据库操作等功能
  6. 采用了tp5的chunk进行分批处理
  7. HTTP请求采用了 Guzze库,PHP还是有不少好用的库的
  8. 执行php think start出错提示 No such file or directory

    原因:该脚本文件格式是 dos 格式 而非 unix 格式。 可以用 vim 查看或修改文件格式,命令如下 vim ./file :set
    ff // 查看 :set ff=unix // 设置文件格式为 unix

  9. fopen要开启