ThingJS v1.0-alpha


在过去的两年中,我一直在开发自己的物联网平台,今天我准备展示其Alpha版本。


我们与合作伙伴一起创建并支持IoT设备。 在这项活动过程中,我们拆除了多只耙子 。 ThingJS的诞生并不是出于渴望,而是出于使我们的生活更轻松的需要,但与此同时,我希望对您而言。


这篇文章对那些接近IoT主题并且已经在此领域有所作为的人们来说很有趣。 重要的一点是,该平台应该(突然)使JavaScript开发人员感兴趣,因为 选择该语言作为平台的基础。 当然,C / C ++开发人员也需要阅读一些内容。


首先,我将讨论在开发IoT设备时遇到的主要问题,然后将描述该平台如何处理它们,最后,这一切都很无聊: 视频技术部分,您可以触摸生活中的一切。



物联网问题:


-短臂问题


物联网基于生态系统。 其概念和技术体系结构的开发确实需要大量工作。 此外,您仍然需要为异构设备开发大量固件。 根据各种物理和逻辑原理,发明并实现用于在设备之间交换数据的传输。 扩展云资源。 制定用户界面。 等等 等


即使单个专家具有执行此操作所需的技能,他也根本没有足够的时间(手)来实施这样的想法。 虽然他会削减它,但她将过时。


-巴别塔的问题


开发成熟的物联网生态系统需要非常广泛的技术堆栈。 物联网中的完整堆栈很简单……很困难。 到处都需要经验。 并非所有人都能拥有如此广泛的知识,甚至经验。 这里的问题不在精神能力上。 从速记问题来看,这是一个显而易见的结论。


要创建一个真正富裕的生态系统,需要许多相当狭specialist的专家的工作,但是他们必须具有丰富的知识。 这些专家说不同的语言,使用不同的模式,而且他们通常以不同的方式理解基本术语。 鉴于物联网基于资源有限的设备,有效的通信对于实现预期目标至关重要。


-斯德哥尔摩综合症的问题


如今,有些供应商正在开发其生态系统。 这些是Google,Microsoft,Yandex,Megaphone,MTS等。 其中一些允许您按照自己的观点将自己的事物整合到他们的生态系统中。 这在很大程度上涵盖了上述问题。 但是它创造了一种新的-成瘾。 而且供应商喜欢更改集成条件。 更重要的是,在这种范式中没有自我实现的问题。


解决问题的方法:


-社区,成瘾,时尚,青年


实际上,上述问题阻碍了个人对物联网开发的访问。 在意识到这些问题的情况下启动了平台的开发。 为通过社区开发平台奠定了基础。


为了实现这个想法,该平台当然带有开放的代码库,并且在所有层上都具有依赖关系范式。


如果您不知道什么是成瘾,那么该是时候了解它们了。 但是,如果您尝试非常简单地解释,那么您正在开发的模块可能取决于您的朋友编写的另一个模块。 然后,您将通过预定义的界面访问其模块。


因此,与此同时,许多人可以独立地开发自己的平台组件并重用某人开发的现有组件。 这从根本上解决了人手不足的问题。



此外,“通天塔”的问题也得到解决。 建立依赖关系是为了使以不同语言开发的平台的各个级别具有用于在它们之间建立依赖关系的预定机制。


例如,C开发人员可以通过为他提供所需的接口来利用现成的前端组件。 或者相反,前端开发人员可以使用用C编写的现成组件。 每个人都将尽其所能。


-更多的承诺和抽象


设备之间的通信协议未定义。 而是有一个抽象-数据总线。 设备可以向总线发送事件或收听总线。 目前尚不清楚谁先写信给谁,谁先收到信。 还有什么时候。 不保证异步数据交换和传送。 总的来说-地狱。 不用担心 如此构思。


问题是,生态系统是一组独立的自给自足的设备。 在任何时候,某些设备可能不可用。 由于各种原因。 如果某个零件不可用,则停止其他设备的活动不是最佳方案。 有必要将无法避免的合法化。


该平台实现了提供事件的承诺范式。 第一个设备订阅第二个设备的承诺,以向他提供信息。 但是没有保证。 订户必须决定在不及时向其提供数据的情况下该怎么做。


