精华内容
下载资源
问答
  • 适用于BK7231T的Tuya IoTOS嵌入式Wi-Fi和BLE SDK | 概述 Tuya IoTOS由Tuya Smart独立开发,是全球唯一的IoT操作系统,涵盖所有级别的IoT传感,中断,网络,平台和应用程序。 受益于Tuya Smart在物联网行业的积累,...
  • 多媒体SDK是Tuya IoTOS的一部分,用于开发嵌入式设备,例如IP摄像机(IPC),网络视频录像机(NVR),数字视频录像机(DVR),门铃和泛光灯。 包含C标准库,相关的头文件和文档以支持Linux,LiteOS和实时操作系统...
  • Tuya IoTOS嵌入式演示WiFi和BLE智能灌溉器 | 介绍 该演示基于Tuya Smart Cloud平台,Tuya Smart APP,IoTOS嵌入式WiFi&Ble SDK,使用Tuya WiFi / WiFi + BLE系列模块快速设置智能土壤湿度控制器,以通过手机和自动...
  • Tuya IoTOS嵌入演示WiFi和BLE光强度传感器 | 介绍 该演示基于Tuya Smart Cloud平台,Tuya Smart APP,IoTOS嵌入式WiFi&Ble SDK,使用Tuya WiFi / WiFi + BLE系列模块快速设置光传感器并实现对手机光强度数据的远程...
  • Tuya IoTOS嵌入演示WiFi和BLE Smart辅助照明 | 介绍 该演示基于Tuya Smart Cloud平台,Tuya Smart APP,IoTOS嵌入式WiFi&Ble SDK,使用Tuya WiFi / WiFi + BLE系列模块快速设置自动光补给控制器,以实现通过手机和...
  • Tuya IoTOS嵌入式演示WiFi和BLE龙头模块 | 介绍 该演示基于Tuya Smart Cloud平台,Tuya Smart APP,IoTOS嵌入式WiFi&Ble SDK,使用Tuya WiFi / WiFi + BLE系列模块快速设置了爆震模块演示,可以检测爆震信号并在...
  • Tuya IoTOS嵌入式演示WiFi和BLE激光发射器 | 介绍 该演示基于Tuya Smart Cloud平台,Tuya Smart App,IoTOS嵌入式WiFi&Ble SDK,使用Tuya WiFi / WiFi + BLE系列模块快速设置激光发射器演示,您可以通过移动应用...
  • Tuya IoTOS嵌入式演示WiFi和BLE温湿度传感器 | 介绍 该演示基于Toodle Smart Cloud平台,Tuya Smart APP,IoTOS嵌入式WiFi&Ble SDK,使用Tuya WiFi / WiFi + BLE系列模块快速构建温度和湿度传感器,以实现对手机...
  • IOT OS 浅谈

    2020-12-16 11:55:06
    移动开源Iot Os,引发对比现有Iot Os情况。 主要从Iot Os中进行总结,对比。从以下几个维度进行:厂商、Os内核、支持内核、社区活跃度。 并在最后罗列一下,现有物联网协议的对比。 国内IOT OS 主要介绍RT-Thread、...

    移动开源Iot Os,引发对比现有Iot Os情况。
    主要从Iot Os中进行总结,对比。从以下几个维度进行:厂商、Os内核、支持内核、社区活跃度。
    并在最后罗列一下,现有物联网协议的对比。
    在这里插入图片描述

    国内IOT OS
    主要介绍RT-Thread、TencentOS-tiny、Huawei LiteOS,其中Huawei LiteOS目前star不高,不做详细介绍。移动的也是类似,但目前看,社区还没有建立起来。
    tiny目前star最多,rt-thread的社区目前看非常活跃。
    一、 RT-Thread https://gitee.com/rtthread/rt-thread
    RT-Thread诞生于2006年,是一款以开源、中立、社区化发展起来的物联网操作系统。社区活跃度较高,且相关网站较多(https://www.rt-thread.org/)。
    RT-Thread有完整版和Nano版,对于资源受限的微控制器(MCU)系统,可通过简单易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 内核版本;而相对资源丰富的物联网设备,可使用RT-Thread完整版,通过在线的软件包管理工具,配合系统配置工具实现直观快速的模块化裁剪,并且可以无缝地导入丰富的软件功能包,实现类似 Android 的图形界面及触摸滑动效果、智能语音交互效果等复杂功能。
    框架如下:
    在这里插入图片描述

    二、 TencentOS-tiny https://github.com/Tencent/TencentOS-tiny
    TencentOS tiny 提供精简的 RTOS 内核,内核组件可裁剪可配置,可快速移植到多种主流 MCU (如 STM32 全系列)及模组芯片上。而且,基于 RTOS 内核提供了丰富的物联网组件,内部集成主流物联网协议栈(如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等),可助力物联网终端设备及业务快速接入腾讯云物联网平台。
    框架图如下:

    三、 Huawei LiteOS https://gitee.com/LiteOS/LiteOS?_from=gitee_search
    Huawei LiteOS操作系统,包括: 任务管理、内存管理、时间管理、通信机制、中断管理、队列管理、事件管理、定时器、异常管理等操作系统基础组件,可以单独运行。
    框架图:
    在这里插入图片描述

    综合对比:
    在这里插入图片描述

    国外IOT总体对比
    在这里插入图片描述

    分别介绍
    一、 Brillo
    地址:https://link.zhihu.com/?target=https%3A//developers.google.com/brillo/
    Brillo基于Android,跑在Linux上。它把Android上关于图形、JVM及Framework裁减掉。保留了C/C++运行环境,Binder IPC,SSL等网络安全必须组件。Brillo可以在资源较少的MPU上跑(35MB内存)。
    框架图如下:
    在这里插入图片描述

    二、 mbedOS
    地址:https://link.zhihu.com/?target=https%3A//www.mbed.com/en
    mbed是ARM自己建立的IoT解决方案平台,分成三大部分mbed Cloud、mbed Device Connector、mbed Client。
    mbedOS既是基于RTOS内核,并提供各种ARM SoC硬件平台驱动和BSP的操作系统,在此之上,实现整个mbed Client库。在PAN的物联区域内,设备与设备的通讯都可以使用mbedOS提供的方案来解决,它支持NFC,RFID,BLE,6LowPAN甚至是Thread。在设备与云端的通讯上,mbedOS既支持以太网,WiFi,也支持3G。
    框架图:
    在这里插入图片描述

    三、 RIOT
    地址:https://link.zhihu.com/?target=https%3A//riot-os.org/
    RIOT是面向开发者的,开源的,适合物联网的操作系统。它的背后没有某个公司的支持,而完全是由社区驱动。
    RIOT最早是由柏林自由大学开发的,目前完全由社区维护,社区活跃程度一般。
    RIOT由微内核(microkernel)实现,所有的系统服务包括时钟、网络协议栈、网络服务等,都是通过创建独立的线程来实现。RIOT中最关键的是GNRC(Generic network stack)网络协议栈,它实现了从MAC层一直到传输层的各种协议,如6LowPan,IPv4/v6,RPL,TCP/UDP。并且这些不同的协议栈之间通过netapi统一接口开放给用户。
    框架图:
    在这里插入图片描述

    四、 Contiki
    地址:https://link.zhihu.com/?target=http%3A//www.contiki-os.org/
    Contiki是为智能城市而生,支持的平台有限,基本是内部集成CC24xx/25xx,MC1322x之类Radio的SensorTag平台(https://www.ti.com.cn/tool/cn/SENSORTAG-SW),或者一个很小的MCU加上这些Radio模块的平台。从它所支持的平台也能看出,Contiki更加专注于小型传感器节点。它更关注与PAN内的节点通讯,当然他也有传统的IPv4/v6,TCP/UDP支持,使得利用CoAP可以用来和云端通讯。
    Contiki也是个微内核(microkernel),所有的系统服务都是通过启线程完成,Protothreads线程整合了线程间事件通讯,使得编写系统服务非常容易。驱动程序方面,Contiki没有统一的驱动程序框架,驱动都是各家MCU自带开发包提供,这样的好处是能够保证生成的二进制代码够小。
    五、 Zephyr
    地址:https://link.zhihu.com/?target=http%3A//www.zephyrproject.org/
    Zephyr居然是Linux基金会的合作项目。应该是由INTEL将WindRiver的商用操作系统WindRiver Rocket部分开源后诞生的项目(今年才诞生)。目前可用资料不多,而且支持的硬件平台较少,ARM的平台没几个。
    六、 Nuttx
    地址:https://link.zhihu.com/?target=http%3A//www.nuttx.org/
    Nuttx,实时操作系统,POSIX接口支持,Loadable内核模块支持,BSD socket,MMU支持。

    展开全文
  • 登录平台:IOTOS®爱投斯物联中台 账号:iotos_test 密码:iotos123 代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com) 1、前言 MQTT(消息队列遥测传输)是ISO标准(ISO/IEC ...

    本文章为原创,转载请注明出处!

    登录平台:IOTOS®爱投斯物联中台

    账号:iotos_test    密码:iotos123

    代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com)

    目录

    1、前言

    2、驱动目的

    3、驱动代码

    4、驱动解析

    4.1、从设备实例上获取配置的参数

     4.2、配置mqtt连接参数:

    4.3、获取空开当前状态

     4.4、下发按钮控制空开状况


    1、前言

    MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 

    MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。

    2、驱动目的

    在中台控制智能空开的开启和关闭

    3、驱动代码

    #!coding:utf8
    import sys
    
    sys.path.append("..")
    from driver import *
    import json
    import time
    import paho.mqtt.client as mqtt
    
    reload(sys)
    sys.setdefaultencoding('utf8')
    
    
    
    def on_connect(client, userdata, flags, rc):
        print("Connected with result code " + str(rc))
        client.subscribe("/wf/wifiswitch/server")  # 订阅消息
    
    
    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)
    
    
    class TemplateDriver(IOTOSDriverI):
        def on_message(self, client, userdata, msg):
            print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
            a = json.loads(msg.payload)
            if str(a[u'act']) == str('allmsg'):
                sn = a[u'sw'][u'sw']
                self.setValue(u'open',sn)
                sn1 = a[u'sw2'][u'sw']
                self.setValue(u'open2', sn1)
    
        def InitComm(self, attrs):
            self.online(True)
            self.setPauseCollect(False)
            self.setCollectingOneCircle(False)
            self.client = mqtt.Client()
            self.air_host = self.sysAttrs['config']['param']['host']
            self.air_port = self.sysAttrs['config']['param']['port']
            self.air_username = self.sysAttrs['config']['param']['username']
            self.air_password = self.sysAttrs['config']['param']['password']
            self.air_id = self.sysAttrs['config']['param']['id']
            self.air_value = self.sysAttrs['config']['param']['value']
            # 注册事件
            self.client.on_connect = on_connect
            self.client.on_message = self.on_message
            self.client.on_subscribe = on_subscribe
            self.client.on_disconnect = on_disconnect
            self.client.username_pw_set(username=self.air_username, password=self.air_password)
            # 连接到服务器
            self.client.connect(host=self.air_host, port=self.air_port, keepalive=60)
            self.client.loop_start()
    
        def Collecting(self, dataId):
            sn = ''
            sn1 = ''
            self.client.publish(self.air_id, payload="act=getallmsg&mode=0", qos=0)  # 发送消息
            # self.setValue(u'open', 0)
            for key, value in self.data2attrs.items():  # 拿出数据点的键和值
                if "private" in value['config']['param']:
                    # 在private中识别开关控制的反控标签
                    if value['config']['param']['private'] == "open":
                        self.key_s = key  # 将下发数据点的dataid保存到self中,后续Event_setData中判断下发数据点时需要用到
                        self.debug(self.key_s)
                        if "memoryvalue" not in self.data2attrs[key]:
                            self.setValue(u'open', sn)
                        else:
                            self.setValue(u'open', self.data2attrs[key]["memoryvalue"])
                    if value['config']['param']['private'] == "open2":
                        self.key_s1 = key  # 将下发数据点的dataid保存到self中,后续Event_setData中判断下发数据点时需要用到
                        self.debug(self.key_s1)
                        if "memoryvalue" not in self.data2attrs[key]:
                            self.setValue(u'open2', sn1)
                        else:
                            self.setValue(u'open2', self.data2attrs[key]["memoryvalue"])
    
            time.sleep(20)
            return ()
    
        def Event_setData(self, dataId, value):
            if dataId == self.key_s:
                self.setValue(u'open', value)
                data = "act=ctrlio&sw=" + str(value)
                self.client.publish(self.air_id+self.air_value, payload=data, qos=0)  # 发送消息
            if dataId == self.key_s1:
                self.setValue(u'open2', value)
                data = "act=ctrlio2&sw=" + str(value)
                self.client.publish(self.air_id+self.air_value, payload=data, qos=0)  # 发送消息
            # if dataId=="a8c3" and value==True:
            #     # self.setValue(u'data', '333333333')
            #     self.info(u"Data delivery succeeded>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>switch=1")
            # if dataId=="e8e4" and value==False:
            #     return json.dumps({'code': 10010, 'msg': '下发失败', 'data': ''})
            return json.dumps({'code': 0, 'msg': '', 'data': ''})
    

    4、驱动解析

    4.1、从设备实例上获取配置的参数

    配置参数如下:

     sdk中获取参数配置如下:

     4.2、配置mqtt连接参数:

    4.3、获取空开当前状态

    给mqtt服务器发送请求

     将请求的值发送给中台

     4.4、下发按钮控制空开状况

    先获取到当前数据点的值,存储到value中

     根据获取到的值向mqtt发送指定消息

     运行.bat文件后结果如下

     

     可以看到mqtt每20s向中台传一次数据

    当进行数据下发时,开关状况也发生了改变

    展开全文
  • 通过IoTOS嵌入式Wi-Fi和低功耗蓝牙SDK进行的Tuya环境监视器演示 | 概述 本演示介绍了如何使用Tuya IoT Platform,Tuya Smart应用以及IoTOS嵌入式Wi-Fi和Bluetooth Low Energy SDK开发环境监视器。 它使用Tuya Wi-Fi...
  • 11月4日,IOTOS创始人李儒强作为工业互联网专业人才受邀参加并担任授课讲师。 中国中车是以高端装备制造为核心、多元发展、跨国经营的高端装备系统解决方案供应商。拥有世界领先的轨道交通装备研发平台,产品技术...

     由华中科技大学主办的面向中国中车“数字化人才(技术)专题研修班”在华中科技大学开班,此次培训需历时1个月,受邀参加并担任讲师的有院校专家教授、科技企业专业人才等,旨在加强校企科学研究、人才培养、产业发展等。11月4日,IOTOS创始人李儒强作为工业互联网专业人才受邀参加并担任授课讲师。

    中国中车是以高端装备制造为核心、多元发展、跨国经营的高端装备系统解决方案供应商。拥有世界领先的轨道交通装备研发平台,产品技术性能达到世界先进水平,同时还是全球轨道交通行业少数实现产品类型全覆盖的企业,产品出口全球六大洲100多个国家和地区。参加此次培训的是来自全国各地的中高层领导。

     爱投斯[IOTOS]创始人李儒强此次培训的主题是《工业互联网与物联网中台》,包括:产业升级是时代发展主题、国家政策在主导弯道超车、工业互联网是业务模式、物联网中台是技术手段、工业和建筑引领数字化、智能制造基于数据采集、智慧城市依赖系统集成、工具化与通用化是趋势、IoT OS将支撑工业APP、工业互联网的数字化交易等内容。

     

     李儒强从多个层次的角度分析了当前工业面临的机遇和挑战,从国家政策和国际发展态势,认为产业数字化、智能化未来将是产业升级,提升工业水平实现弯道超车的关键因素;系统展示了数据采集、系统集成是智能制造、智慧城市的基础以及工具化与通用化产品是发展趋势。重点介绍了物联网中台在采集接入、数据展示、工业APP开发的一站式能力,并结合工业特点与物联网中台的实践应用进行全面介绍。

    历时三个小时的培训课结束后,中国中车研修团队对爱投斯[IOTOS]的物联网中台在工业中解决设备系统接入难问题上产生了浓厚的兴趣,就目前中国中车遇到的问题双方进行深入的讨论,并对物联网中台表示赞赏和认可。 

     感谢华中科技大学和中国中车对公司的认可,感谢大家的支持!爱投斯[IOTOS]将会一如既往的加大在产品的研发力度,为客户提供更好的产品和服务。

     

    展开全文
  • Tuya Device OS 是涂鸦独创 IoT OS 操作系统级别的端云 SDK,提供了按照业务需求选择组件,定制 SDK 的能力,是涂鸦开发者的利剑,具备轻量级、互联互通、安全传输、组件丰富、快速开发等关键能力,有效降低开发门槛...
  • Tuya IoTOS信标SDK AK80x 适用于AK80x的Tuya IoTOS Beacon SDK的演示代码。 介绍 Tuya IOT平台的蓝牙协议包括:Tuya BLE协议,SIG Mesh协议,Tuya Beacon协议。 与Tuya BLE协议和SIG Mesh协议相比,Tuya Beacon...
  • RT-Thread 小而美的 IoT OS 介绍
  • IOTOS驱动modbus_rtu从0到1对接详解

    千次阅读 2021-08-12 11:28:41
    登录平台:IOTOS®爱投斯物联中台 账号:iotos_test 密码:iotos123 代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com) 目录 前言 驱动目的 适用范围 驱动代码 驱动解析 使用...

    本文章为原创,转载请注明出处!

    登录平台:IOTOS®爱投斯物联中台

    账号:iotos_test    密码:iotos123

    代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com)

    • 前言

            Modbus协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络例如以太网)和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。

            Modbus具有两种串行传输模式:分别为ASCII和RTU。Modbus是一种单主站的主从通信模式,Modbus网络上只能有一个主站存在,主站在Modbus网络上没有地址,每个从站必须有唯一的地址,从站的地址范围为0 - 247,其中0为广播地址,从站的实际地址范围为1 - 247。

            Modbus RTU通信以主从的方式进行数据传输,在传输的过程中Modbus RTU主站是主动方,即主站发送数据请求报文到从站,Modbus RTU从站返回响应报文。


    • 驱动目的

            modbus RTU 该驱动是将中台(爱投斯物联中台)作为服务端(上位机)向客户端(下位机)/modbus 485通讯的前端设备发送询问帧,客户端(下位机)/modbus 485通讯的前端设备接收到询问帧并返回应答帧给到服务端(上位机)进行解析工作并展示数据


    • 适用范围

    凡是走标准的modbus_rtu协议的设备,例如烟感、光感、PLC等,需要注意的是,若客户端(下位机)/modbus 485通讯的前端设备只有485/232 等的串口通讯不具备上网功能,需增加一个外接模块(如485 转4g /485 转wifi 模块)与服务器(上位机进行网络通讯)。使用者或用户可在生产生活中使用串口通讯测试软件测试设备是否通讯正常。

    • 使用示例

    • 以光感传感器(威海晶合数字矿山技术有限公司的光照传感器)为示例进行演示

    设备信息

    •  首先,连接光感和485模块,光感的485线的A,B级分别连接模块的485接口AB级;其次光感的电源线连接符合光感正常运转的电源(可用变压器控制电源大小),然后模块网口连接交换机,最后分别给模块和光感通上电,具体连接方式如下图:

    设备连接

    •  进入模块的IP,进行配置,将模式改为TCP Client格式,地址改为爱投斯中台的IP地址(121.36.152.36),端口改为为被分配的端口,注册包方式改为云转发

     模块配置

    •  进入爱投斯中台,账号为iotos_test,密码为iotos123,创建网关

     

    • 填好网关名称后点击确认 

    • 创建设备示例点击【我的设备】 -> 【通信网关】 -> 【设备实例】

    createDevice1

    • 填写【设备名称】、选择刚刚创建的【模板驱动】和【通信网关】。参数tcp为中台需要开发的端口,用来与模块进行通讯,与模块配置里面的端口保持一致

    • 创建数据点,点击【我的设备】 -> 【通信网关】 -> 【设备实例】 -> 【数据点】,并在【设备实例】下拉列表选择刚刚创建的设备实例

    点击右边的创建数据点,填写名称

     并在高级配置中配置需要给光感发送的指令,以下为光感的询问帧和中台的配置:

     中台配置:

    • 在【我的设备】 -> 【通信网关】中找到刚才创建的网关,点击【高级】

    •  开启云网关,密码为账号密码

    • 点击 【我的设备】 -> 【通信网关】 -> 【设备实例】->【数据点】,选择刚才创建的设备实例

    •  即可查看数据已经上报成功,light即为此时的光照强度


    • 驱动代码

    #!coding:utf8
    import json
    import sys
    
    sys.path.append("..")
    from driver import *
    
    import time
    import modbus_tk
    import modbus_tk.defines as cst
    import modbus_tk.modbus as modbus
    import modbus_tk.modbus_rtu as modbus_rtu
    from modbus_tk.exceptions import ModbusInvalidResponseError
    import serial
    import signal
    import traceback
    from jcomm import *
    import re
    import struct
    import math
    
    #硬件心跳线程
    class RunHardwareHeartbeatThread(threading.Thread,JLib):
        def __init__(self, driver):
            threading.Thread.__init__(self)
            JLib.__init__(self)
            self.driver = driver
        def run(self):
            statetmp = False
            dataIdTmp = ''
            recycletmp = 0
            for dataId,attrs in self.driver.data2attrs.items():
                if 'param' not in attrs['config']:
                    self.error(attrs['config'])
                    break
                if 'hbt' in attrs['config']['param']:
                    dataIdTmp = dataId
                    recycletmp = attrs['config']['param']['hbt']
                    break
            while True:
                try:
                    if not self.driver.startHeartbeat:
                        return
    
                    #状态反转及延时
                    if statetmp == False:
                        statetmp = True
                    else:
                        statetmp = False
                    time.sleep(recycletmp)
    
                    # self.warn('HARDWARE HEATBEAT ' + dataIdTmp + u'硬件心跳:' + str(statetmp))
                    #控制执行
                    rettmp = ''
                    if statetmp:
                        rettmp = self.driver.Event_setData(dataIdTmp,'true')
                    else:
                        rettmp = self.driver.Event_setData(dataIdTmp,'false')
                    if json.loads(rettmp)["code"] == 0:
                        self.driver.setValue(self.driver.name(dataIdTmp), statetmp)
                except Exception,e:
                    traceback.print_exc(e.message)
                    continue
    
    class ModbusDriver(IOTOSDriverI):
        def __init__(self):
            IOTOSDriverI.__init__(self)
            self.master = None
            # 心跳开关
            self.startHeartbeat = False
            self.bitsState = [0,0,0,0,0,0,0,0]
            self.sourceDataIn = []
    
        # 1、通信初始化
        def InitComm(self, attrs = None):
            try:
                #一、tcp端口监听
                self.__port = self.sysAttrs['config']['param']['tcp']
                self.__tcpServer = TcpServerThread(self,self.__port)
                self.__tcpServer.setDaemon(True)
                self.__tcpServer.start()
                self.debug(self.sysAttrs['name'] + u' TCP端口' + str(self.__port) + u"已启动监听!")
    
                #二、创建串口1 <=> 串口2
                serialtmp = self.sysAttrs['config']['param']['serial']
                self.__serial = SerialDtu(serialtmp)
                self.__serial.setCallback(self.serialCallback)
                self.__serial.open()
    
                #三、串口1 <=> modbus_tk
                self.master = modbus_rtu.RtuMaster(self.__serial.serial)
                self.master.set_timeout(5)
                self.master.set_verbose(False)
                self.debug(self.sysAttrs['name'] + u' 串口' + self.__serial.portName() + u'已打开!')
    
                self.zm.pauseCollect = True
                # 实例化硬件心跳线程
                RunHardwareHeartbeatThread(self).start()
    
            except Exception,e:
                self.online(False)
                traceback.print_exc(u'通信初始化失败' + e.message)
    
        #四、串口2 <=> tcp
        #tcp => 串口2
        def tcpCallback(self,data):
            datastr = self.str2hex(data)
            self.sourceDataIn = data
            self.info("Master < < < < < < Device: " + datastr)
            self.__serial.send(data)
    
        #tcp <= 串口2
        def serialCallback(self,data):
            self.info("Master > > > > > > Device: " + self.str2hex(data))
            self.__tcpServer.send(data)
    
        #连接状态回调
        def connectEvent(self,state):
            self.online(state)
            try:
                if state == True:
                    self.warn('连接成功,启动采集、心跳')
                    self.pauseCollect = False
                    #启动软件看门狗
                    self.startHeartbeat = True
                else:
                    self.warn('连接断开,将关闭采集和心跳!')
                    self.startHeartbeat = False
                    self.pauseCollect = True
            except Exception,e:
                self.error(u'硬件心跳错误, ' + e.message)
    
        # 2、采集
        def Collecting(self, dataId):
            try:
                rtu_ret = ()
                cfgtmp = self.data2attrs[dataId]['config']
    
                #added by lrq,过滤非modbus rtu配置的点
                if not cfgtmp.has_key('param') or not cfgtmp.has_key('proxy'):
                    return ()
    
                #当是新一组功能号时;当没有proxy.pointer,或者有,但是值为null时,就进行采集!否则(有pointer且值不为null,表明设置了采集代理,那么自己自然就被略过了,因为被代理了)当前数据点遍历轮询会被略过!
                if 'pointer' not in cfgtmp['proxy'] or cfgtmp['proxy']['pointer'] == None or cfgtmp['proxy']['pointer'] == '':
    
                    #added by lrq,某些过滤掉不采集,因为有的地址的设备不在线,只要在proxy下面配置disabled:true,这样就不会轮训到它!
                    if 'disabled' in cfgtmp['proxy'] and cfgtmp['proxy']['disabled'] == True:
                        return ()
                    else:
                        self.warn(self.name(dataId))
    
                    # added by lrq,过滤非modbus rtu配置的点
                    if not cfgtmp['param'].has_key('funid'):
                        return ()
    
                    funid = cfgtmp['param']['funid']
                    devid = cfgtmp['param']['devid']
                    regad = cfgtmp['param']['regad']
                    format = cfgtmp['param']['format']
                    quantity = re.findall(r"\d+\.?\d*", format)
                    if len(quantity):
                        quantity = int(quantity[0])
                    else:
                        quantity = 1
                    if format.lower().find('i') != -1:       #I、i类型数据为4个字节,所以n个数据,就是4n字节,除一般应对modbus标准协议的2字节一个数据的个数单位!
                        quantity *= 4/2
                    elif format.lower().find('h') != -1:
                        quantity *= 2/2
                    elif format.lower().find('b') != -1:
                        quantity *= 1/2
                    elif format.find('d') != -1:
                        quantity *= 8/2
                    elif format.find('f') != -1:
                        quantity *= 4/2
                    elif format.find('?') != -1:           #对于功能号1、2的开关量读,开关个数,对于这种bool开关型,个数就不是返回字节数的两倍了!返回的字节个数是动态的,要字节数对应的位数总和,能覆盖传入的个数数值!
                        quantity *= 1
                        format = ''                        #实践发现,对于bool开关型,传入开关量个数就行,format保留为空!如果format设置为 "?"或"8?"、">?"等,都会解析不正确!!
                    self.debug('>>>>>>' + '(PORT-' + str(self.__port) + ')' + str(devid) + ' ' + str(funid) + ' ' + str(regad) + ' ' + str(quantity) + ' ' + str(format))
                    rtu_ret = self.master.execute(devid, funid, regad, quantity,data_format=format)
    
                    
                    if funid == 3:
                        retlist = []
                        for i in range(len(rtu_ret)):
                            retlist.append(rtu_ret[i])
                        rtu_ret = tuple(retlist)
    
                    #周期查询的开关量输出状态进行备份,用来给控制用
                    if funid == 1:
                        self.bitsState = list(rtu_ret)
                    self.debug(rtu_ret)
                    return rtu_ret
                # 一组功能号内的数据点,不进行遍历采集!跳过!
                else:
                    return ()   #注意,这种情况下不是采集错误,如果返回None,那么会当作采集错误处理,进行采集错误计数了!!
            except ModbusInvalidResponseError, e:
                self.error(u'MODBUS响应超时, ' + e.message)
                return None
            except Exception, e:
                traceback.print_exc(e.message)
                self.error(u'采集解析参数错误:' + e.message)
                return None
    
        # 3、控制 数据点配置
        # 事件回调接口,监测点操作访问
        def Event_getData(self, dataId, condition=''):
    
            return json.dumps({'code': 0, 'msg': '', 'data': new_val})
    
        # 事件回调接口,监测点操作访问
        def Event_setData(self, dataId, value):
            self.warn(value)
            try:
                if self.master == None:
                    self.InitComm()
                data_config = self.data2attrs[dataId]['config']
                bit = 0
                if 'proxy' in data_config.keys() and 'pointer' in data_config['proxy'] and data_config['proxy']['pointer'] != None:
                    bit = data_config['proxy']['index']
                if self.valueTyped(dataId,value) == True:
                    self.bitsState[bit] = 1
                else:
                    self.bitsState[bit] = 0
                self.warn(self.bitsState)
    
                #注意,这里地址是1,但是再huaihua等用了3合一设备的,地址是2,接下来需要这里也做个区分,按照当前操作的数据点对应的实际数据点来!
                ret = self.master.execute(1, cst.WRITE_MULTIPLE_COILS, 0, output_value=self.bitsState)
                self.warn(ret)
                return json.dumps({'code': 0, 'msg': u'操作成功!', 'data': list(ret)})
            except Exception,e:
                return json.dumps({'code': 501, 'msg': u'操作失败,错误码501,' + e.message, 'data': None})
    
    • 驱动解析

    • 编写环境为python2,首先需要导入modbus、数据解析和爱投斯中台驱动文件(driver)的相关包
    #!coding:utf8
    import json
    import sys
    
    sys.path.append("..")
    from driver import *
    
    import time
    import modbus_tk
    import modbus_tk.defines as cst
    import modbus_tk.modbus as modbus
    import modbus_tk.modbus_rtu as modbus_rtu
    from modbus_tk.exceptions import ModbusInvalidResponseError
    import serial
    import signal
    import traceback
    from jcomm import *
    import re
    import struct
    import math
    
    •  创建硬件心跳进程,判断中台的数据点是否含有必要的属性,如果没有则提示error,防止后续过程报错,开启心跳进程则启动中台的通讯
    class RunHardwareHeartbeatThread(threading.Thread,JLib):
        def __init__(self, driver):
            threading.Thread.__init__(self)
            JLib.__init__(self)
            self.driver = driver
        def run(self):
            statetmp = False
            dataIdTmp = ''
            recycletmp = 0
            for dataId,attrs in self.driver.data2attrs.items():
                if 'param' not in attrs['config']:
                    self.error(attrs['config'])
                    break
                if 'hbt' in attrs['config']['param']:
                    dataIdTmp = dataId
                    recycletmp = attrs['config']['param']['hbt']
                    break
            while True:
                try:
                    if not self.driver.startHeartbeat:
                        return
    
                    #状态反转及延时
                    if statetmp == False:
                        statetmp = True
                    else:
                        statetmp = False
                    time.sleep(recycletmp)
    
                    # self.warn('HARDWARE HEATBEAT ' + dataIdTmp + u'硬件心跳:' + str(statetmp))
                    #控制执行
                    rettmp = ''
                    if statetmp:
                        rettmp = self.driver.Event_setData(dataIdTmp,'true')
                    else:
                        rettmp = self.driver.Event_setData(dataIdTmp,'false')
                    if json.loads(rettmp)["code"] == 0:
                        self.driver.setValue(self.driver.name(dataIdTmp), statetmp)
                except Exception,e:
                    traceback.print_exc(e.message)
                    continue
    •  继承IOTOSDriverI类,进行初始化,设置心跳开关
    class ModbusDriver(IOTOSDriverI):
        def __init__(self):
            IOTOSDriverI.__init__(self)
            self.master = None
            # 心跳开关
            self.startHeartbeat = False
            self.bitsState = [0,0,0,0,0,0,0,0]
            self.sourceDataIn = []
    • 进行通讯初始化,获取爱投斯中台设备实例中配置的端口和serial属性并且启动tcp监听,实例化心跳进程
    # 1、通信初始化
        def InitComm(self, attrs = None):
            try:
                #一、tcp端口监听
                self.__port = self.sysAttrs['config']['param']['tcp']
                self.__tcpServer = TcpServerThread(self,self.__port)
                self.__tcpServer.setDaemon(True)
                self.__tcpServer.start()
                self.debug(self.sysAttrs['name'] + u' TCP端口' + str(self.__port) + u"已启动监听!")
    
                #二、创建串口1 <=> 串口2
                serialtmp = self.sysAttrs['config']['param']['serial']
                self.__serial = SerialDtu(serialtmp)
                self.__serial.setCallback(self.serialCallback)
                self.__serial.open()
    
                #三、串口1 <=> modbus_tk
                self.master = modbus_rtu.RtuMaster(self.__serial.serial)
                self.master.set_timeout(5)
                self.master.set_verbose(False)
                self.debug(self.sysAttrs['name'] + u' 串口' + self.__serial.portName() + u'已打开!')
    
                self.zm.pauseCollect = True
                # 实例化硬件心跳线程
                RunHardwareHeartbeatThread(self).start()
    
            except Exception,e:
                self.online(False)
                traceback.print_exc(u'通信初始化失败' + e.message)
    • tcp回调,可以查看设备是否与中台以及连接成功
    #四、串口2 <=> tcp
        #tcp => 串口2
        def tcpCallback(self,data):
            datastr = self.str2hex(data)
            self.sourceDataIn = data
            self.info("Master < < < < < < Device: " + datastr)
            self.__serial.send(data)
    
    #tcp <= 串口2
        def serialCallback(self,data):
            self.info("Master > > > > > > Device: " + self.str2hex(data))
            self.__tcpServer.send(data)
    • 连接状态回调,连接成功则启动硬件心跳进程并且设置中台的网关状态
    #连接状态回调
        def connectEvent(self,state):
            self.online(state)
            try:
                if state == True:
                    self.warn('连接成功,启动采集、心跳')
                    self.pauseCollect = False
                    #启动软件看门狗
                    self.startHeartbeat = True
                else:
                    self.warn('连接断开,将关闭采集和心跳!')
                    self.startHeartbeat = False
                    self.pauseCollect = True
            except Exception,e:
                self.error(u'硬件心跳错误, ' + e.message)
    •  最后是采集函数,先过滤掉中台非modbus rtu配置的点,再拿到数据点属性中的参数,将参数进行处理后可以拿到需要给设备发送的指令,发送过去后对接收过来的数据进行进制转换和处理后再上传至中台即可将设备的数据上云
    # 2、采集
        def Collecting(self, dataId):
            try:
                rtu_ret = ()
                cfgtmp = self.data2attrs[dataId]['config']
    
                #added by lrq,过滤非modbus rtu配置的点
                if not cfgtmp.has_key('param') or not cfgtmp.has_key('proxy'):
                    return ()
    
                #当是新一组功能号时;当没有proxy.pointer,或者有,但是值为null时,就进行采集!否则(有pointer且值不为null,表明设置了采集代理,那么自己自然就被略过了,因为被代理了)当前数据点遍历轮询会被略过!
                if 'pointer' not in cfgtmp['proxy'] or cfgtmp['proxy']['pointer'] == None or cfgtmp['proxy']['pointer'] == '':
    
                    #added by lrq,某些过滤掉不采集,因为有的地址的设备不在线,只要在proxy下面配置disabled:true,这样就不会轮训到它!
                    if 'disabled' in cfgtmp['proxy'] and cfgtmp['proxy']['disabled'] == True:
                        return ()
                    else:
                        self.warn(self.name(dataId))
    
                    # added by lrq,过滤非modbus rtu配置的点
                    if not cfgtmp['param'].has_key('funid'):
                        return ()
    
                    funid = cfgtmp['param']['funid']
                    devid = cfgtmp['param']['devid']
                    regad = cfgtmp['param']['regad']
                    format = cfgtmp['param']['format']
                    quantity = re.findall(r"\d+\.?\d*", format)
                    if len(quantity):
                        quantity = int(quantity[0])
                    else:
                        quantity = 1
                    if format.lower().find('i') != -1:       #I、i类型数据为4个字节,所以n个数据,就是4n字节,除一般应对modbus标准协议的2字节一个数据的个数单位!
                        quantity *= 4/2
                    elif format.lower().find('h') != -1:
                        quantity *= 2/2
                    elif format.lower().find('b') != -1:
                        quantity *= 1/2
                    elif format.find('d') != -1:
                        quantity *= 8/2
                    elif format.find('f') != -1:
                        quantity *= 4/2
                    elif format.find('?') != -1:           #对于功能号1、2的开关量读,开关个数,对于这种bool开关型,个数就不是返回字节数的两倍了!返回的字节个数是动态的,要字节数对应的位数总和,能覆盖传入的个数数值!
                        quantity *= 1
                        format = ''                        #实践发现,对于bool开关型,传入开关量个数就行,format保留为空!如果format设置为 "?"或"8?"、">?"等,都会解析不正确!!
                    self.debug('>>>>>>' + '(PORT-' + str(self.__port) + ')' + str(devid) + ' ' + str(funid) + ' ' + str(regad) + ' ' + str(quantity) + ' ' + str(format))
                    rtu_ret = self.master.execute(devid, funid, regad, quantity,data_format=format)
    
                    
                    if funid == 3:
                        retlist = []
                        for i in range(len(rtu_ret)):
                            retlist.append(rtu_ret[i])
                        rtu_ret = tuple(retlist)
    
                    #周期查询的开关量输出状态进行备份,用来给控制用
                    if funid == 1:
                        self.bitsState = list(rtu_ret)
                    self.debug(rtu_ret)
                    return rtu_ret
                # 一组功能号内的数据点,不进行遍历采集!跳过!
                else:
                    return ()   #注意,这种情况下不是采集错误,如果返回None,那么会当作采集错误处理,进行采集错误计数了!!
            except ModbusInvalidResponseError, e:
                self.error(u'MODBUS响应超时, ' + e.message)
                return None
            except Exception, e:
                traceback.print_exc(e.message)
                self.error(u'采集解析参数错误:' + e.message)
                return None
    •  部分设备可以进行数据的下发来控制设备的状态或者配置设备的参数,可以利用如下的函
    # 事件回调接口,监测点操作访问
        def Event_setData(self, dataId, value):
            self.warn(value)
            try:
                if self.master == None:
                    self.InitComm()
                data_config = self.data2attrs[dataId]['config']
                bit = 0
                if 'proxy' in data_config.keys() and 'pointer' in data_config['proxy'] and data_config['proxy']['pointer'] != None:
                    bit = data_config['proxy']['index']
                if self.valueTyped(dataId,value) == True:
                    self.bitsState[bit] = 1
                else:
                    self.bitsState[bit] = 0
                self.warn(self.bitsState)
    
                #注意,这里地址是1,但是再huaihua等用了3合一设备的,地址是2,接下来需要这里也做个区分,按照当前操作的数据点对应的实际数据点来!
                ret = self.master.execute(1, cst.WRITE_MULTIPLE_COILS, 0, output_value=self.bitsState)
                self.warn(ret)
                return json.dumps({'code': 0, 'msg': u'操作成功!', 'data': list(ret)})
            except Exception,e:
                return json.dumps({'code': 501, 'msg': u'操作失败,错误码501,' + e.message, 'data': None})
    展开全文
  • Tuya IoTOS嵌入演示WiFi和BLE红外测距 | 介绍 本演示通过Tuya WiFi / WiFi + BLE系列模块,通过Tuya Smart Cloud平台,Tuya Smart APP,IoTOS嵌入式WiFi&Ble SDK实现了智能红外测距。 已实现的功能。 实时报告...
  • Tuya IoTOS嵌入演示WiFi和BLE水位传感器 | 介绍 该演示基于Tuya Smart Cloud平台,Tuya Smart APP,IoTOS嵌入式WiFi&Ble SDK,使用Tuya WiFi / WiFi + BLE系列模块快速设置水位传感器并通过手机实现对水位数据的...
  • 导语 |腾讯物联网终端操作系统(TencentOS tiny)是腾讯面向物联网领域自主研发的嵌入式实时操作系统,可助力物联网终端设备及业务快速接入腾讯云物联网平台。本文是对腾讯高级工程...
  • Whitefield通过将现实的PHY / MAC层仿真与流行的IoT堆栈/ OS(例如 / / / / / 模式结合使用,为传感器网络提供了仿真环境。 因此,人们可以按原样使用现有的堆栈实现,并在实际的RF仿真基础上对其进行测试。 ...
  • Tuya IoTOS嵌入式MCU演示4G自动售货机 | 介绍 该演示使用Tuya智能云平台,Tuya智能APP和IoTOS嵌入式MCU SDK实现自动售货机,该自动售货机使用Tuya 4G系列模块实现自动交付和其他智能功能。 已实现的功能包括: ...
  • 登录平台:IOTOS®爱投斯物联中台 账号:iotos_test 密码:iotos123 sdk代码获取:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com) 1、下发代码如下 #!coding:utf8 import sys sys....
  • IoT OS的用户是开发者,要被广大开发者所采用IoT OS需要产品化。   第一,要有产品思维,要站在用户、开发者的角度考虑问题,尽量保持OS接口的一致性,不断地完善、抽象、迭代。   第二,对新功能、新...
  • 国内外主流IOT-OS系统

    2021-05-05 14:33:13
    IOT-OS系统 开闭源,语言,主贡献, 源地址(例子) LiteOS: 开源,语言C, 华为, https://gitee.com/LiteOS/LiteOS AliOS Things 开源,语言C, 阿里云,https://gitee.com/mirrors/AliOS-Things TencentOS tiny ...
  • IOTOS驱动 CoAP协议对接解析

    千次阅读 2021-11-05 14:14:24
    登录平台:IOTOS®爱投斯物联中台 账号:iotos_test 密码:iotos123 代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com) 目录 前言 驱动目的 适用范围 驱动代码 驱动解析...
  • 登录平台:IOTOS®爱投斯物联中台 账号:iotos_test 密码:iotos123 代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com) 目录 前言 驱动目的 适用范围 使用示例 驱动代码 ...
  • 登录平台:IOTOS®爱投斯物联中台 账号:iotos_test 密码:iotos123 代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com) 目录 前言 驱动目的 适用范围 使用示例 驱动代码 ...
  • IoT OS作为工具化的底层软件,具备二次开发扩展性,能通用在各类场景,实现设备与应用之间解耦,既可以用来搭建行业物联网平台,又可以开发设备子系统,以形成多位一体的开放性生态。这将解决物联网碎片化难题,构建...
  • 登录平台:IOTOS®爱投斯物联中台 账号:iotos_test 密码:iotos123 代码地址:IOTOSDK-Python: IOTOS Python版本SDK,自带原生接口和采集引擎 (gitee.com) 目录 前言 驱动目的 适用范围 使用示例 驱动代码 ...
  • IOTOS驱动Thales800对接从0到1详细过程 Thales800 代码分析` 代码拆分解析 1. InitComm init负责代码编写过程中初始化通讯,不论是客户在和设备对接时,还是在开发者拿到数据后和中台进行通讯,均只在此过程初始化...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,605
精华内容 3,842
关键字:

IOTOS