同步通信的问题是通过经由具有同步通道链接的总线传输事件来解决的。 同步通道协议由事件本身的类型确定。 例如,您可以发送类型为“ do-render-video-stream”的事件,以及如何发送IP WEB摄像机作为有效负载。 因此,收件人将知道您需要从指定的地址播放视频流。



但是,公共汽车在物理上如何工作? 公交车的实施取决于社区。 轮胎会随着您的项目所需的运输而扩展。 例如,一个事件通过http接收并通过UART中继。 对于生态系统的所有要素,向外没有任何变化。


-虚拟物联网设备


对于ThingJS,事物不仅是物理事物,而且是特殊的应用程序-虚拟事物。 而且,物理事物可以包含使用物理事物的资源的多个虚拟事物(应用程序)。


这种方法允许您统一条件后端(控制器/服务器/云等)与前端(浏览器,应用程序等)以及b2b甚至f2f之间的交互。 构建矩阵,而不是交互层次结构。



一个简单的示例是WEB摄像机,它本身具有虚拟物体-用户界面。 当用户转到地址http://192.168.4.1时 ,将打开WEB页面,其中虚拟事物开始“运行”。 相机(物理物体)和页面(虚拟物体)自动成为可使用统一数据总线的生态系统。 通过它,虚拟事物与物理事物进行通信。 在这种情况下:物理事物通过总线将视频流的地址,其状态等告知虚拟事物,而虚拟事物向用户显示视频并向物理事物发出必要的命令。


逻辑上的延续是将虚拟事物托管在云中并将其包含在公共生态系统中的能力。 而这又使您可以创建具有巨大资源的虚拟设备来解决问题,例如可用于AI的虚拟设备。


您可以自己创建此类设备,也可以使用已创建的设备。 斯德哥尔摩综合症被击败。 您可以自己确定项目所依赖的内容以及开发方式。


技术资料


ThingJS应用程序结构



技术栈


所选的硬件平台为ESP32控制器。 该平台被设计为独立于硬件。 但是,不幸的是,没有时间在其他设备上进行分区。


为了开发固件,使用了推荐的Espressif工具 。 固件在C中开发。cmake收集器。 该项目使用的组件概念也由Espressif推广。


除esp-idf外, 还使用Mongoose WEB服务器以及经过修改的JavaScript解释器Mongoose mJS


对于应用程序开发,JavaScript与VUE 2框架一起使用,并使用webpack构建应用程序。 程序包管理器是npm。 VUE CLI被用作开发环境的基础。


为了使应用程序可视化标准化并缓解UI创造力的困扰 ,该平台中包含vuetifyjs软件包。


开发环境功能


对于JavaScript开发人员(虚拟事物):


  • 推荐的IDE-WEBStorm;
  • VUE CLI和IDE带来的所有收益;
  • 应用程序的系统内调试(控制器上的mJS调试器);
  • MJS实现了debugger命令,该命令允许您在任意位置调用调试器。
  • 在开发过程中将更新的文件热上传到控制器(没有此功能,JavaScript开发人员将无法生存);
  • 运行时开发与真正的控制器配对。 您进行编程,然后在硬件上看到结果;
  • 已配置ESLint以了解平台对象。

对于C开发人员(实际的事情):


  • 推荐的IDE-CLion;
  • 所有利润esp-idf和IDE;
  • 作为esp-idf概念的一部分,该平台分为多个部分。
  • 易于与本机组件平台集成。

支持的设备


目前仅支持ESP32。 该芯片因其可用性和惊人的技术特性而广受欢迎。 基于此,已经创建了许多现成的IoT设备,可以在ThingJS下使用。


与竞争对手比较


我建议不要跑那么远。 我不敢称商业平台为竞争对手。 开源的出现和消失没有留下明显的痕迹。 因此,我没有进行比较。 但是,如果有人有需求,我准备在这里发布他的工作结果。


快速上手


我只需要看



我想尝试


为了在真正的硬件上尝试该平台,您将需要任何基于ESP32的设备,该设备具有Flash 4mb并能够通过USB对其进行闪存。 但是ESP32核心板v2最适合。



您可以在Aliexpress或Ebay上购买这些东西而没有任何问题。 此外,在俄罗斯甚至设有代表处。 我个人在圣彼得堡购买。


为了测试“ Blink”测试应用程序的运行,您需要连接一个LED。 某些版本的开发板上已预安装了连接到GPIO2的LED。 如果您有这样的董事会,那么您将无能为力。 眨眼应该没有任何不必要的动作。 如果只有一个二极管(电源),则必须自己连接指示器二极管。 这并不复杂。


您将需要任何指示灯LED和1至5K的电阻。



剩下的唯一事情就是在设备上部署用户软件包。 你可以在这里拿。 部署说明位于此处。




眨眼是一个简单的生态系统,由一个实现用户界面的虚拟设备和一个物理设备组成。 通过浏览器访问虚拟设备时,虚拟设备将从物理设备启动。


脚本很简单。 在物理设备上安装应用程序时,LED(以前已与其连接)开始以1 Hz的频率闪烁。 用户可以通过界面打开或关闭二极管的闪烁。 您可以在“我只能观看”部分观看视频。


来源在src / applications / blink 存储库中 。 为了收集眨眼并使用它,您只需要此存储库。 确保已经安装了git,npm和nodejs。


git clone --branch alpha https://github.com/rpiontik/ThingJS-front cd ThingJS-front npm install npm run build 

如果一切顺利,您将得到如下结果:



恭喜你! 您已经构建了第一个ThingJS应用。 您可以在dist / apps / blink文件夹中找到它,然后在“我只看”部分的视频指导下立即尝试将其安装在设备上。



档案文件内容描述
脚本/blink.js控制器上安装的脚本
blink.js应用程序组件安装点
眨眼实现用户界面的VUE组件
favicon.svg应用程序图标
langs.js应用语言包
manifest.json申请清单

您可以自己了解应用程序的所有详细信息。 我将重点介绍几个文件。



 { "name": "Blink", "vendor" : "rpiontik", "version" : 1, "subversion" : 0, "patch" : 0, "description": { "ru": " ", "en": "Blink Example" }, "components": {...}, "scripts": {...}, "requires" : {...} } 

如文件名所示,这是应用程序清单。 它具有关于目的的一般元数据,很容易猜到。 除了它们,还有三个重要的块。 让我们仔细看看它们:



 "components": { "blink-app": { "source": "blink.js", "intent_filter": [ { "action": "thingjs.intent.action.MAIN", "category": "thingjs.intent.category.LAUNCH" } ] } } 

该块描述了应用程序的整个组件库。 “源”字段指向组件的安装点(请参见blink.js),并且是webpack的程序集入口点( entry )。 因此,每个组件将在单独的捆绑包中发行。 该捆绑包将根据需要加载延迟加载 )。


一个重要的结构是intent_filter 。 如果您碰巧为Android编程,将会发现一些您熟悉的东西。 并且不要犯错。 系统生成组件订阅的接口和服务事件。 如果发生满足过滤条件的事件,则将加载组件并将控制权转移到安装点。


在这种情况下,“ blink-app”组件被订阅到应用程序主界面组件的启动事件。 启动器启动应用程序时,将引入此组件。


如果您通过更改行来修改清单


thingjs.intent.category.LAUNCH >> thingjs.intent.category.PREFERENCE


,然后在组装和安装后发现该应用程序已停止在桌面上打开。 但是,“设置”部分中出现了一个新的“平铺”。 同时,功能上没有任何改变。


因此,我们向启动器指示此组件是用于自定义应用程序的接口元素。 并且此组件开始出现在设置中。



 "scripts": { "entry": "blink", "subscriptions" : ["$-script-restart", "blink"], "modules": { "blink": { "hot_reload": true, "source": "scripts/blink.js", "optimize": false } } } 

该块的功能类似于“ components”块,但它基于控制器端描述了应用程序组件。


它清楚地指示了入口点。 在“输入”字段中。 另外,我将注意安装该应用程序时该脚本不会立即启动。 仅当预订脚本的事件之一发生时才启动它。


“订阅”字段负责订阅。 现在它指示两个事件:


  • $ -script-restart-在系统启动或重新启动时发生;
  • 眨眼是与眨眼生态系统相关的自定义事件。

在“模块”块中,下面是脚本的描述。 我将注意两个领域:


  • hot_reload-如果此字段设置为true,则在开发模式下更改文件时,它将自动下载到控制器(热重载);
  • 优化 -如果为true,则在构建项目时,将对脚本进行优化和聚合。


 "requires" : { "interfaces" : { "blink" : { "type" : "bit_port", "required" : true, "default" : 2, "description" : { "ru" : "LED ", "en" : "LED indicator" } } } } 

您可能已经注意到,在安装应用程序时,您需要选择LED闪烁的引脚。 但是,默认情况下已将其选择为GPIO2。 该块负责这些设置。


在该块中,指示依赖性。 在这种情况下,为了使应用程序正常运行,它需要提供类型为“ bit_port”的接口。 此接口是必需的要求(必需= true),默认情况下,指定了GPIO2(默认= 2)。 它将以“ blink”的名称投影到脚本中。


安装应用程序时,将考虑将在其上部署脚本的设备的配置文件。 此配置文件列出了可用的接口和接口的可用硬件资源(尤其是引脚及其组合)。 检查需求和设备的兼容性。 如果设备可以满足应用程序的要求,则会向用户显示一个资源分配方案,其中自动考虑到清单的建议自动分配主要资源。 即 来自相同的“默认”字段。


因此,可以在一个设备上安装多个应用程序,它们可以在它们之间共享硬件资源。



 import App from './Blink.vue'; import Langs from './langs'; $includeLang(Langs); $exportComponent('blink-app', App); 

该文件是清单中声明的​​组件的安装点(请参见manifest.js / components),它通过抽象方法$ exportComponent注册VUE组件“ blink-app”,并注册语言包。


您可能会问-为什么会有这样的困难? 为什么不立即注册在源中指定的VUE组件? 事实是清单描述了公共组件。 第三方应用程序可能会请求这些组件(运行时依赖项)。 挂载点又可以注册相关组件(供内部使用)以及服务。 即,准备组件环境。



 export default { name: 'Blink', watch: { blink_state (state) { // Send event to script this.$bus.$emit($consts.EVENTS.UBUS_MESSAGE, 'blink', state); } }, data () { return { blink_state: true }; } }; 

该代码说明一切。 更改“ blink_state”属性后,会将具有当前值的消息发送到总线($ bus)。 这就是您需要做的所有事情,以便控制器端的脚本可以接收所需的命令。



 let active = true; let state = true; // Set port direction $res.blink.direction($res.blink.DIR_MODE_DEF_OUTPUT); // Run background process setInterval(function () { if (active) { // $res - is container with required resources $res.blink.set(state); // Do invert state = !state; } }, 1000); // Event listener // $bus - system bus interface $bus.on(function (event, content, data) { if (event === 'blink') { active = !!JSON.parse(content); } }, null); 

通常,该代码与JavaScript中计时器的经典用法非常相似。 除了它不在JavaScript的这种方言中。 它在平台中实现。 认识这个mJS 。 您可以在项目的官方页面上了解更多信息。


对于平台的需求,方言已完成。 引入了计时器以及诸如“调试器”之类的有用命令。 好吧,调试器本身。 在“开发环境”部分中单独详细介绍了此内容。


注意平台的全局对象。 它们以“ $”字符命名。


  • $ res-包含分配给脚本的资源;
  • $ bus-总线接口。

因为 该应用程序请求的接口的类型为“ bit_port”(请参见profile.json / require),名称为“ blink”,并以$ res.blink的名称提供。 该接口仅实现三个功能:


  • 设置(值) -设置GPIO级别
  • get() -获取当前的GPIO级别
  • 方向(值) -设置GPIO模式

对于方向函数,可通过相同的接口$ res.blink。:DIR_MODE_DISABLE;描述可用的常数。 DIR_MODE_DEF_INPUT; DIR_MODE_DEF_OUTPUT; DIR_MODE_INPUT_OUTPUT_OD; DIR_MODE_INPUT_OUTPUT。


订阅总线事件是通过$ bus.on方法完成的。 在这种情况下,脚本所预订的所有事件都将到达处理程序。 处理程序接受三个参数:


  • 事件 - 事件标识符。 在这种情况下,只有两个可能:“ $ -script-restart”和“ blink”。 其中只有一个被处理-闪烁。 只有在系统启动时立即启动脚本,才需要订阅第二个脚本。
  • 内容 -事件可能会附带数据。 考虑到事件标识符的长度,它们的大小限制为126个字节。
  • 数据 -订阅事件作为第二参数时传输的数据。 在这种情况下,它们为null。

接口是可扩展的。 在下面,您将找到有关如何创建自己的界面的描述。


接口实现


ThingJS允许您通过特殊接口扩展可用的硬件和服务资源。 您可以独立创建一个接口,该接口将实现任何复杂,准确,已加载等。 功能。


例如,您可以实现与云服务的集成接口。 或者是后台异步进程,脚本可以通过该进程来交换消息。 好了,还是实现显示支持。 它将同样易于制造和使用。 你和其他人。 是的,为此,您需要了解C。


考虑一下Blink示例中使用的bit_port接口的实现。 为了开始,您需要部署ThingJS-template alpha版本项目。 部署文档位于项目本身中。


 git clone --branch alpha https://github.com/rpiontik/ThingJS-template 

该项目包括以下组件:


  • ThingJS板 -包含设备配置。 到目前为止,仅与ESP32_CORE_BOARD V2兼容;
  • ThingJS-extern -ThingJS使用的第三方项目的库;
  • ThingJS核心 -平台核心;
  • ThingJS-front-应用程序开发环境;
  • ThingJS-stdi-标准接口。

我们对ThingJS-stdi项目感兴趣。 其结构如下:


档案文件内容描述
实施/ tgsi_bit_port.cBit_port接口实现
实施/ tgsi_bit_port.hBit_pro接口头文件
CMakeLists.txtcmake构建脚本
自述文件
sdti_utils.h帮手
somethingjs_stdi.c接口安装点
somethingjs_stdi.h挂载点头文件

实际上,我们只对一个文件感兴趣-实现/ tgsi_bit_port.c。 它包含所有需要单独解释的内容。


 void thingjsBitPortRegister(void) { static int thingjs_bit_port_cases[] = DEF_CASES( DEF_CASE(GPIO0), DEF_CASE(GPIO2), DEF_CASE(GPIO3), DEF_CASE(GPIO4), DEF_CASE(GPIO5), DEF_CASE(GPIO12), DEF_CASE(GPIO13), DEF_CASE(GPIO14), DEF_CASE(GPIO15), DEF_CASE(GPIO16), DEF_CASE(GPIO17), DEF_CASE(GPIO18), DEF_CASE(GPIO19), DEF_CASE(GPIO21), DEF_CASE(GPIO22), DEF_CASE(GPIO23), DEF_CASE(GPIO25), DEF_CASE(GPIO26), DEF_CASE(GPIO27), DEF_CASE(GPIO32), DEF_CASE(GPIO33) ); static const struct st_thingjs_interface_manifest interface = { .type = "bit_port", .constructor = thingjsBitPortConstructor, .cases = thingjs_bit_port_cases }; thingjsRegisterInterface(&interface); } 

ThingJSBitPortRegister函数在ThingJS内核中注册一个组件。 为此,它调用thingjsRegisterInterface函数,并向该函数传递带有接口描述的结构。


  • 类型 -接口标识符。 在应用程序的manifest.json文件中将他指定为类型。
  • 构造函数 -链接到接口构造函数。 每当您需要创建接口的新实例时,都会调用该函数。
  • case是一个数组,描述了接口可以用于其工作的可能的硬件资源。 在这种情况下,这些是单个GPIO。 但是它们的组合或依赖性可以单独描述。

接口构造函数将接口安装到mJS计算机中。


 mjs_val_t thingjsBitPortConstructor(struct mjs *mjs, cJSON *params) { //Validate preset params //The params must have pin number if (!cJSON_IsNumber(params)) return MJS_UNDEFINED; //Get pin number gpio_num_t gpio = params->valueint; //Create mjs object mjs_val_t interface = mjs_mk_object(mjs); /* Configure the IOMUX register for pad BLINK_GPIO (some pads are muxed to GPIO on reset already, but some default to other functions and need to be switched to GPIO. Consult the Technical Reference for a list of pads and their default functions.) */ gpio_pad_select_gpio(gpio); //Add protected property to interface mjs_set(mjs, interface, "gpio", ~0, mjs_mk_number(mjs, gpio)); //Set protected flag mjs_set_protected(mjs, interface, "gpio", ~0, true); //Bind functions mjs_set(mjs, interface, "set", ~0, mjs_mk_foreign_func(mjs, (mjs_func_ptr_t) thingjsBitPortSet)); mjs_set(mjs, interface, "get", ~0, mjs_mk_foreign_func(mjs, (mjs_func_ptr_t) thingjsBitPortGet)); mjs_set(mjs, interface, "direction", ~0, mjs_mk_foreign_func(mjs, (mjs_func_ptr_t) thingjsBitPortDirection)); //Consts mjs_set(mjs, interface, "DIR_MODE_DISABLE", ~0, mjs_mk_number(mjs, GPIO_MODE_DISABLE)); mjs_set(mjs, interface, "DIR_MODE_DEF_INPUT", ~0, mjs_mk_number(mjs, GPIO_MODE_DEF_INPUT)); mjs_set(mjs, interface, "DIR_MODE_DEF_OUTPUT", ~0, mjs_mk_number(mjs, GPIO_MODE_DEF_OUTPUT)); mjs_set(mjs, interface, "DIR_MODE_INPUT_OUTPUT_OD", ~0, mjs_mk_number(mjs, GPIO_MODE_INPUT_OUTPUT_OD)); mjs_set(mjs, interface, "DIR_MODE_INPUT_OUTPUT", ~0, mjs_mk_number(mjs, GPIO_MODE_INPUT_OUTPUT)); //Return mJS interface object return interface; } 

如何传递参数:


  • mjs-全局执行上下文;
  • params-接口初始化参数。 在这种情况下,这是GPIO号。

创建了一个mJS“接口”对象,该接口的方法和属性将在其中安装:


  • gpio-只读属性,用于存储使用的GPIO数量;
  • set-设置信号电平的方法;
  • get-获取当前信号电平的方法;
  • 方向 -设置GPIO模式;

此外,还安装了可以使用脚本进行操作的常量(DIR_MODE_DISABLE,DIR_MODE_DEF_INPUT等)。


创建接口后,将其安装在全局$ res对象中的特定标识符下(在Blink示例中为“ blink”)。 可以在“眨眼”部分找到一个使用示例( scripts / blink.js )。


您可以将接口格式化为单独的组件或程序包。 这将使您可以将固件组装为乐高玩具。


开发环境


应用开发


应用程序开发环境基于VUE CLI,已经对其进行了改进以满足ThingJS平台的需求。 这是一个硬叉,包括。 如果VUE CLI的新功能可以极大地改善生活,则值得期待。


要部署环境,您需要克隆ThingJS-front -alpha发布项目。 确保已经安装了git,npm和nodejs。


 git clone --branch alpha https://github.com/rpiontik/ThingJS-front cd ThingJS-front npm install 

开发时,建议使用IDE WEBStorm。


项目的组成和结构继承自VUE CLI。 我将反映出重大差异:


  1. 重新制作了build文件夹中的build脚本。
  2. 环境变量“ HW_DEVICE_URL”已添加到开发环境配置(config / dev.env.js)。 必须指定一个与您将使用的物理设备的链接。
  3. 出现src / Applications系统文件夹。 它包含将自动构建的应用程序。 特别是,它包含两个应用程序:ante(启动器)和眨眼(应用程序)。
  4. src / applications文件夹上方的所有内容均视为平台模块和资源。 当然,您可以对其进行更改,但是在这种情况下,它们只有在闪烁后才会出现在控制器中。 T.ch. 除非您专门为自己设定目标,否则最好不要触摸它们。

为了进行测试,您可以立即启动开发服务器。 尽管没有物理硬件也无法完全开发,但这不会干扰接口的开发。 因此,开发服务器启动:


 npm run dev 

结果应该是这样的:



打开浏览器并在地址栏中输入http://0.0.0.0:8080 ,您将看到处于开发模式的平台:



接口开发过程本身与VUE上的经典前端开发没有太大区别。 除了需要注意的全局平台对象外:


  • $ const-包含平台常量以及语言包;
  • $ bus-数据总线;
  • $ store-全局存储(VUEX)。
    从示例中,您可以了解如何使用它们。

多种语言以最简单的方式实现-通过“ lang”过滤器。 指定语言常数,根据接口语言将其解释为文本。


 v-bind:label="'BLINK_SATE' | lang" 

为了全面评估开发环境的功能,您将需要一个准备好的(缝合)控制器。 您可以从项目中自行组装固件,也可以从此处使用现成的固件和实用程序。


刷新控制器并连接到网络后,您需要确保可以通过IP从计算机访问控制器。 为此,在浏览器中键入http:// [控制器IP ]。 WEB界面应打开。


现在您需要在config / dev.env.js文件中指定控制器的地址


 'use strict' const merge = require('webpack-merge') const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"', HW_DEVICE_URL: '"http://[IP ]"' //HW_DEVICE_URL: '"http://192.168.8.105"', //HW_DEVICE_URL: '"http://192.168.4.1"', }) 

如果开发服务器已启动,请停止并重新启动它。 将来,在更改构建文件,配置和应用程序清单后,请始终重新启动开发服务器。


尽管在开发环境中工作时,会显示已安装的src / application文件夹中的所有应用程序,但只有那些真正安装在控制器上的应用程序才能完全运行。 这不是功能,而是Alpha错误。 将来,硬件和开发环境的同步将自动发生。 但是现在,您需要在控制器上手动安装应用程序,以便环境“挂接”该应用程序并将其与dev中的内容同步。


我们以生产模式组装应用程序:


 npm run prod 

将收集的应用程序直接安装在控制器上。 不能通过开发服务器


现在您可以开始开发了。 您对文件所做的任何更改都会自动开始重建应用程序,并且屏幕上的图片也会更改(热重装)。 相同的规则适用于控制器脚本。 例如,您可以将debugger命令添加到闪烁的应用程序脚本中并查看结果。


 // Event listener // $bus - system bus interface $bus.on(function (event, content, data) { if (event === 'blink') { debugger; active = !!JSON.parse(content); } }, null); 

现在,当“眨眼”应用程序的复选框的状态更改时,开发环境将引发以下消息:



单击“启动调试器”链接将带您进入调试器。 显示发生停止的行。



调试过程本身与其他调试器没有太大区别。



调试器分为四个部分。 在中央代码本身。 在控制器上保留已安装的应用程序。 它们的结构和组成。 对,检查员。 日志显示如下。 左下方是与控制器通讯的当前状态。


调试环境正在密集开发中。 还有更多的监视和调试工具要构建。 对于可能出现的错误,我深表歉意。


固件开发


固件开发基于Espressif提出的概念。 在这方面,我无法击败本地文档


已经准备好存储库以快速入门。 它包含部署信息。 有关使用的示例,请参见“实现接口”


组装非常简单,实际上在1-2个小时内,您就可以组装固件了,没有任何问题。


接下来是什么?


此外,如果平台对社区感兴趣,则计划:


  • 开发调试环境;
  • 接口,事件,组件的命名标准化;
  • 平台上的详细文档;
  • 云托管虚拟事物;
  • 运行时存储库
  • 分区到各种成品设备。

另外,我正在寻找愿意与我一起开发该平台的人。 它的范围和野心已经很大。 我承担着平等的合作,其目的是将平台开发为成熟的OpenSource原则。


pull- .


参考文献


ThingJS:



ThingJS:



:



FAQ


.

Source: https://habr.com/ru/post/zh-CN474356/


All Articles