控制基础架构的制作方法

文档序号:11290935阅读:212来源:国知局
控制基础架构的制造方法与工艺

背景

发明领域

本文中描述的实施方案大体涉及控制基础架构的各种部件。

相关技术描述

当前,存在统一并流线化工业控制和家庭自动化领域的需要。虽然这两个领域共有控制外部装置的相同基本目标,但在可用于每一领域的现有解决方案中存在大量差异和复杂性。

举例来说,在工业控制的领域中,系统一般通过系统集成公司针对每一特定客户的复杂要求手工操作。即使当此集成是基于广泛可用的部件时,那些部件的配置也在各集成之间有所不同,由此迫使工业自动化系统的成本上升。这些成本包含初始研发成本以及用于维护和升级的成本。因此,工业控制的领域将受益于构建块架构,所述构建块架构能够与几乎任何装置介接,但所述构建块架构足够简单以由不太熟练的用户构造和配置。工业控制的此去复杂化可消除对中间商(即,系统集成公司)的需要,并使客户的研发和维护成本下降。

在家庭自动化的领域中,价格约束必然比在工业控制的领域中更加严格。因此,普通客户可尝试仅相对较简单形式的控制和自动化。不幸的是,当前存在大量不相容且重叠的架构可用于家庭自动化的领域中。因此,家庭自动化的领域将受益于可处理所有可能的基础的架构,并且所述架构可快速地、便宜地并且连续地升级为新技术出现。

另外,当前存在针对每一竖直定向的市场解决方案的各种各样的竖井型传输协议。对于住宅应用,存在x-10tm、zigbeetm、z-wavetm以及komextm。对于商业应用,存在bacnettm和lonworkstm。对于照明应用,存在dalitm。对于工业应用,存在modbustm、profilebustm、devicenettm以及controlnettm。对于汽车应用,存在can-bustm。对于计量应用,存在m-bustm

因此,所需要的是可使各种控制领域与平台无关的、协议无关的、传输无关的可扩展分布式构建块架构统一的控制基础架构。

概述

因此,本发明公开一种统一控制基础架构。

在实施方案中,本发明公开一种系统。所述系统可包括脚本执行模块,所述脚本执行模块包括:编译器,所述编译器将用基础脚本语言表示的脚本编译成虚拟机程序,其中所述脚本包括引用装置属性的指令,虚拟机,所述虚拟机执行虚拟机程序,以及脚本管理器,所述脚本管理器将脚本存储在脚本注册表中,从所述脚本注册表检索脚本,并将脚本加载到编译器中;以及一个或多个网关,其中所述一个或多个网关中的每一个以通信方式连接到一个或多个物理装置,并且其中所述一个或多个网关中的每一个包括:至少一个硬件处理器,一个或多个驱动器,其中所述一个或多个驱动器中的每一个使用通信协议来与一个或多个物理装置中的至少一个通信,以读取、写入或读取并写入物理装置的装置属性,以及装置管理器,所述装置管理器在通过至少一个硬件处理器执行时,根据映射,将在虚拟机程序中引用的装置属性映射到通过一个或多个驱动器使用的装置属性。一个或多个网关可包括多个网关。一个或多个网关中的每一个可还包括脚本执行模块。对于一个或多个网关中的每一个,脚本执行模块和装置管理器可被网关的至少一个硬件处理器执行为单一统一过程。对于一个或多个网关中的每一个,一个或多个驱动器中的每一个可通过网关的至少一个硬件处理器以与一个或多个驱动器中的其它驱动器和所述单一统一过程不同的过程执行。一个或多个网关中的每一个可还包括通信层,并且对于一个或多个网关中的每一个,脚本执行模块和装置管理器可通过网关的至少一个硬件处理器执行为单独的过程,并且脚本执行模块的过程和装置管理器的过程可经由网关的通信层彼此通信。所述系统可还包括平台,所述平台经由至少一个网络以通信方式连接到一个或多个网关中的每一个。所述平台可包括至少一个硬件处理器和脚本执行模块,多个网关中的每一个可还包括通信层,脚本执行模块可通过平台的至少一个硬件处理器执行为第一过程,对于多个网关中的每一个,装置管理器可通过网关的至少一个硬件处理器执行为第二过程,以及对于多个网关中的每一个,第一过程可经由至少一个网络和网关上的通信层与网关上的第二过程通信。所述平台可包括存储器,所述存储器存储定义通过装置管理器使用的映射的模式,并且一个或多个网关中的每一个在初始化后可经由至少一个网络从平台下载所述模式。所述模式可使用适配器编程语言来定义映射,所述适配器编程语言是基础脚本语言的子集。所述平台可包括web应用,所述web应用在通过平台的至少一个硬件处理器执行时,产生脚本图形用户界面(gui)以用于创建脚本。所述脚本gui可包括一个或多个输入用于将每个表示基础脚本语言的结构的图形元素链接到脚本的图形表示中,并且平台的至少一个硬件处理器可将脚本的图形表示转换成中间的基于文本的格式。脚本执行模块可还包括脚本转换器,所述脚本转换器将脚本的中间的基于文本的格式转换成符合基础脚本语言的脚本。以通信方式连接到一个或多个网关中的每一个的一个或多个物理装置中的每一个的每一装置属性可与所述装置属性的值和状态相关联,所述状态指示权威机构是否已确认装置属性的值表示装置属性的实际值。权威机构可为与具有装置属性的物理装置通信的驱动器。基础脚本语言可提供assign-and-wait-while-pending运算符,所述运算符在用于在被编译成虚拟机程序并通过虚拟机执行的脚本内将值赋给装置属性的指令中时,使得虚拟机将值赋给装置属性,并等待直到与装置属性相关联的状态指示权威机构已确认所赋的值表示装置属性的实际值,才继续执行虚拟机程序中的任何其它经编译指令。基础脚本语言可提供trigger结构,所述trigger结构包括触发条件和主体,并且其中trigger结构在用于被编译成虚拟机程序并通过虚拟机执行的脚本中时,使得虚拟机每当发生从不满足触发条件的第一状态到满足触发条件的第二状态的转变时执行对应于主体的指令。trigger结构可还包括滞后量,通过所述滞后量在从第一状态到第二状态的转变发生之前必须满足触发条件。基础脚本语言可提供every结构,所述every结构定义时间间隔并包括主体,其中every结构在用于被编译成虚拟机程序并通过虚拟机执行的脚本中时,使得虚拟机在连续多次经过所定义的时间间隔中的每一次经过之后执行对应于主体的指令。基础脚本语言可提供pause结构,所述pause结构定义时间段,其中pause结构在用于被编译成虚拟机程序并通过虚拟机执行的脚本中时,使得虚拟机在继续执行虚拟机程序中的任何其它经编译指令之前在所定义的时间段的长度上暂停。基础脚本语言可提供activation结构,所述activation结构识别脚本,其中activation结构在用于被编译成父虚拟机程序并通过虚拟机执行的父脚本中时,使得虚拟机激活所识别的脚本以作为父脚本的子脚本。激活所识别的脚本以作为子脚本可包括执行从子脚本编译的子虚拟机程序。基础脚本语言可提供关键字,所述关键字在与activation结构一起用于被编译成父虚拟机程序并通过虚拟机执行的父脚本中时,使得虚拟机并行地执行子虚拟机程序与父虚拟机程序。当关键字不与activation结构一起用于被编译成父虚拟机程序并通过虚拟机执行的父脚本中时,虚拟机可在继续执行父虚拟机程序中的任何其它经编译指令之前执行子虚拟机程序。虚拟机可并行地执行多个虚拟机程序。一个或多个网关中的每一个可还包括脚本执行模块,其中,对于一个或多个网关中的每一个,网关的脚本管理器使其脚本注册表经由至少一个网络与镜像脚本注册表同步,所述镜像脚本注册表与网关相关联并存储在平台上。对于一个或多个网关中的每一个,即使当网关不能够经由至少一个网络与平台通信时,脚本管理器也可从脚本注册表检索脚本,编译器可将检索出的脚本编译成虚拟机程序,且虚拟机可执行虚拟机程序。一个或多个网关中的每一个可还包括脚本执行模块,其中平台包括web应用,所述web应用在通过平台的所述至少一个硬件处理器执行时,产生图形用户界面(gui)以用于选择一个或多个脚本以发送到一个或多个网关的子集中的至少每一个的脚本注册表并存储在所述脚本注册表中。gui可包括一个或多个输入以用于将多个物理装置分成装置群组,所述装置群组表示为虚拟装置,其中基础脚本语言将对虚拟装置的引用视为与对物理装置的引用相同。装置群组可包括一个或多个虚拟装置。当对在虚拟机程序中引用并表示装置群组的虚拟装置的装置属性执行映射时,对于装置群组中的每一物理装置,装置管理器可:当物理装置不具有对应于虚拟装置的装置属性的装置属性时,不将虚拟装置的装置属性映射到由一个或多个驱动器使用的任何装置属性,以及当物理装置的确具有对应于虚拟装置的装置属性的装置属性时,将虚拟装置的装置属性映射到对应的装置属性。装置管理器可还包括:装置管理器抽象层,所述装置管理器抽象层根据第一映射将在虚拟机程序中引用的装置属性映射到逻辑装置属性;以及通用驱动器抽象层,所述通用驱动器抽象层根据第二映射将逻辑装置属性映射到由一个或多个物理装置使用的物理装置属性。第一映射可使用基础脚本语言的第一变化型式定义,并且第二映射可使用基础脚本语言的与第一变化型式不同的第二变化型式定义。对于与一个或多个物理装置中的至少一个通信的一个或多个驱动器中的至少一个,通用驱动器抽象层可将至少一个物理装置的装置属性的值存储在一个或多个内部注册表中,并且通用驱动器抽象层可通过以下操作来更新存储在一个或多个内部注册表中的值:使用一个或多个回调函数来轮询至少一个物理装置,所述至少一个驱动器已向通用驱动器抽象层注册所述回调函数。至少一个驱动器可包括多个驱动器。至少一个物理装置可包括多个物理装置。装置管理器可包括用户界面,其中用户界面包括基于文本的控制台,所述控制台经配置以从用户接收一个或多个基于文本的命令,并显示基于文本的输出以响应于所述一个或多个命令。控制台可还经配置以在第一上下文与第二上下文之间切换,所述第一上下文为用户提供与装置管理器的交互,所述第二上下文为用户提供与一个或多个驱动器中的至少一个的交互。

在实施方案中,本发明公开一种方法。所述方法包括使用以通信方式连接到一个或多个物理装置的网关装置上的至少一个硬件处理器以:经由至少一个网络从平台接收脚本;自动地将接收到的脚本编译成虚拟机程序;以及,响应于针对所述脚本的激活命令,将虚拟机程序加载到虚拟机中,通过虚拟机执行虚拟机程序,其中虚拟机程序的执行包括对装置属性的一个或多个引用,响应于在虚拟机程序的执行期间对装置属性的引用中的一个或多个,自动地将在虚拟机程序的执行期间引用的至少一个装置属性映射到存储在网关装置上的由至少一个驱动器使用的装置属性,以及,通过至少一个驱动器,使用通信协议来与一个或多个物理装置中的至少一个通信,以读取、写入或读取并写入至少一个物理装置的对应于由至少一个驱动器使用的装置属性的实际属性。

在实施方案中,本发明公开一种非暂时性计算机可读介质。所述介质具有存储在其上的指令,所述指令在通过处理器执行时使得处理器:经由至少一个网络从平台接收脚本;自动地将接收到的脚本编译成虚拟机程序;以及,响应于针对所述脚本的激活命令,将虚拟机程序加载到虚拟机中,通过虚拟机执行虚拟机程序,其中虚拟机程序的执行包括对装置属性的一个或多个引用,响应于在虚拟机程序的执行期间对装置属性的引用中的一个或多个,自动地将在虚拟机程序的执行期间引用的至少一个装置属性映射到存储在网关装置上的由至少一个驱动器使用的装置属性,以及,通过至少一个驱动器,使用通信协议来与一个或多个物理装置中的至少一个通信,以读取、写入或读取并写入至少一个物理装置的对应于由至少一个驱动器使用的装置属性的实际属性。

在实施方案中,本发明公开一种方法。所述方法包括使用至少一个硬件处理器以:提供脚本图形用户界面(gui),其中所述脚本gui包括一个或多个输入以用于图形地组合多个可视化脚本部件,其中多个可视化脚本部件中的每一个对应于基础脚本语言的结构;经由脚本gui接收多个可视化脚本部件的图形组合;以及将接收到的多个可视化脚本部件的图形组合转换成以基础脚本语言写入的脚本。所述方法可还包括使用至少一个硬件处理器以将以基础脚本语言写入的脚本编译成虚拟机程序以通过虚拟机执行。接收到的多个可视化脚本部件的图形组合中的可视化脚本部件中的一个或多个可对应于基础脚本语言的trigger结构,对应于trigger结构的一个或多个可视化脚本部件可包括触发条件和主体的可视化表示,并且trigger结构在于脚本内执行时,可使得每当发生从不满足触发条件的第一状态到满足触发条件的第二状态的转变时执行表示主体的指令。对于将通过脚本控制的装置,多个可视化脚本部件可包括装置识别符的表示和装置属性的表示。所述方法可还包括使用至少一个硬件处理器以:填充可选装置识别符的列表;当用户选定装置识别符的表示时,在脚本gui中提供经填充的可选装置识别符的列表;从经填充的可选装置识别符的列表接收对可选装置识别符中的一个的选择;以及更新装置识别符的表示以反映可选装置识别符中的选定装置识别符。所述方法可还包括使用至少一个硬件处理器以:填充与可选装置识别符中的选定装置识别符相关联的可选装置属性的列表;当用户选定装置属性的表示时,在脚本gui中提供经填充的可选装置属性的列表;从经填充的可选装置属性的列表接收对可选装置属性中的一个的选择;以及更新装置属性的表示以反映可选装置属性中的选定装置属性。

在实施方案中,本发明公开一种方法。所述方法包括使用至少一个硬件处理器通过以下操作将脚本编译成虚拟机程序:每当在脚本中检测到使用assign-and-wait-while-pending运算符来将值赋给装置的装置属性的assignment结构时,将assignment结构编译成一个或多个指令,所述指令将值赋给装置属性,并等待直到与装置属性相关联的状态指示与装置通信的驱动器已确认所赋的值表示装置属性的实际值,才继续执行从脚本编译的任何其它指令;每当在脚本中检测到trigger结构时,将trigger结构编译成一个或多个指令,所述指令每当发生从不满足trigger结构的条件的第一状态到满足trigger结构的条件的第二状态的转变时执行trigger结构的主体;每当在脚本中检测到every结构时,将every结构编译成一个或多个指令,所述指令在连续多次经过在every结构中定义的时间间隔中的每一次经过之后执行every结构的主体;每当在脚本中检测到pause结构时,将pause结构编译成一个或多个指令,所述指令在继续执行从脚本编译的任何其它指令之前在pause结构中定义的时间段的长度上暂停;以及,每当在脚本中检测到activation结构时,将activation结构编译成一个或多个指令,所述指令激活在activation结构中所识别的脚本以作为被编译的脚本的子脚本。当在脚本中检测到具有预定关键字的activation结构时,从activation结构编译的一个或多个指令可激活子脚本以与被编译的脚本并行地执行,并且,当在脚本中检测到没有预定关键字的activation结构时,从activation结构编译的一个或多个指令可激活子脚本以在继续执行从被编译的脚本编译的任何其它指令之前执行至完成。

在实施方案中,本发明公开一种方法。所述方法包括使用网关装置上的至少一个硬件处理器以:存储多个装置属性,其中所述多个装置属性中的每一个表示经由至少一个驱动器以通信方式连接到网关装置的至少一个物理装置的物理装置属性,所述驱动器与至少一个物理装置通信,其中多个装置属性中的每一个包括识别符、值以及确认的、未决的或未知的状态;执行控制脚本;以及每当控制脚本的执行使得多个装置属性中的一个的值改变时,将被改变的一个装置属性的状态设定为未决的,直到与物理装置属性通过一个装置属性表示的至少一个物理装置通信的驱动器确认一个装置属性的值与通过一个装置属性表示的物理装置属性的实际值相匹配,以及,一旦与物理装置属性通过一个装置属性表示的物理装置通信的驱动器确认一个装置属性的值与通过一个装置属性表示的物理装置属性的实际值相匹配,就将所述一个装置属性的状态设定为确认的。执行控制脚本可包括:实例化解析器以用于解析基础脚本语言;以及,通过经实例化的解析器,解析具有控制脚本的指令,并在控制脚本被解析时执行那些指令。执行控制脚本可包括:将控制脚本编译成虚拟机程序;以及通过网关装置上的虚拟机,执行虚拟机程序。

应理解,本文中公开的方法的实施方案中的任一个还可实施为包括至少一个硬件处理器的系统,所述硬件处理器经配置以执行存储在非暂时性计算机可读介质上的方法和/或指令,其使得处理器执行所述方法。

附图简述

本发明的关于其结构和操作两者的细节可部分通过研究附图来收集,其中相同的参考标号指代相同的部分,并且其中:

图1说明根据实施方案的控制基础架构;

图2说明根据实施方案的脚本执行环境;

图3说明根据实施方案的在基于云的平台与网关之间的实例关系;

图4a至图4e说明根据实施方案的用于创建脚本的用户界面;

图5a至图5h说明根据实施方案的用于网关管理的用户界面;

图6a至图6i说明根据实施方案的用于创建脚本的用户界面;

图7说明根据实施方案的实例统一线程模型;

图8a和图8b说明根据实施方案的控制基础架构的变化型式;

图9说明根据实施方案的通用驱动器抽象;以及

图10说明根据实施方案的处理系统,本文中描述的过程中的一个或多个可在所述处理系统上执行。

详述

在实施方案中,公开包含脚本语言的控制基础架构。控制基础架构可包括统一各种领域的数据架构。控制基础架构还可包括一个或多个网关,所述网关能够与一个或多个插件式硬件模块介接,所述硬件模块包括物理硬件装置或与物理硬件装置介接。每一网关可能能够使用任何给定传输来连接到硬件模块并与基于云的平台通信,并且可通过因特网协议(ip)寻址。另外,每一网关可包括装置管理器,所述装置管理器抽象在数据架构内的数据的标准化表示与数据的多个装置特定的表示之间转换所必需的逻辑。

控制基础架构的脚本语言可为统一并满足所有应用的需要的装置控制语言。基础脚本语言可以简化形式与用户界面(基于图形或文本的)配对以用于创建并编辑脚本。举例来说,可提供图形用户界面(gui)以允许用户使用基础脚本语言的子集来创建脚本。

虽然在本文中将使用某些函数名称、过程名称、命令名称、关键字等,但应理解,特定名称和关键字的选择是任意的,且因此,在不脱离本发明申请的范围的情况下,此类名称和关键字可用其它名称或关键字替换。

在阅读此描述之后,所属领域的技术人员应变得清楚如何针对各种替代应用实施各种替代实施方案。因此,即使本文中将描述某些实施方案,也应理解,这些实施方案仅作为实例和说明而非作为限制呈现。由此,各种实施方案的此详细描述不应被理解为限制如随附权利要求书中所阐述的本发明申请的范围或宽度。

1.平台

图1说明根据实施方案的基础架构,本文中描述的系统和过程可在所述基础架构中操作。基础架构包括平台110,所述平台包括数据库112或与所述数据库介接,并提供界面114(例如,web应用和/或web服务器)。如所说明,平台110和数据库112可在“云”中实施。云计算是基于因特网的计算的形式,其中共享资源和信息按需要提供给装置。然而,应理解,替代地,平台110和数据库112可实施为一个或多个专用服务器。

在实施方案中,界面114包括提供图形用户界面(gui)的web应用。gui可包括用超文本标记语言(html)或其它语言生成的一个或多个网页。平台110发送或提供gui以响应于来自用户系统(未示出)的请求。在一些应用中,gui可以向导的形式提供,在此情况下,可以连续方式提供两个或更多个用户界面(例如,网页),且所述连续的用户界面中的一个或多个可取决于用户或用户系统与一个或多个先前用户界面的交互。在实施方案中,gui可包括脚本gui,所述脚本gui使得用户能够通过将基本脚本语言的元素的可视化表示连贯在一起来图形地构造脚本。gui可包括内容和元素的组合,例如文本、图像、视频、动画、引用(例如,超链接)、帧、输入(例如,文本框、文本区、复选框、单选按钮、下拉式菜单、按钮、表单等)、脚本(例如,javascript)及类似者,包含包括存储在数据库112中的数据或从所述数据得到的元素,所述数据库可为本地的和/或可供平台110远程地访问。平台110还可对来自用户系统的其它请求作出响应。

替代地或除web应用外,界面114还可包括web服务。在此情况下,平台110可从用户系统接收请求,并以可扩展标记语言(xml)和/或任何其它合适的或期望的格式提供响应。在此类实施方案中,平台110可提供应用程序设计接口(api),所述应用程序设计接口定义用户系统可与web服务交互的方式。因此,自身可为服务器的用户系统可定义其自身的用户界面,并依赖于web服务来实施或以其它方式提供本文中描述的后端过程、方法、功能性、存储装置等。

应理解,对平台110的任何请求和来自平台110的响应(包含gui)可都通过网络来传送,所述网络可包含使用标准通信协议(例如,http、https)的因特网。

2.网关

在实施方案中,基础架构包括一个或多个网关120。每一网关120可从通过california的sandiego的systechcorporation提供的模块化网关族选择。通过systechcorporation提供的族产品包含多个模型,所述模型为多个配置选项提供最大灵活性。例如,500/800/1000/15000模型线包涵低成本、单用途网关,所述网关通常用于简单的桥接应用,以及用于简单的自动取款机(atm)、销售点(pos)以及售货应用。2000、3000以及4000模型线是全功能的通用网关、网桥以及路由器,所述网关、网桥以及路由器支持多个装置跨越多个本地或远程网络的连接,且通常用于多用途建筑、家庭以及远端场所应用。族装置可支持包含多个本地网络连接和用于因特网连接的多个宽带网络的组合。然而,应理解,来自其它制造商的其它网关也可用作网关120中的一个或多个。

每一网关120可经配置以经由宽范围传输协议(例如因特网)而与平台110通信。虽然网关120将被主要描述为经由因特网与平台110通信,但应理解,网关120可经配置以使用任何常规的通信协议来与平台110通信。

在实施方案中,网关120还能够经由一个或多个局域传输协议与一个或多个硬件装置控制器170通信,所述局域传输协议例如thingworxtm、z-wavetm、zigbeetm、bluetoothtm、wi-fitm和/或类似者。此经由多个协议进行通信的能力允许网关120为传输不可知且协议不可知的,并允许所述网关经由宽范围的复杂性处理控制系统。

可用于网关的任何特定配置的特定选项可通过硬件功能的物理存在控制,和/或通过与硬件功能的物理存在无关的电子配置在本地或远程地控制。可用作网关120中的一个或多个的族网关包括以下各项中的一个或多个:

●一个或多个硬件升级槽,所述硬件升级槽支持蜂窝模块和/或其它硬件选项,包含未来的硬件选项;

●架构,所述架构支持2g、3g以及4g蜂窝技术(例如,码分多址(cdma)、演进数据优化(evdo)、长期演进(lte)、全球移动通信系统(gsm)、单载波无线电传输技术(1xrtt)、高速分组接入(spa+)),以及未来蜂窝技术;

●一个或多个多以太网端口,包含具有多个独立的因特网协议(ip)地址的多个以太网端口;

●一个或多个普通老式电话服务(pots)端口(例如,v.90、v.92);

●一个或多个串行端口(例如,具有rs232、rs422和/或rs485物理接口),所述串行端口可被配置为标准串行端口(例如,用于pos和/或安全性应用)和/或dex和mdb端口(例如,用于售货应用);

●一个或多个通用串行总线(usb)端口;

●一个或多个microsd槽;

●对一个或多个本地无线技术的支持,所述本地无线技术包含wi-fitm(例如802.11a/b/g/n)、zigbeetm、z-wavetm、bluetoothtm、近场通信(nfc)、ant等;

●一个或多个传感器(例如,温度传感器、运动传感器等);

●一个或多个连接器,所述连接器用于外部通用输入/输出(gpio),例如,使用gpio和/或usb接口;

●一个或多个内部或外部电池;和/或

●对本地应用的支持。

3.数据架构

在实施方案中,通过平台110和网关120用于数据的通信、处理以及存储(例如,在数据库112和/或132中)的数据架构使得广泛分布的部件通过标准因特网协议层连接,使得数据值(例如,所述数据值可表示硬件测量或设置,在基于web的用户界面中做出的选择等)的变化可以可靠地传播遍及基础架构的部件(例如,平台110和/或网关120)。

在实施方案中,数据架构通过在平台110上且在网关120的控制器130内运行的软件实施,以在平台110与网关120之间提供数据传播。在实施方案中,数据架构利用基于javascript对象符号(json)标准的数据格式。然而,应理解,不同的数据标准可用作本文中论述的数据格式的基础。

在实施方案中,数据架构实施分布式数据服务器联合,所述数据服务器联合允许在本地网关120与平台110上的基于云的管理服务之间的数据协调以用于本地网关120的集中控制和配置,同时允许本地网关120和平台110在分布式部件之间的通信被中断时彼此独立地操作。另外,数据架构可改进用于表示通过跨越分布式系统的通信的时延产生的过渡数据状态的常规方法。数据架构可允许平台110和网关120在这些分布式部件之间的通信被中断时独立地操作。

在实施方案中,数据架构支持以下各项中的一个或多个:

●可扩展联合多服务器联网环境;

●用于数据完整性的状态属性的同步;

●针对每一属性的中心同步权威机构(例如,平台110),任何数目的客户端服务可订阅所述属性;

●离线工作和随后的重新同步;和/或

●用于部件和/或第三方应用的api。

从根本上说,数据架构可表示数据永久策略和通信协议,所述协议允许web应用、脚本语言、硬件接口以及第三方应用通过共同的抽象和查询语言(例如,经由api)与共享数据交互。数据架构可适用于在较小硬件装置(例如,网关120)以及较大因特网服务器(例如,门户网站)上实施。数据架构协议可为传输不可知的,并经由公共的因特网通信传输(例如,http、websocket、传输控制协议(tcp)等)工作。

如上文所提及,在实施方案中,数据架构的数据格式为json。然而,应理解,可使用除json外的格式,而不改变数据架构的本质特性。例如,此json数据可通过部件转换成在所述部件内部的格式。例如,通过每一网关120的装置管理器160接收的json数据可被转换成装置管理器160的内部格式。另外,平台110的每一实例可以适合于所述实例的操作环境的任何方式保留所述实例的本地数据。

图3说明根据实施方案的在基于云的平台110与网关120之间的实例关系。平台110可包括一个或多个数据服务器310,所述数据服务器使数据与多个网关120的多个网关服务器330(例如,在控制器130中运行)或其它客户端同步。客户端是使用由数据服务器310提供的api来连接到数据服务器310的任何软件模块。数据服务器310中的每一个可向彼此并向外部或内部客户端呈现刚好相同的api。(例如,界面114的)门户网站314和外部应用320(例如,thingworxtm)可使用此api来提供用户界面以用于经由数据服务器310控制并配置网关120。在实施方案中,网关120和任何其它客户端可经由node.js、http、socket.io或tcp介接到数据服务器310。

在实施方案中,每一网关服务器330是数据服务器310的轻量级实施。例如,网关服务器330可经精简以在较小的linux环境中运行,所述linux环境执行为网关120的控制器130中的操作系统。网关120上的内部服务,例如网关服务340、脚本管理器210以及装置管理器160,可经由node.js、socket.io或本地主机tcp直接地连接到所述内部服务的本地网关服务器330。

在实施方案中,数据服务器310可为或包括一个或多个云服务器。云服务器提供相同的连接协议和api,但为更加可扩展的且可经由唯一网关识别符来寻址,正如网关服务器330一样。每一云服务器可类似于网关服务器330,除了以下情况:因为云服务器可充当网关服务器330的群组的通信集线器,所以在云服务器连接到网关服务器330时,云服务器内的某些内部行为可为不同的。在实施方案中,每一网关服务器330是一个云服务器的客户端,而一个云服务器可具有多个客户端(但云服务器未必具有任何客户端)。另外,一个云服务器可为另一云服务器的客户端。

网关服务340、脚本管理器210以及装置管理器160是在实施方案中在每一网关120内部的过程,并且可使用数据服务器310的api来集成装置控制与数据架构,如本文中的其它地方所描述。

3.1.离线操作

在实施方案中,平台110使得用户能够作用于每一网关120的脚本和装置数据,即使是当网关120不连接到平台110(例如,由在网关120处的网络故障、机械故障等导致)时。这可通过将每一网关120的相关数据(例如,在每一网关上执行的脚本和驱动器)的镜像维持在平台110处实现。当在平台110与网关120之间建立连接时,此镜像数据与在网关120处的数据同步。

在实施方案中,每一网关120独立地操作,即使是当所述网关已从平台110断开(例如,由网络故障导致)时。这可通过将网关120的操作所需的所有数据维持在网关上的镜像本地库(例如,数据库132和/或脚本注册表214)中实现。当在平台110与网关120之间建立连接时,数据与存储在平台110处(例如,在数据库112内)的相关数据同步。

3.2.数据同步

当平台110与网关120连接时,平台110和网关120的镜像数据仓库持续同步。另外,在平台110处进行的数据改变(例如,经由界面114)传播遍及平台110(例如,从联合中的一个数据架构服务器传播到联合中的所有其它数据架构服务器)。

在实施方案中,平台110的客户端,例如脚本管理器210和装置管理器160,使用平台110的api来订阅相关数据。当订阅相关数据时,客户端被告知将影响在客户端处的动作的任何数据改变。这可导致平台110将命令发送到装置(例如,经由装置管理器160),改变用户界面(例如,在thingworx中)等。

3.3.同步状态

常规的分布式控制系统通常难以准确地表示在用户请求远程数据的改变的时间与知道改变已生效的时间之间的时延。在实施方案中,数据架构使用每属性同步状态来解决此问题。此机制可用于驱动可视化用户界面,例如,界面114的gui。

具体地说,存储在平台110处的每一装置属性可通过值和状态两者表示。在实施方案中,对于每一装置属性,所述值和状态必须一起设定。所述值表示所述装置属性的值,且所述状态表示所述装置属性的同步状态,正如平台110当前已知。例如,在实施方案中,状态可为“确认的”、“未决的”或“未知的。”

在实施方案中,对于数据架构联合中的每一数据元素(例如,装置属性),仅一个参与者被指定为所述数据元素的“权威机构。”例如,网关120上的装置管理器160是表示连接到所述网关120的物理装置的装置属性的权威机构。当权威机构将装置属性值设定为已知值时,装置属性状态被设定为“确认的,”指示权威机构确认此装置属性。当任何其它参与者(例如,用户界面,例如界面114的gui)改变装置属性值时,所述装置属性状态被设定为“未决的,”且将保持“未决的”直到装置属性值已成功地传播到权威机构,此时权威机构将设定装置属性状态为“确认的。”一般地,权威机构将具有“未决的”状态的装置属性解译为采取外部动作的请求,在此之后,权威机构将设定装置属性为适合的值并设定装置属性的状态为“确认的。”当无法确定装置属性的当前状态时(例如,在物理装置有缺陷的情况下),权威机构可将装置属性状态设定为“未知的。”

4.简化的图形用户界面(gui)脚本

在实施方案中,脚本图形用户界面(gui)提供新手或非技术用户对基础脚本语言的简化使用。脚本gui允许用户利用界面114的gui来直观地构造中等复杂的脚本行为,所述脚本行为随后自动地转换成基础脚本语言,例如,以用于在脚本执行环境150内的解析或编译。由脚本gui提供的功能可为基础脚本语言的功能的简化子集,且具体地说涉及通过在网关120和/或装置的数据架构中读取和/或写入数据来控制远程网关120上的行为。在实施方案中,界面114还可包括一个或多个工具,所述工具用于管理一个或多个网关120上的脚本的部署和激活和/或去激活。

脚本gui可包括一个或多个简单脚本用户界面,所述用户界面包括用于将脚本元素的可视化表示连接成完整的脚本的输入,所述完整的脚本随后可在被转换成基础脚本语言之前被转译成中间表示(在本文中被称为“gui脚本”)。替代地,可视化创建的脚本可在没有中间表示的情况下直接地转换成基础脚本语言。另外,脚本gui的用户界面可允许用户将脚本文本(即,用基础脚本语言表示)直接地插入到gui脚本中。另外或替代地,脚本gui可包括一个或多个基础脚本用户界面,所述用户界面使得用户能够使用基础脚本语言直接地写入脚本。当一起使用时,用户可从使用简单脚本用户界面来创建简单脚本逐渐地转变成使用基础脚本用户界面来用基础脚本语言直接地创建更加复杂的脚本。

在实施方案中,脚本gui包含以下属性中的一个或多个:

●多特征门户(例如,通过界面114实施),所述门户允许授权用户构造并管理脚本和脚本库,并将那些脚本库或来自那些脚本库的一个或多个脚本的特定集合安装在远程网关120上;

●用于产生gui脚本的一个或多个用户界面,所述gui脚本通过用数据架构的数据格式读取和写入装置和网关数据来控制远程网关120上的行为;

●用数据架构的数据格式将gui脚本存储为数据的能力;和/或

●工具,所述工具用于管理针对一个或多个网关120的脚本的部署和激活。

在实施方案中,脚本gui包括一个或多个简单脚本用户界面的直观集合,所述集合使用户经过创建gui脚本的过程。将参考图4a至图4e描述实例脚本创建过程:

(1)如图4a中所示,用户确定脚本是否将具有触发条件,或通过用户或通过另一脚本单独地激活;

(2)如果用户指定脚本将具有触发条件,如图4b和图4c中所示,那么用户选择一个或多个触发条件,所述触发条件可包含例如“与”、“或”以及“非”运算符;

(3)如图4d和图4e中所示,用户选择将在满足“触发”条件后执行的动作;以及

(4)用户将脚本保存(例如)到平台110的数据库112和/或一个或多个网关120的脚本注册表214。

4.1.更新网关

在实施方案中,在用户已使用脚本gui成功地创建或编辑脚本后,脚本gui将用于将脚本发送到一个或多个网关的输入呈现给用户。如果用户选择将gui脚本发送到网关(例如,通过选择所述输入和/或选择或以其它方式指定目的地网关),那么平台110将gui脚本发送到网关120(例如,经由因特网)。以此方式,平台110使得用户能够随时间推移做出许多编辑,并仅在每一编辑的每一次完成之后替换网关120上的脚本。

4.2.激活脚本

在实施方案中,已部署在网关120上的脚本将仅在所述脚本被激活时执行。网关120上的脚本可通过用户的动作(例如,经由界面114)或通过在被执行(例如,在脚本执行环境150中)的另一脚本中的“激活”指令来激活。

4.3.离线地创建脚本

传统的基于因特网的硬件布置中的问题是需要持续的因特网连接。此问题通过使用不一致的蜂窝数据连接而复杂化。在硬件装置失去其因特网连接的情况下,传统布置的用户将不能够对所述硬件装置执行任何更新,例如添加或修改所述硬件装置上的脚本。

本文中描述的数据架构的同步特征的实施方案避免此问题。用户可登入平台110的界面114的gui,即使是当通过用户管理的网关120不连接到因特网时。在此情况下,gui可前摄地(例如,在用户尝试更新网关之前)或反应性地(例如,在用户尝试更新网关之后)告知用户网关120离线。通过用户经由gui针对离线网关120执行的所有更新可以“未决的”状态存储。当先前离线的网关120重连到因特网并订阅平台110时,经重连的网关120将接收所有未决的更新并将更新后的数据的状态设定为“确认的”。“确认的”状态将被发送回到平台110,使得所述状态可将存储在平台110上的对应的数据的状态同步为“确认的。”之后,数据的经同步状态将在界面114的gui中反映。

4.4.管理多个网关

在实施方案中,平台110实现用户与网关120之间的多对多关系。一旦用户注册网关120(例如,经由界面114的管理gui),界面114的gui就可将用户可访问的所有网关呈现给经认证用户,如根据实施方案在图5a中所说明。

在实施方案中,用户可经由界面114的gui对用户可访问的网关120分类。例如,用户可创建类别,并将网关120的一个或多个表示移动到每一创建的类别中。任何分类可仅应用于当前用户,从而允许可访问相同网关120的其它用户以不同方式对相同网关120分类。替代地,通过一个用户对网关120的任何分类可自动地应用到另一用户对相同网关120的分类。根据实施方案,提供网关120的实例分类的gui的实例在图5b中说明。特别地,图5a和图5b中所说明的gui还指示每一网关的状态(即,“断开”或“连接”)。

4.5.在多个网关上部署并激活脚本

在实施方案中,脚本gui能够构造在用户的网关中的一些或全部上起作用的脚本,而不必针对通过脚本控制的每一特定装置来创建脚本。这使得单一用户能够在简单的用户体验内管理数百个网关。

例如,界面114的gui可包括用户界面,所述用户界面具有选择一个或多个脚本的输入和选择一个或多个网关的输入。如在图5c的实例实施方案中所说明,每一脚本与“网关”输入相关联。当用户选择脚本和用于所述脚本的“网关”输入时,显示用户的网关的全部的表示(例如,在置于gui的特定网页上的帧中的列表中)。用户随后可从所有网关的所述表示选择一个或多个网关,选定脚本应可用于所述一个或多个网关。一旦用户已选定网关和/或经由gui确认对网关的选择,平台110就可确保选定脚本安装在选定网关上,且gui可显示上面已安装有脚本的多个网关。

一旦脚本已被分布到选定网关,用户随后就可激活在那些网关上的所述脚本。如在图5d的实例实施方案中所说明,每一脚本与“激活”输入相关联。当用户选择脚本和用于所述脚本的“激活”输入时,显示上面安装有选定脚本的所有用户的网关的表示(例如,在整体都在gui的特定网页上的帧中的列表中),如图5e中的实例实施方案中所说明。用户随后可从上面安装有选定脚本的所有网关的所述表示选择一个或多个网关,应可针对所述一个或多个网关激活选定脚本。作为响应,平台110可经由与控制器130和/或脚本执行环境150的通信来激活选定网关上的选定脚本。

4.6.识别多个网关上的类似装置

跨越多个网关120复制脚本的困难是确保那些脚本能够与多个网关120中的每一个上的装置的不同集合介接。在常规的控制系统中,用户将必须在每一网关上重构脚本,针对多个网关中的每一个选择适合的装置集合。此过程对于非常大数目的网关和/或装置不可行。

在数据架构的实施方案中,以两种方式识别每一装置:(1)唯一的字母数字识别符;以及(2)没有特殊性要求的名称。在脚本引用装置识别符且脚本执行环境150(例如,编译器220或vm230)不能够用连接到网关120的匹配识别符定位装置(例如,因为已从另一网关复制所述脚本)的情况下,脚本执行环境150自动地搜索连接到网关120的相同名称的装置以替代使用。因此,只要网关120包含具有相同名称的装置,脚本就可在没有用户介入的情况下恰当地起作用。

4.7.作用于装置的群组

在实施方案中,数据架构提供装置分组。具体地说,用户可通过界面114的gui创建群组。一旦已创建群组,用户就可将任何数目的装置置于群组中。特定装置可在一个或多个装置群组中。脚本gui可使得用户能够在这些装置群组中的一个或多个上以及在个别的装置上创建脚本操作。图5f和图5g说明根据实施方案的在脚本gui中的装置群组的选择。在所说明的实例中,脚本gui可查询装置群组,并提供装置群组连同个别装置的可选择列表。用户可选择这些个别装置或装置群组中的一个以用于操作。在图5f和图5g中,用户选择“灯光”装置群组,并指定将“灯光”装置群组切换到“接通”的操作。

装置群组上的脚本操作作用于装置群组中的所有装置,例如,将任何改变或查询转发到装置群组中所包含的每一个别装置。在图5f和图5g的所说明实例中,脚本将把“灯光”装置群组中的所有装置切换到“接通。”以此方式,单一脚本操作可设定装置群组中的所有装置的属性的值。在装置群组内的特定装置不具有被设定的属性(例如,针对包含二进制开关和非二进制装置两者的群组将二进制开关值设定为“接通”)的情况下,可忽略针对那些特定装置的操作。

类似地,脚本gui可使得用户能够基于装置群组创建触发器。例如,脚本gui可查询装置群组,并提供装置群组连同个别装置的可选择列表以用于触发条件中。在实施方案中,如果“触发”条件是基于装置群组,那么“触发”主体将在装置群组内的任何装置满足“触发”条件时执行。例如,图5h说明在“灯光”装置群组中的任何装置切换到“接通”时将警报器设定为“闪光”的实例脚本。

有利地,装置群组的使用简化对具有相同功能的大量装置的管理。例如,单一脚本可告知管理员装置群组内的任何运动传感器是否检测到设施中的运动。这与常规系统相反,所述常规系统将需要针对每一运动传感器写入脚本。

5.脚本执行环境

在实施方案中,网关120提供支持用于控制网关120的基础脚本语言的脚本执行环境150。基础脚本语言和脚本执行环境150可经设计以允许最不熟悉编程概念的用户创建在多个领域中的复杂控制系统。如本文中所描述,通过小心的分层、抽象以及分割,且通过使用新的高级语言和解析技术,结合普遍使用数据驱动技术,可实施简单强大且自适应的通用控制语言。

图2说明根据实施方案的脚本执行环境150。如所说明,脚本执行环境150包括脚本管理器210。在实施方案中,脚本管理器210:

●接收脚本;

●经由脚本转换器212提供脚本从中间gui脚本(例如,在数据架构中表达为来自脚本gui的输出)到基础脚本语言的自动转换;

●经由脚本转换器212提供接收到的gui脚本和呈基础脚本语言的经转换脚本两者的同时句法检查,以确保正确性;

●将脚本存储在脚本注册表214中;

●从脚本注册表214检索脚本;

●处理脚本相关的命令和通知,例如将脚本添加到脚本注册表214,从脚本注册表214删除脚本,激活或去激活脚本注册表214中的脚本,和/或类似者;和/或

●即使失去与平台110的通信和/或针对网关120循环电源,也执行激活的脚本。

如上文所论述,在实施方案中,脚本管理器210包括或访问本地脚本注册表214。本地脚本注册表214可存储将通过网关120执行的任何脚本的本地版本,由此实现网关120的自主操作。这确保网关120即使失去与平台110的通信也可继续操作。

在实施方案中,基础脚本语言在句法上且在表达层面上类似于c,但被简化(例如,缺少声明)并针对控制系统概念的规范而专门化。基础脚本语言可经实施以处理以下各项中的一个或多个:

●通过甚至新手程序员可快速习得的小且常见的语言,允许控制系统概念的规范,而没有对程序员表达能力的任何限制;

●允许在所述语言的句法内直接地处理并操控外部装置和属性;

●提供线程隐喻,所述线程隐喻使得易于创建独立但互相通信的脚本线程的集合;

●消除程序员“声明”变量的需要并操控数据类型(例如,通过提供动态数据类型模型,所述模型支持仅四种内置类型,例如布尔型、64位整数、双精度实数以及字符串);

●允许语言可扩展性以支持效用函数的不断增长的库;

●在存储器和处理器时间中具有较小“占用区域”,同时允许脚本的并行的线程状执行(例如,在高级精简指令集计算机器(arm)处理器上),例如,通过用完全正交的操作码集合和简单编程隐喻实施虚拟机(vm)以执行用基础脚本语言写入的脚本;

●使得通过基础脚本语言提供的所有功能性能够在多个处理器(例如,平台110的多个服务器)上执行为异构互连网络的一部分,包含一个或多个网关120;

●使得用基础脚本语言写入的脚本能够执行为(i)与用于装置管理器160的过程分开的独立过程,和/或(ii)与装置管理器160统一的过程,以进行直接驱动器调用以实现最大效率和最小开销;

●支持开发人员的广泛的调试功能、错误日志、堆栈回溯、断点等;

●快速地适应于其它基础架构部件中的变化,例如数据架构和装置管理器160,而不改变现有脚本;和/或

●使用相同但受约束的句法来支持基础脚本语言的无线程版本,以供动态创建的解析器内(即,不在vm230内)的驱动器层164直接使用,使得用基础脚本语言写入的脚本能够用无线程(经由动态创建的解析器)和线程(经由vm230)模式两者执行。

在实施方案中,基础脚本语言还具有以下属性中的一个或多个:

●易于使用但强大的通用装置控制语言;

●由于与c的共同性而易于使用,包含对几乎所有c逻辑、算术以及按位运算符的支持,具有与c相同的运算符优先级;

●经典的“if-elsif-else”和“while”语句(例如,具有“break”和“continue”),类似于c;

●内置类型,包含布尔型、64位整数、双精度数、字符串(例如,utf-8文本)和/或未知的;

●任意嵌套的表达和函数调用,类似于c;

●函数的变量参数计数;

●函数可支持多个参数类型;

●块结构,类似于c;

●行和块注释,类似于c;

●支持日期、时间、一天中的时间、日历等,例如,呈现为双精度数并经受所有适合的运算符;

●数据类型、装置属性以及装置类型在运行时间处动态地确定,使得不需要声明,由此使得脚本为简单且自适应的;

●在激活后对vm程序的动态编译,而不会对所需脚本重新编译;

●线程模型,所述线程模型与函数调用隐喻紧密集成并包含参数传递(例如,通过值和/或通过引用);

●使用标准语言令牌来直接地引用装置和装置属性;

●内置库函数的套件,所述套件可通过开发人员扩展;

●局部和全局符号类型动态地确定,使得所述符号类型通过赋值来简单地创建;

●脚本可同步地或异步地激活、去激活、启动以及卸载其它脚本,并将参数/输出传递到其它脚本;

●从激活中的脚本(即,祖先脚本或父脚本)到激活后的脚本(即,后裔脚本或子脚本)的分层符号范围;

●动态构造的解析器,所述解析器允许语言的快速修改和/或扩展;

●触发语句(具有可选的“else”语句),所述语句用可选的滞后项对状态转变做出响应;

●任何符号或属性可具有未知值,且语言逻辑以未知值恰当的运行;

●“pause”操作,所述操作提供精确延迟;

●“when”结构,所述结构将一个或多个指令封锁在脚本中,直到满足指定条件;

●“every”结构,所述结构以精确时间间隔将一个或多个指令封锁在脚本中;

●内置控制台和输出日志;

●正交集操控和索引函数;

●“assignandwaitwhilepending”运算符(例如,“:=”),所述运算符处理困扰通用编程语言的经典异步问题;

●对于嵌入式系统理想的具有较小存储器占用区域的高性能;

●下推自动机vm汇编器编程模型;

●使用美国国家标准协会(ansi)c并不需要第三方外部库来加强可移性;

●在虚拟机内解译;和/或

●经由激活祖先脚本分层符号范围,其中所有脚本共享根本的祖先,所述根本的祖先的范围定义可用于所有执行的脚本的共用动态全局参数集。

另外,脚本执行环境150可具有或支持以下各项中的一个或多个:

●将gui脚本的表示转换成基础脚本语言的能力;

●用基础脚本语言直接地将语句插入到脚本gui中的能力;

●通过vm230并行地执行多个脚本(例如,数百个脚本)的能力,每个脚本在单独模拟的线程中;

●将脚本编译成vm程序以用于快速执行;

●在其它平台(例如,pc)上运行同时仍控制经由ip访问并连接到多个分布式网关120和平台110的装置的能力;

●调试设施;

●隐藏传输层和装置特定的协议的细节;

●通过vm230运行脚本的能力,即使是当从平台110断开时;

●通过名称和识别符进行的装置解析;

●对基础脚本语言隐藏驱动器指定的伪影;

●装置和装置属性的动态发现;

●用于自主操作的本地脚本注册表214;

●与用于装置管理器160中的适配器语言的共同性,以及与用于所提供的通用驱动器抽象内的物理到逻辑映射语言的共同性,以易于学习;

●从平台110动态下载新的和/或经修正的脚本,其中网关120在脚本的改变后自动更新;

●在云中可经由界面114的gui访问的脚本状态和日志;

●能够通过名称或识别符来引用和解析装置并将装置布置成群组,使得可创建通用(即,非装置特定的)脚本且所述脚本可在多个不同的设施(例如,具有不同外部硬件装置设施的网关120)上运行,且可通过简单地将属性分配给表示装置群组的虚拟装置来将属性分配给装置的群组;

●能够创建网关120的分层,并写入以虚拟装置为中介的元脚本(即,控制网关和其它脚本的脚本);

5.1.基础脚本语言

在实施方案中,基础脚本语言在通用解析或解译器框架内操作,所述框架可用于指定特定于每一界面的自定义语言句法,并用于通过提供回调来实施行为。此框架的技术方法例如在以下文件中描述:2007年4月24日发布的且标题为“用于解析数据的方法和系统(systemandmethodforparsingdata)”的第7,210,130号美国专利案(“‘130专利案”),以及2008年2月5日发布的且标题为“用于分析数据和执行词法分析的方法(methodforanalyzingdataandperforminglexicalanalysis)”的第7,328,430号美国专利案(“‘430专利案”),所述专利案都特此通过引用并入本文中。基础脚本语言的语言句法将在本文中使用在‘130专利案中描述的扩充巴科斯-诺尔范式(bnf)来描述,且所描述的代码实施使用在‘130专利案中描述的已注册的“解析器”和“插件”架构来组织。基础脚本语言的词法结构将在本文中使用在‘430专利案中定义的形式化来描述。虽然有可能使用其它解析器生成工具来实施所公开的基础脚本语言的功能,但在实施方案中,基础脚本语言基于在‘130专利案和‘430专利案中描述的库来构建。

5.1.1.词法结构

根据实施方案,下方的列表1表示根据在‘430专利案中定义的形式化的基础脚本语言的词法结构:

在实施方案中,除列表1中的“<begin>”与“<next>”分隔符之间的各种关键字和运算符外,基础脚本语言还支持以下变量词法令牌:

●令牌1:变量或符号值(例如,counter、idx_1、a、varname等);

●令牌2:具有换码的单或多字符常量(例如,“x、”“\n”、“\x34、”“abcd”);

●令牌3:十进制64位整数(例如,1234);

●令牌4和5:具有可选指数的双精度浮点数(例如,1.234、1.3e5);

●令牌6:装置属性(例如,@dev.temperature、@[xxydd].contact、@.prop等);

●令牌7:十六进制64位整数(例如,0xffff、0x34ab);

●令牌8和9:未经使用,因为所有的整数都是相同大小;

●令牌10:八进制64位整数常量(例如,03777);

●令牌11:未经使用,因为所有的整数都是相同大小;和/或

●令牌12和13:具有换码的字符串常量(例如,“helloworld\n”)。

在实施方案中,通过基础脚本语言支持的运算符集类似于在标准c语言内支持的运算符集,除了基础脚本语言可不包含自动递增/递减形式,且c逻辑操作(即,&&、||、!)可分别通过关键字“and”、“or”以及“not”替代,以便于新手程序员理解。

在实施方案中,除了内置类型外,基础脚本语言不允许定义类型,所述内置类型可紧密地对应于词法令牌。内置类型可包括:

●布尔型:布尔值(例如,保持为64位整数),所述布尔值可采用“真”或“假”的值。

●整数:64位整数值(但可使用不同大小的整数值);

●实数:双精度浮点值(例如,等效于c中的双精度数);

●字符串:任意长度的字符串值(例如,“helloworld”);

●符号:符号值,所述符号值自动地呈现数据类型和赋给所述符号值的任何项的值(例如,myvariablename),使得符号可具有任何基础类型(例如,布尔型、整数、实数、字符串或未知的);和/或

●属性:装置属性值(例如,@dev.temperature),其中属性的数据类型通过模式和处理所述模式的装置驱动器确定为任何基础类型(例如,布尔型、整数、实数、字符串或未知的)。

在实施方案中,基础脚本语言是动态类型语言,所述语言利用与装置相关联的所有字段和属性的数据驱动运行时间发现。换句话说,符号呈现数据类型和最近赋给符号的任何项的值。这消除了对与类型定义相关联的句法或逻辑的需要,所述需要使其它编程语言复杂化。

如上文所提及,在实施方案中,符号和属性数据类型可赋有基础数据类型中的任何类型,以及表示“unknown”的值。如本文中其它地方将描述,“unknown”值可具有特殊意义,尤其是在给表达式赋值时。

在实施方案中,基础脚本语言支持块和行注释两者,类似于c。基础脚本语言还可支持块语句(例如,通过括号“{”和“}”包围),类似于c。列表1中所说明的其它关键字的使用和语义将在本文中的其它地方参考基础脚本语言的句法来描述。

5.1.2.句法

根据实施方案,给出列表1中定义的词法结构并根据在‘130专利案中定义的形式化,下方的列表2表示基础脚本语言的句法:

列表2中的bnf的区段,从“expression”的左手侧(lhs)产生式开始并以“real”的lhs产生式结束,基本上指定可用于表达式内的所有运算符,和通过bnf内的声明序列实施的对应的运算符优先级规则。

在实施方案中,基础脚本语言的句法在根本上与c编程语言类似或相同,且因此,将不进行详细描述。此外,在实施方案中,所有这些语言功能都通过基于‘130专利案的解析器技术而内置在库中的代码实施,如通过呈“<@0:n>”形式的语法元素指示。出于此原因,基础脚本语言的这些方面,包含任意深度的嵌套表达式的赋值,将也不在本文中详细描述。在实施方案中,与标准c编程语言的唯一句法差异是用逻辑运算符“and”替代“&&,”用“or”替代“||,”且用“not”替代“!,”并在“primary”的产生式中允许值“unknown。”

在实施方案中,基础脚本语言支持对内置函数(返回某一值)和程序(返回“unknown”的值)的调用,可将零个或更多个逗号分隔的参数传递到所述内置函数和程序。每一参数可为任意表达式(包含嵌套函数调用),所述表达式产生可采用基础数据类型中的任何数据类型的形式的参数值。与此功能相关联的语法产生式包含“object”、“rstof_object”、“parameter_list”以及“rstof_param_list。”函数可确定传递到所述函数的参数的数量和数据类型,且许多函数可对于任何给定参数接受超过一个数据类型,并根据传递作为给定参数的数据类型操作。可用内置函数的取样在本文中的其它地方出于说明性目的而描述。

应理解,虽然本文中将使用并描述某些特定关键字,但可将任何数目的不同关键字(例如,传达相同或相似的理念)用作所描述的那些关键字的替代。

5.1.3.声明和参数化

列表2中的产生式,在“program”处开始并在“end_sfishid”处结束,涉及用基础脚本语言写入的脚本的声明和参数化。脚本包括一个或多个函数声明和主体。在实施方案中,在脚本源文件内遇到的第一声明被视为脚本的“主”函数。主函数表示在脚本已通过编译器220编译成vm程序并加载到vm230中以用于执行之后实际执行的代码。

在实施方案中,如果在主函数定义后出现另外的函数定义,那么这些另外的函数表示另外的静态范围的脚本,所述脚本可仅从具有同一脚本源文件的代码(例如,通过在“主”函数或另一函数内的代码)激活。正如主函数一样,这些另外的函数可采用零个或更多个参数。列表2中的产生式“program、”“function”以及“opt_more_funcs”描述脚本的整个主要和子例程内容。

在实施方案中,脚本可具有可选的相关联id(见例如,列表2中的产生式“script_prototype”)和字符串描述。id值一般与本文中在其它地方描述的gui脚本的id相同,从所述gui脚本可得出基础语言脚本(例如,经由脚本转换器212)。此脚本id形成方便的方式,通过所述方式,脚本可被引用回到原始gui脚本源(如果适当)。针对基础语言脚本的描述一般还可对应于gui脚本的描述。描述形成用于识别哪一个脚本在执行并用于其目的的方便的人可读方式。id和描述两者可用于调试界面内。在从gui脚本得出的基础语言脚本的情况下,转换过程(例如,通过脚本转换器212实施)可在基础语言脚本的描述前方插入gui脚本的原始名称(例如,呈“[原始gui脚本名称][描述的剩余部分]”的形式)。这允许脚本管理器210在必要时恢复原始gui脚本名称,所述原始gui脚本名称可符合或可不符合基础语言命名要求。

在实施方案中,所有脚本可接受零个或更多个逗号分隔的参数,所述参数可通过值或通过引用传递(见例如,列表2中的产生式“opt_io”和“more_opt_io”)。当在给定脚本内脚本原型内的识别符在关键字“value”之前时,所述识别符将在范围中且将初始化为通过调用脚本传递为所述参数的值的任何表达式的值和数据类型。当参数以此方式通过值传递时,在父脚本或激活脚本中的所传递值的改变将不影响子脚本中的值。子脚本还无法经由已通过值传递的参数而返回到值。

另一方面,如果在脚本的参数之前是关键字“reference,”父脚本或激活脚本必须传递包含将通过引用传递的符号或装置属性的名称的字符串值。在此情况下,在子脚本内执行的代码可通过参数的局部名称访问参数,但所有此类访问自动地解析为对初始命名的符号或属性的引用。结果是,如果子脚本更改已通过引用传递的参数的值,那么所述值立刻在父脚本中改变,且反之亦然。因为符号具有通过使用所述符号的脚本定义的范围,所以子脚本能够引用并更改在父脚本的范围内的符号值。此机制允许脚本之间的简单通信,并允许子脚本将结果值返回到父脚本(即,通过改变在父脚本的范围内的符号或属性的值)。脚本参数的使用在本文中的其它地方更详细论述。

5.1.4.简单语句

在实施方案中,基础脚本语言提供多个简单语句。这些简单语句中的每一个可通过分号与下一个分隔,所述分号在实施方案中是语句分隔符。如通过列表2中的“simple_stmt”产生式所说明,无论简单语句可存在于何处,所述简单语句都可被包含另外的内部语句的块语句(即,“{more_statements}”)替代。另外,在任何简单语句为合法的情况下,空语句(即,只有“;”)是合法的。

在实施方案中,可用于基础脚本语言中的简单语句包括以下各项中的一个或多个:

●“break:”可用于任何循环内以立即中断包含“break”的循环。“break”语句在功能上与c中的“break”语句相同。出现在任何循环外部的“break”语句可忽略。

●“continue:”可用于任何循环内以立即使得循环的下一迭代开始。“continue”语句在功能上与c中的“continue”语句相同。出现在任何循环外部的“continue”语句可忽略。

●“pause:”使得脚本在指定量的时间上暂停且不进行其它操作。“pause”语句看起来就像对名称为“pause”的函数(见例如,“simple_stmt”产生式)的函数调用一样。然而,所述“pause”语句的实施可以不同方式处理,如在本文中的其它地方所说明。在实施方案中,“pause”语句接受两个参数:(a)整数或实数表达式,所述表达式指定构成所述暂停的时间单位的数目,以及(b)字符串值,所述字符串值包含合法的固定长度时间单位(例如,“week、”“day、”“hour”、“minute”、“second”或“tick,”和/或这些单词的复数形式,例如,“weeks,”...“ticks”)中的一个的名称。因此,语句“pause(1.5,‘seconds’)”将使得当前脚本的活动暂停1.5秒,同时允许并行地执行的任何其它脚本在暂停期间继续正常执行。作为实例,“pause”语句可用于将简单的延迟引入到脚本中,同时等待现实世界的事件达到稳定状态;

●“@devname.property=x”(即,某一形式,其中x表示任何任意复杂的表达式,devname表示任何装置名称,且property表示通过devname表示的装置的任何装置属性):将赋值运算符(即,“=”或“:=”)的右手侧的值(即,通过“x”表示的值)赋给通过“@devname.property”指定的装置属性;

●“symbolname=x”(即,某一形式,其中x表示任何任意复杂的表达式,且symbolname表示任何符号的名称):将赋值运算符(即,“=”或“:=”)的右手侧的值(即,通过“x”表示的值)赋给通过“symbolname”指定的符号。如果“symbolname”是已通过引用(与值相对)传递到脚本的参数的名称,那么最终赋值可赋给在父脚本的范围内的装置属性或所引用的符号;

●对内置程序或内置函数的调用(丢弃结果值)构成有效的简单语句(见例如,列表2中的“assign_or_call”);

●“deactivatemyscriptname()”(即,某一形式,其中myscriptname表示任何任意脚本的名称):立即去激活通过“myscriptname”表示的命名脚本。脚本可同时被激活(在不同的vm线程中并行的),或不同时被激活(即,串行的)。“deactivate”语句用于去激活同时运行的脚本。在实施方案中,“deactivate”语句不应用于没有关键字“concurrently”的已激活的脚本。每当脚本被去激活时,所有后裔脚本也可被去激活。去激活从vm环境去除脚本;和/或

●“activatemyscriptname(...)”(即,某一形式,其中myscriptname表示任何任意脚本的名称,且“...”表示逗号分隔的参数的任意长集合,包含零个参数):激活通过“myscriptname”表示的命名脚本,且可选地通过值或通过引用将一个或多个参数传递到脚本。在实施方案中,激活的脚本是调用“activate”语句的脚本的子脚本(且可使用关键字“concurrently”激活以同时运行)。激活将命名的脚本添加到vm环境以作为激活中的脚本的子脚本,并开始新近激活的脚本的执行。

5.1.5.循环和条件语句

在实施方案中,基础脚本语言提供仅单个循环语句。在实施方案中,此单个循环语句是“while”循环语句。“while”循环可在功能上和句法上与c中的“while”循环相同。在循环的每一迭代后,评估“while”条件,当“while”条件为真时执行循环主体,且当“while”条件为假时终止循环。在实例中,“while”条件可表达为“while(true)”以创建无限循环,所述无限循环可通过循环主体内的“break”或在祖先脚本中执行的“deactivate”语句终止。意图连续运行的大部分脚本将包括外部无限“while”循环。在没有外部无限“while”循环的情况下,脚本将运行至完成,且随后自动地去激活(可能地将执行的结果用通过引用通过激活中的脚本传递的参数返回到激活中的脚本)。通过其它语言提供的此标准循环结构的简化简化了学习曲线。应理解,在替代实施方案中,可使用另一循环结构(例如,“do...while”语句、“repeat”语句、“for”语句等)来替代“while”循环结构。

另一方面,在实施方案中,基础脚本语言提供比常规编程语言更复杂的条件语句以支持控制系统专门化。基础脚本语言的“if”语句可类似于c中的“if”语句,除了在实施方案中,基础脚本语言通过禁止任何条件或循环语句直接嵌套在另一条件语句的主体内来避免c中的悬挂“else”问题和其它问题。这意味着人们不能写入“if(x)statement;elseif(y)statement;...”的结构,因为在没有围绕的块语句的情况下禁止第二个“if”语句。另一方面,在基础脚本语言中将可接受“if(x)statement;else{if(y)statement;}”的结构。这同样适用于在“if”子句内嵌套条件语句或循环。“elseif”结构允许在创建条件语句的扩展列表时克服此限制。

在实施“trigger”条件语句的实施方案中,“trigger”语句,类似于“if”语句,也可具有可选的“else”子句。“if”与“trigger”语句之间的差异是,在“if”语句中,在评估条件时条件的值确定执行“if”语句的哪个分支(即,“if”子句或“else”子句),而在“trigger”语句中,必定存在正确的布尔条件值和到/从正/假值的转变,以便执行“trigger”子句一次。相同的子句将不再执行,直到条件从满足的条件改变且然后返回到满足的条件。对于“trigger”语句在外部循环内的最初执行,先前状态被视为“unknown,”所述“unknown”意味着,在外部循环的第一次迭代中,“trigger”语句表现得像“if”语句,但在外部循环的每一随后的迭代中,“trigger”语句需要到满足的条件的转变。相同的转变要求适用于“trigger”语句的可选“else”子句。换句话说,“trigger”子句将在满足条件后执行一次(在第一次迭代上或在转变之后),且“else”子句将在条件不再被满足时执行一次(在第一次迭代上或在转变之后)。

“trigger”语句是用于处理在现实世界中的属性以某一明显方式改变状态时发生的情况的理想工具,而不必担心跟踪状态以确保脚本并不一遍又一遍地执行相同操作的复杂性。因此,“trigger”语句是处理跟踪控制系统中的状态的复杂性的创新方法。

在实施方案中,“trigger”语句可接受第二参数(即,除触发条件外),所述第二参数表示与触发条件的任何比较必须超出以便检测到“边缘”(即,状态转变)的变量或阈值。例如,对于语句“trigger(a>100,1),”直到“a”的值在增加方向上超出101或在下降方向上下降至低于99时才出现边缘。此句法将“滞后”添加到“trigger”语句。滞后可用于避免例如在温度徘徊在100左右时的常见问题,因此快速地触发“trigger”和“else”子句两者的一系列调用,而非通过断点值在每一转变上的单个触发。

在实施方案中,基础脚本语言还实施“every”语句。“every”语句满足定期地执行代码的主体的控制系统要求,而非另外跳过所述代码的主体,且可尤其有益于监视函数和具有中间静止的常规活动的产生(例如,洒水车控制系统)。“every”条件语句琐碎地处理所有此类情况。对于“every”语句,条件不是布尔条件,而是整数、实数、双精度数或日期(见例如,本文中在其它地方描述的“stringtotime”的内置函数),其指定将在“every”语句的主体的每一次执行之间传递的经过时间。类似于“trigger”语句,第一次在循环内遇到“every”语句时,先前值是“unknown,”且因此,执行“every”语句的主体。在循环的每一随后迭代中,跳过“every”语句的主体直到已经过指定时间,此时“every”语句的主体再执行一次。

5.1.6.线程模型

在实施方案中,基础脚本语言实施简单但强大的线程模型,如通过“activateconcurrently”语句指定。为说明此特征和此特征如何与基础脚本语言的其它功能交互,将参考下方的列表3描述简单的测试案例实例:

列表3的实例中的主脚本是“illustratethreading,”所述脚本不采用参数且同时激活被称为“sawtooth”的局部声明的子脚本(即,“illustratethreading”是父脚本,且“sawtooth”是子脚本),从而通过引用传递单个参数,所述参数在“sawtooth”内称为符号“property。”当激活“sawtooth”时,“illustratethreading”将装置属性“@thermometer1.temperature”(例如,表示被称为“thermometer1”的装置的温度值)传递作为在“sawtooth”内称为符号“property”的参数。“sawtooth”子脚本执行无限循环,在所述无限循环内,“property”的值交替地递增至上限110,且随后递减至下限90。因为“@thermometer1.temperature”通过引用传递,所以“sawtooth”子脚本中的“property”的值的改变立即在“@thermometer1.temperature”中反映出。结果是“sawtooth”子脚本以与主脚本“illustratethreading”异步且完全并行的线程创建“@thermometer1.temperature”属性的值的三角波或锯齿波。在“sawtooth”子脚本内传递到“pause”语句的值设定所产生的锯齿波的频率。

在激活“sawtooth”子脚本之后,主“illustratethreading”脚本进入循环,其中每当执行内部“trigger”子句或“else”子句时,定义条件的变量递增一次。因为“trigger”语句的每一子句在“@thermometer1.temperature”的值经过100的均值时仅执行一次,所以对于符号“heatwave”和“cooling”中的每一个,恰当执行的“illustratingthreading”脚本应产生最终值4。注意,同步子线程“sawtooth”通过更改装置属性“@thermometer1.temperature”的值来直接地且同时地与父脚本“illustratethreading”交互,由此交替地迫使“trigger”语句的“trigger”子句或“else”子句在每当所述值在任一方向上经过100时执行。

此简单精巧设计的实例说明线程模型的实施方案的能力和简单性,如通过“activateconcurrently”语句所提供。“activateconcurrently”语句可用于创建复杂的系统,所述复杂的系统将对用其它编程语言实施具有大得多的挑战性,且将需要高得多的水平的编程专业知识。并行线程的实际实施将在本文中的其它地方参考vm230的实施方案描述。

5.1.7.内置函数

在实施方案中,基础脚本语言可提供内置函数的库。以下是可在基础脚本语言的库中提供的内置函数中的一些的非穷尽性列表,其中“[i]”指示整数参数,“[b]”指示布尔参数,“[f]”指示实数参数,“[s]”指示字符串参数,且“[v]”指示空返回值(即,程序而非函数):

●[f]stringtotime([[s]datetimestring]):将日期(和/或可选地,时间)字符串转换成双精度日期。在实施方案中,日期必须用以下“yyyy/mm/dd[hh:mm[:ss[:tt]][am/pm]]”的格式指定。所述函数可仅支持公历。滴答值“tt”(如果存在)表示一秒的1/100(范围为00...99)。日期可指定为“0000/00/00”以便将一天中的时间值/偏移转换成等效双精度值。如果日期字符串是无效的,那么可返回值0.0。被返回的双精度日期的整数部分是日期序列号(sdn)。sdn是日期的顺序编号,其中sdn1是公历公元前4714年11月25号,且sdn2447893是1990年1月1号。此日期编号系统有时被称为“julian”日期,但为避免混淆我们在本文中使用术语“sdn。”实际值的小数部分包含一天中的时间,使得一小时=1/24.0,一分钟=1/1440.0等等。此外部表示的优点是以此格式表示的日期可使用基础脚本语言的普通算术运算符来容易地比较和操控。如果省略“datetimestring”参数,那么函数返回当前日期和时间值。此函数还接受形式“yyyy-mm-ddt...”的字符串,所述字符串可通过本文中的其它地方描述的脚本gui输出(其中从t向前的所有字符被忽略);

●[i]round([f]realvalue):将实数四舍五入到最近的整数值;

●[i]int([i/r/s]avalue):将整数、实数或字符串值转换成整数值。字符串转换可类似于c中的“strtoll()”函数;

●[f]real([i/r/s]avalue):将整数、实数或字符串值转换成实数值。字符串转换可类似于c中的“strtod()”函数;

●[s]sprintf([s]formatstring,...):类似于c中的“sprintf()”函数,除了整数和实数可变自变量大小始终分别为int64和双精度数;

●[f]random():产生在0至1的范围内的随机实数;

●[i]randomirange([i]min,[i]max):产生在“min”至“max-1”的范围内的随机整数;

●[i]setoptions([i]options/[s]optionsstr):用于开始选定的解析器选项。此函数可用于调试脚本的选定部分,而不会通过跟踪其它的每一项而使控制台混乱。字符串形式允许符号化地设定选项。在执行所设定的操作后,此函数返回选项设定以作为结果;

●[i]clroptions([i]options/[s]optionsstr):清除指定的解析选项。此函数与setoptions()相反,并在清除操作后返回选项设定以作为结果。字符串形式允许符号化地清除选项;

●[i]getoptions():获得并返回解析选项的当前设定;

●[s]timetostring([[f]datedouble]):将双精度日期转换成公历日期字符串,随后是时间值(24小时制);

●[i]timeelement([f]datedouble,][s]elementname):获得指定时间元素以作为来自日期双精度值的整数。“elementname”的有效字符串值是:“year”(年值),“month”(在用于1月的0与用于12月的11之间的月值),“dayofyear”(在1与365之间的一年中的天数),“day”(在1与31之间的一月中的天数),“dayofweek”(在用于星期天的0与用于星期六的6之间的一周的天数),“weekdayofmonth”(从1至5的一月中的某周的天数,例如,一月的第3个星期天),“hour”(在0与23之间的一天的小时),“hour12”(在1与12之间的钟面小时),“ampm”(在用于am的0与用于pm的1之间的am/pm),“minute”(在0与59之间的一小时的分钟),“second(”在0与59之间的一分钟的秒),和/或“tick”(在0与99之间的一秒的滴答);

●[f/i]timeunit([s]unitname):返回等效于指定的固定长度时间单位的双精度值。值“unitname”字符串是“week”、“day”、“hour”、“minute”、“second”以及“tick。”例如,表达式“3*timeunit(‘week’)”将用于获得三周的双精度值等效物。此函数可取决于哪个合适而返回实数值或整数值;

●[s]exit([s]areason):使得当前脚本清楚地退出,且可选地(向控制台)显示退出的原因,如果通过“areason”参数指定的话;

●[i]linenum():返回当前脚本的源文件中的当前行号;

●[s/i/f]indexset([i]index,[s/i/f]set1,...[s/i/f]setn):通过索引从给定成员列表选择特定的成员集,并返回选定成员作为结果。如果指定索引在范围外,那么返回指示“novalue”的值。函数的返回数据类型通过集合成员的数据类型(所述集合成员的数据类型必定全都相同且为整数、实数或字符串数据类型中的一个)确定;

●[i]setindex([s/i/f]src,[s/i/f]set1,…[s/i/f]setn):比较“src”与所提供的可能匹配值的集合中的元素中的每一个,并在找到匹配时返回所找到的匹配的索引(从1开始),或在未找到匹配时返回零。如果“src”为整数,待检查的其余的集合值必定也为整数。类似地,如果“src”为字符串,那么待检查的其余的集合值必定也为字符串,并且,如果“src”为实数,那么待检查的其余的集合值必定也为实数。此函数表示用以针对值的集合中的成员关系检查值的方便方式,并且可用仅单个函数调用来替代大量的个别比较;

●[f]timeofday([[f]datedouble]):返回“datedouble”的对应于一天中的时间的小数部分;

●[f]sunrise():返回对应于在当前日期上的当前位置处的日出的小数datetime值。如果在当前日期上的当前位置处太阳未升起,那么函数返回指示“unknown”的值。否则,函数返回所请求的小数日期双精度实数值;

●[f]sunset():返回对应于在当前日期上的当前位置处的日落的小数datetime值。如果在当前日期上的当前位置处太阳未落下,那么函数返回指示“unknown”的值。否则,函数返回所请求的小数日期双精度实数值;

●[i]rangeindex([i/f]src,[i/f]set1,…[i/f]setn):类似于setindex()函数,但在集合中寻找匹配的“lessthanorequalto”值,而非相等。因此,此函数可用于索引数值范围的有序集合,由此替代较大数目的条件语句。不同于setindex()函数,在rangeindex()函数中禁止字符串值;

●[s]consolemessage([s]formatstr[,…]):执行与c中的“sprintf()”函数类似的函数,返回所产生的字符串作为结果,且同时将所产生的字符串发送到控制台。此函数可用于产生调试或进展消息;

●[v]log([s]action,[s]formatstring[,…]):对应于脚本gui“log”命令,并将所得字符串发送到界面114的gui的登录页面,由此充当记录整个系统活动的方式。在实施方案中,脚本gui自身仅传递简单的字符串。然而,广义“log”函数将第二参数视为c“sprintf()”兼容格式区分符。所传递的任何另外参数用于替换值,正如c中的“sprintf()”一样。因此,最终的日志输出可包含可变值,而非仅固定字符串;和/或

●可提供多种其它内置函数,包含但不限于以下各项中的一个或多个,以下各项已经选择以说明环境功能:

[b]scriptactive([s]scriptname):在通过“scriptname”指定的脚本活动且在vm230内运行时返回“true,”以及否则返回“false。”注意,对于在脚本内声明的子脚本,仅激活中的脚本具有可视性。因此,仅仅激活中的脚本可确定子脚本的状态;

[b]between([i/f]val,[i/f]low,[i/f]high):检查通过“val”表示的值是否在通过“low”和“high”表示的限制值之间;

[i]configoptions([i]index,[s]optionstoset,[s]optionstoclear):动态地改变系统配置和/或调试选项;

[b]known([s]asymbol[,[s]devtype]):确定符号是否是“known;”

[v]forget([s]asymbol[,[s]devtype]):“forgets”符号的定义或值;

[v]newblock_pid([s]asymbol,[s]currentval,[f]windupguard,[f]propgain,[f]intgain,[f]derivgain):创建参数化比例-积分-微分(pid)控制器。这是能够创建具有持续状态的任意块的实例;

[i/f/s/v]updateblock([r]blockref{,[i/f/s]paramn}):更新“block”的状态;

[s]record([s]adschannel,[s]aname,[i/f/s]avalue[,[i/f]deltavalue]):将值记录到“datastream”虚拟装置的指定信道;和/或

[s]setdevice([s]devnameandorref):设定通过所允许的语言形式“@.propertyname”意指的装置引用。在本文中的其它地方描述的适配器语言中,此隐式装置可通过上下文自动设定。

5.1.8.解析器上下文和符号

在实施方案中,基础脚本语言中的脚本可通过以下操作执行:(i)通过编译器220编译成在vm230中执行的vm程序;或(ii)通过解析器直接地解译,而不必被编译成vm程序。

如在本文中的其它地方所论述,在基础脚本语言中,符号一被赋值并接受最近赋给符号的内容的数据类型和值,就在局部范围内被创建。换句话说,基础脚本语言是动态类型的语言。符号是基本解析器抽象能够使任意上下文与解析器的任何给定实例相关联的一个实例。

在实施方案中,解析器结合值将符号存储为字符串,包含符号的名称,所述值可具有内置数据类型(例如,布尔型、整数、实数、字符串或未知的)中的一个。每一符号还可具有相关联的标志值。例如,标志可用于指示,特定符号实际上是已通过引用传递的脚本参数,在此情况下,出于读取或写入目的而访问所述符号的任何代码可遵循引用以执行读取或写入。每当解析器遇到符号名称时,所述解析器可在本地解析器的符号注册表中实施查找以寻找符号名称的条目,且随后在符号注册表中检索或设定数据类型和值。在实施方案中,使用‘430专利案的词法分析器抽象来索引符号注册表以用于快速查找。这使符号查找几乎是瞬时的,而不管符号注册表中的符号的数目。

解析器抽象还支持解析器之间的父子关系的创建。例如,在跟踪给定父脚本的子脚本时利用此父子关系。每个和每一脚本,无论是父脚本还是子脚本,都具有相关联的解析器,而不管所述脚本是直接地在所述解析器内还是在vm230内执行。在实施方案中,vm230不使用解析器来解译执行的脚本的操作码,而是确实使用所述解析器来维持上下文和符号以及脚本所有权的层次。这意味着,相对于在解析器上下文内实施的功能,在基于解析器的直接执行与vm230执行之间的操作不存在差异。采取将脚本转换成vm程序以用于在vm230中执行的额外步骤的主要原因是,vm程序的速度可优于基于解析器的形式。vm程序还更易于理解并描述线程实施的实施方案。

解析器之间的父子关系和符号被维持在解析器上下文内的事实意味着,基础脚本语言可维持分层符号范围。具体地说,如果在子脚本的局部脚本范围内未声明相同名称的符号,则子解析器可直接地引用父解析器内的符号。然而,此特征可被停用以避免可能的混淆,因为,在‘130专利案中描述的抽象中,所有解析器通过“cloning”祖先解析器动态地创建。这意味着基础脚本语言的所有解析器都是此祖先解析器的后裔,所述祖先解析器本身在开始时通过列表1中的词法分析规范和列表2中的bnf规范动态地创建。因此,将祖先解析器范围用作全局变量的库,所述全局变量可从所有脚本访问且可在脚本设计者需要时使用。可定义专门初始化脚本,所述脚本设定此祖先上下文中的所有全局变量的初始值。

在实施方案中,当将经编译的脚本运行为vm230中的vm程序时,解析器上下文具有到和来自vm程序的双向链接,所述vm程序已被加载到vm230中以用于执行。

5.1.9.控制特定的结构

在实施方案中,基础脚本语言具有特定于控制领域的多个独特功能。虽然这些功能中的一些在本文中的其它地方更详细描述,但现将简单地描述每一所述功能。

在实施方案中,数据架构使用数据格式,所述数据格式包含与每个和每一装置属性相关联的状态字段。此状态字段可采用指示“确认”的值、指示“未决”的值,或指示“未知”的值。与特定装置控制器170通信的装置驱动器166是所述特定装置的属性和属性状态的权威机构。当数据架构中除装置属性的权威机构外的任何部件(例如,gui、解译器、vm230等)请求对属性值的改变时,属性的状态设定为“未决。”随后,权威机构(即,对应于与给定属性相关联的装置的装置驱动器166)以所实现的值(所述值可能不同或可能并非不同于所请求的值)回复,且属性的状态设定为“确认,”指示现实世界值已设定为所请求的值。此使用“未决”和“确认”状态的方法实现装置属性变化在整个系统上的受良好控制的分布。

在实施方案中,为改进性能,脚本执行环境150维持所有已知装置属性的状态的内部高速缓存。高速缓存中的条目可使用可用函数(例如,rg_setpropertystate()和rg_getpropertystate())来创建、更新和读取。对于每一装置属性,高速缓存包含对装置属性的引用、值和数据类型以及状态。当装置属性值被脚本读取时,所述装置属性的值一般将来自此内部高速缓存,使得vm230不必等待来自装置驱动器166的响应。装置驱动器166负责在每当装置属性值改变时调用函数(例如,dm_devmgrnfy()),以更新内部高速缓存中的装置属性值。结果是内部高速缓存中的装置属性值一般将不具有“未决”状态,因为所述装置属性值通过其相应的权威机构(即,相应的装置驱动器166)更新,从而产生“确认”状态。

必须等待来自装置驱动器166的实际更新以便改变装置属性值的内部表示的影响是控制系统的特征,所述特征常常对不习惯于使用实时编程的程序员造成混淆。在标准的编程隐喻中,当设定某一值时,可假定已设定所述值。然而,在现实世界的控制系统中,当设定某一值时,可能不能立即获取所述值,而是仅在命令到达装置且装置按命令操作后才获取所述值。例如,缺乏经验的程序员可写入脚本,例如下文的脚本,并预期log()消息将永不被发送,因为“if”条件应永不被满足:

相反,在控制系统环境中,log()消息很可能将被发送,因为“@thermostat.setpoint=60;”语句到“if”条件被测试时不太可能被适当的装置驱动器确认(即,“@thermostat.setpoint”的内部高速缓存值将很可能仍为70,因此,满足“if”条件)。这是不熟悉实时编程的程序员混淆的源。

有利地,“未决”状态的存在为此混淆的源提供解决方案。在基础脚本语言的实施方案中,存在可应用到装置属性的两个相异赋值运算符:“=”和“:=。”“:=”赋值运算符在本文中可被称为“assignandwaitwhilepending”运算符。如果在以上脚本中的“@thermostat.setpoint=60;”被“@thermostate.setpoint:=60;”替代,则脚本将按预期操作。具体地说,log()消息将不被发送。

每当脚本将值赋给装置属性且随后在不久之后引用所述值时,“:=”运算符是适合的。为实施此“assignandwaitwhilepending”运算符,实施vm230的逻辑,使得当脚本使用所述运算符对装置属性赋值时,所述逻辑将内部高速缓存中的装置属性的状态设定为“未决,”但不改变内部高速缓存中的装置属性的值。最终,权威机构(例如,具有属性的装置的装置驱动器166)将改变内部高速缓存中的装置属性的值,并将内部高速缓存中的状态更新为“确认。”对于以上实例,“:=”运算符可用vm汇编器格式实施为:

如所说明,在load“:=”运算符的操作码后添加标签和跳跃,且jmc操作码知道所包括的属性(“@thermostat.setpoint”),因为所述操作码在load后仍在堆栈上。在此情况下,jmc操作码将使得逻辑在属性的状态仍为“未决”时封锁(即,继续跳回到标签“l1”)。换句话说,语句“@thermostat.setpoint:=60;”的使用使得逻辑等待直到赋值已被确认,才继续执行下一语句。最终结果是用以解决常规的控制语言中的普遍问题的优良的解决方案。

根据实施方案,基础脚本语言的另一控制相关的特征是能够在语言的句法内直接地处理装置属性(例如,如在以上实例中的“@thermostat.setpoint”中)。另外,由于基本数据架构的和通过脚本执行环境150在开始时订阅的模式,基础脚本语言已知道所引用的属性的数据类型而不需要任何声明。换句话说,在运行时间处发现关于装置和其属性的所有事物,使得不需要任何编辑、编译或构建周期来进行改变。这使得基础脚本语言以其它语言不用的方式自适应。

在实施方案中,装置可通过名称、id或名称和id两者来引用。因此,以上引用的完整句法可为“@thermostat[deviceid].setpoint。”这是通过从gui脚本语言得出的脚本使用的格式。脚本执行环境150(例如,在解析器或vm230内)的逻辑尝试通过以下操作解析所引用的装置:(1)首先,通过所述装置的id(如果存在),以及(2)其次,如果所述失败,通过所述装置的名称。结果是脚本可从一个网关120复制到另一网关120,且即使所复制的脚本中的装置id可能为无效的,如果名称类似的装置存在于新网关120上,则所复制的脚本也正常地在新网关120上运行。具体地说,脚本执行环境150将以透明方式将所复制的脚本中的丢失的id更新为新网关120上具有与所引用的装置相同的名称的第一装置的id。类似地,如果装置重命名,则当脚本执行环境150(例如,vm230)发现在执行中的脚本中所引用的重命名装置不存在(即,因为所述装置已经重命名)时,vm230通过所引用的装置的id查找新名称,且如果找到,自动地将脚本中的装置的名称改变为新名称。脚本在没有中断的情况下继续正常运行。特征的此组合通过自动地编辑脚本以使所述脚本适应于上面执行有所述脚本的当前网关120的特定装置配置来使复杂安装的设置变容易。

在实施方案中,基础脚本语言支持装置群组。装置群组表示为虚拟装置,所述虚拟装置可包含任何数目的物理装置和/或其它虚拟装置的集合。装置群组实现通用脚本的创建,所述通用脚本在控制上下文中是高度有利的特征。另外,装置群组使得能够使用单个语句(即,单个赋值运算)将值赋给所有装置群组成员(即,装置群组内的所有物理或虚拟装置)的属性。

在实施方案中,基础脚本语言提供“trigger”语句,如本文中在其它地方所描述。“trigger”语句是对装置属性值或其它值的边缘(即,状态转变)作出响应的控制特定的句法结构。

在实施方案中,基础脚本语言用同步形式(正如标准函数调用一样)或异步线程形式通过关键字“concurrently”的简单使用来统一脚本激活和去激活的概念。关键字“concurrently”创建对于复杂的控制系统任务理想的简单但强大的线程隐喻,所述任务包括并行地并以紧密协作的方式操作的许多独立线程。用于通过引用或值以同步或异步形式传递参数的语言支持为在控制系统应用中常常需要的多种并行性提供广泛支持,同时维持使用的简单性。

有利地,基础脚本语言的解译性质与基本vm架构的组合提供在存储器和在控制器130中的较小占用区域,以及嵌入式和控制应用的快速性能,同时提供快速自适应的脚本执行环境150。

5.2.解析json数据编码标准

在实施方案中,数据架构使用json标准实施,以对所有通信包中的命令和数据编码。因此,数据架构的所有部件可解析并解译包含多种信息的json数据。为此目的,通用json解析抽象可用于针对每一不同用途创建解析器。此抽象可基于‘130专利案中的抽象,并利用ut_initjson()、ut_termjson()以及ut_parsejson的api函数(constcharptrastring、ut_jsoncallbackacallback,长上下文)。ut_initjson()复制通过以下列表4中的json语言规范创建的通用json解析器:

json解析包装器用库解析器抽象(如在语言规范中的符号“<@1:n>”中)来注册单个插件式函数。被视为插件1内的特殊情况的“n”的各种值如下被符号化地引用:

鉴于此,为实施特定的json解析器,仅需将ut_jsoncallback类型的适合的处理程序供应给ut_parsejson()。此类处理程序的大部分工作是检查json内的“path”以便提取并处理重要数据。因为存在许多不同的解析器(主要在细节上而非结构上不同),所以所述解析器无法在本文中全部描述。替代地,所述技术将使用单个解析器来说明:同时检查任何json的句法并将json转换成人可读的形式的json的“美化打印机。”此解析器可在产生json处用作交叉检查。在主要目标为句法检查的情况下,可丢弃人可读输出。下文示出用于实施“美化打印机”的c源代码:

在“美化打印机”实施中调用的所有函数通过与‘130专利案相关联并在‘130专利案中描述的库来供应。本质上,代码记录“context”中的嵌套(见“pcp->”)并使用此来缩进并格式化输出,所述输出在“pcp->string”内构建。同时,解析器检查json自身的句法并报告所述句法中的任何错误。

当本文中描述数据架构的更专门化的解析器时,可假定所述解析器的实施根本上类似于“美化打印机,”即使所述解析器的实施更加专门化且复杂。

虽然json编码用于所描述的解析器中,但应理解,在基本数据架构中可通过替代所描述的解析器来使用其它编码。因此,数据架构中不存在根本上需要json编码的事物。

5.3.从gui脚本进行转换

图6a说明根据实施方案的简单实例脚本的脚本gui的外观。所说明的脚本包括“trigger”语句,所述语句在指定日期后,在车道接触传感器被激活时,在1.5分钟的时段内打开装置群组“室外灯”中的所有灯。

脚本gui包括已通过用户与脚本gui的交互产生的基本数据的视觉表示。基本数据包括gui脚本对象,所述gui脚本对象描述gui外观且将在执行之前被转换(例如,通过脚本转换器212)成呈基础脚本语言的脚本。在使用json编码的实施方案中,图6a中的gui脚本的经json编码的输出可如下在列表5中(经格式化以易于读取,且关于json的与脚本gui本身相关联并被转换过程忽略的一些方面,为了清晰性而省略):

在列表5中的经json编码的输出中,在gui外观与用各种json键-值对表达的实际数据内容之间存在一一对应。应清楚,此经json编码的格式可能不适合于直接用作编程语言或用于在解析器内直接执行。因此,在实施方案中,将经json编码的输出转换成可通过标准解析技术解析的形式,且所述形式符合普遍施加于经设计用于机器执行的所有编程语言的语法约束。确切地说,编程语言语法往往为ll(1)或类似的(例如,lalr(1))以使所述语法易处理用于机器执行。因此,脚本gui输出本身并非编程语言,且由于通过基于gui的产生机制隐含的约束,脚本gui输出可能不能够表达更加复杂的编程结构。

在实施方案中,转换过程用于将表示gui创建的脚本(在本文中简称为“gui脚本”)的输出转换成基础脚本语言。此转换过程可实施为脚本转换器212。尤其地,脚本gui可表达基础脚本语言的小但有用的子集,所述子集经设计以允许非技术人员表达简单的脚本行为,例如在以上实例中的脚本行为。

用于解析数据的过程在本文中的其它地方描述。此相同方法可用于创建实施脚本转换器212的解析器。在此解析器中,跟踪数据内的当前路径和用基础脚本语言产生输出构成大部分工作。例如,当解析器路径以“:{:sysscript:{:value:{:trigger:{:type”结束时,如在列表5中,解析器确定所述解析器开始在隐含的无限循环内处理脚本gui“trigger”语句。因此,解析器将推动“while(true){,”并将在路径“:{:sysscript:{:value”结束时推动另外的“}”以便产生隐含的“while”块的结束。在处理程序内传递到ut_parsejson()的所有其它解析活动在结构上类似,但根据不同的特定语言元素而在细节上有所不同。

根据实施方案,来自解析列表5中的经json编码的输出的解析器的输出在下文的列表6中得到说明。

尤其地,如列表6中示出,已丢弃所有不需要的数据架构元素,且重要的部分已被转换成基础脚本语言。另外,gui脚本的名称(即,“其它测试脚本”)、gui脚本的id以及gui脚本的描述(gui脚本的“原始”名称已插在其前方)在基础语言脚本中保留。

出于进一步说明的目的,将参考图6b至图6g说明若干另外的实例脚本的输出:

在实施方案中,执行全错误检查(例如,通过脚本转换器212或编译器220),且报告在转换过程中出现的任何错误。所产生的基础语言脚本的错误检查可以与通过用于json的“美化打印机”解析器执行的错误检查相似的方式执行。具体地说,错误检查可包括使用基础脚本语言的句法构建的解析器,而没有脚本的实际执行。在实施方案中,此解析器(例如,通过编译器220实施)还可产生vm输出以用于可选地加载到vm230中。

尤其地,对于开发和测试,能够执行基础语言脚本而无需编译成vm程序的全基础语言解析器是有用的。然而,出于优化目的,vm编译器220可替代地用于将脚本编译成可通过vm230执行的vm程序。

5.4.脚本管理器

在实施方案中,脚本管理器210主要地负责在每一网关120的文件系统内存储并检索呈基础脚本语言的脚本(用基础脚本语言创建或从脚本gui的输出转换)。每一网关120的文件系统存储脚本注册表214的永久性本地复本(例如,在数据库132中)。

在实施方案中,脚本管理器210执行以下功能中的一个或多个:

●将从脚本转换器212接收的经转换gui脚本保存到脚本注册表214;

●将脚本从脚本注册表214加载到编译器220中以用于转换到vm程序和随后的执行;

●从脚本注册表214删除脚本,以响应于接收到“删除”命令(例如,从平台110接收到);

●激活和去激活脚本以响应于命令(例如,来自平台110和/或其它脚本);

●维持解析器和/或vm程序之间的父子关系;和/或

●列出并搜索脚本注册表214(例如,出于实用目的)。

5.5.脚本注册表

在实施方案中,脚本在脚本注册表214中保存为简单的文本文件(例如,扩展名为“.syt”)。用于存储构成脚本注册表214的脚本的文件系统或数据库(例如,数据库132)的特定目录可为可配置选项。

5.6.编译器

在实施方案中,编译器220将呈基础脚本语言的脚本编译成vm程序,所述vm程序可被加载在vm230内并在所述vm内执行。脚本在其被加载到vm230中时可自动地编译成等效vm程序。编译过程可根据与本文中描述的基础语言解析器相同的语言规范来执行。与基础语言解析器的唯一差异是,编译器220在任何执行之前将全部脚本转换成vm形式,而非在脚本被解析时执行脚本。vm形式的脚本可看起来与汇编语言中的程序相似,并包括通过vm230理解的多个基础操作码。下文的列表7说明根据实施方案的通过编译器220输出的列表6中的脚本(所述脚本转而从列表5中的gui脚本得到)的vm程序:

尤其地,在所说明的实例中,在列表7中表示的vm程序包含原始基础语言脚本的全部源代码以作为注释行。注释行的前面是分号,所述分号是vm汇编器的所说明实施方案中的行注释分隔符。在每一注释行内,源代码的前面是其在源代码中的行号,如通过脚本管理器210从脚本注册表214加载。这些具有行号的注释和源代码可通过在脚本执行环境150内提供的调试工具使用。例如,“断点”可置于vm程序内的任何源行上,以便检查在程序执行中在所述点的状态。

在实施方案中,在脚本执行环境150的开始期间,基于列表1和列表2中的基础语言规范,创建复制所有其它解析器所依从的第一“原始”解析器,并创建第二编译器解析器(例如,实施编译器220),如下:

以上代码中的所有函数调用都是针对与基础抽象相关联的库以用于词法分析和解析,如分别在‘430专利案和‘130专利案中所描述。

尤其地,在加载bnf之后,以上代码用序列“<@2:”替换序列“<@0:”的所有事件。在实施方案中,插件零通过解析器抽象提供并实际上执行对应的操作。当用于编译和句法检查时,一般不期望实际地执行程序。因此,为防止抽象的插件零调用的出现,所述语言经修改以替代地引用插件二。插件二产生适合的vm输出,而非执行操作。对此插件的引用在代码中的语句“ps_setplugin(parser,&ma_marlinplugintwox,2)”中被传递到解析器抽象。在解析器抽象的形式化中,ma_marlingplugintwox()的实施可表达为:

如所说明,插件必须进行的所有操作是输出对应于在‘130专利案中详述的原始“<@0:n>”运算符的适合的vm操作码。

在实施方案中,插件一(即,ma_marlinpluginonex)负责进行与插件二类似的操作。然而,插件一输出通过列表2中的原始基础语言规范中的对应的“<@1:n>”点隐含的适合的vm操作码。通过条件和循环结构隐含的跳转标签的产生和引用通过以下操作来处理:跟踪解析器(类似于json“美化打印机”的描述)内的基础语言脚本的嵌套深度,并使用当前深度来产生适合于所涉及的跳转的标签号。标签解析问题在两个阶段中处理。第一阶段基于嵌套深度来符号化地产生标签和标签引用,而不实际地解析特定标签(例如,列表7中的l1...l4)。第二阶段在对“kresolversaybyebye”(见‘130专利案)的无错误调用上调用,并处理这些符号的基于深度的标签到实际顺序且唯一标签号的转换,例如,在列表7的最终vm输出中所说明的。

在实施方案中,在实现vm编译器220的“解析程序”函数(即,ma_marlinresolveronex)中,“kresolverevaluate”和“kresolverassign”代码实质上为空,因为解析器正简单地编译脚本,而非执行脚本。所有其余动作受限于“kresolvernoaction”情况,所述情况可如下处理:

在以上代码中,所调用的函数通过库供应且可参考‘130专利案和‘430专利案来理解。

“if(atype==0)”条件的主体实施基础语言源行对vm形式输出的回应,且还实施与处理基础语言行和块注释相关联的逻辑。

“if(atype==1)”条件的主体基于所遇到的各种类型的令牌(例如,字符串、整数、实数,布尔型等)来产生vm“push”操作码和操作数。

所描述的解析器和编译器220的一个副效应是对基础语言源脚本的脚本id的开始和结束、脚本参数以及脚本描述(如果存在)的识别。此信息由调用函数用于在脚本激活期间处理参数传递。

5.7.脚本激活和去激活

在实施方案中,脚本激活的过程通过函数“su_activatescript()”实施,所述函数在下文列表8中的高级伪代码中详述:

在以上的列表8中对“su_xferparams()”例程的调用通过值并通过引用将参数从调用解析器传递到子解析器的本地符号表,使所传递的参数可用于在vm230内运行的子vm程序。这可通过以下操作实施:提取参数规范文本,并循环经过每一参数以基于所述参数的前面是否由关键字“value”或“reference”来处理所述参数。所传递的参数的实际值可从调用中的解析器的执行堆栈获得,因为所述实际值将已在先前通过响应于“activate”语句而产生的“push”指令被推动到所述堆栈上。如果参数已通过值传递,那么在本地解析器的符号表中创建新符号,所述新符号具有在激活的脚本的参数规范中指定的名称,并赋有来自调用中的解析器的评估堆栈的值和数据类型。

另一方面,如果参数已通过引用传递,那么唯一合法的数据类型是字符串数据类型,所述数据类型必须包含在调用中的脚本的上下文中所述参数引用的符号或属性的名称。在此情况下,将内部范围中的符号设定为数据类型“string”并匹配传入的字符串。然而,另外,针对所述符号设定标志“kreferencedsymbol,”使得在vm程序执行期间调用的访问包装器代码可透明地检测到这是引用并解析它。访问代码将递归地检测到具有“kreferencedsymbol”标志设定的符号被访问,并将所述符号解析成父解析器中的符号。因为此解析过程是递归的,所以脚本可通过引用将值传递到子脚本,所述子脚本自身已通过引用从父脚本接收。此解析过程将从子脚本递归地前进到任何祖先脚本。

在实施方案中,直到所有此类子脚本已结束,才允许父脚本结束,所述父脚本通过引用将参数传递到已使用“concurrent”关键字激活的一个或多个子脚本。否则,通过在子脚本的操作期间结束父脚本,由此使子脚本的操作脱轨,可使得已通过引用传递的参数无效。

5.8.虚拟机

在实施方案中,最后所有脚本,无论是以基础脚本语言写入还是从通过脚本gui产生的gui脚本转换的,都通过vm230执行。

5.8.1.vm程序格式

在实施方案中,经编译的脚本,在本文中称为“vm程序,”对应于包含脚本的每一行的文本内容的字符串的有序列表。例如,在列表7的vm程序中,文本的每个和每一行,包含仅含注释或标签的行,为在有序列表中的单独的字符串值。每一字符串值可具有与所述字符串值相关联的相关联64位值(实数或整数)以作为“标记,”以及多个逻辑标志。在实施方案中,vm230基于平面存储器模型来使用“et_stringlist”结构实施此,所述平面存储器模型描述于2006年9月5日发布的且标题为“用于管理存储器的系统和方法(systemandmethodformanagingmemory)”的第7,103,749号美国专利案(“‘749专利案”)中,所述专利案通过引用特此并入本文中。

使用此模型对字符串列表库的访问通过‘130专利案中的解析器抽象库提供。以下描述将基于使用‘749专利案的字符串列表的实施。虽然可使用替代的实施,但存在将‘749专利案的字符串列表用作所加载的可执行vm程序的基础表示的多个原因,包含以下各项中的一个或多个:

●字符串列表形式提供任意长度的字符串的列表,每一字符串具有可用于外部代码所需要的任何目的的相关联的64位标记值;

●字符串列表形式支持与每一字符串相关联的逻辑“flags”关键字;

●不管有序列表中的字符串的数目是多少,字符串列表需要仅单堆存储器分配。此单个分配对于到vm230中的高效加载和卸载是理想的。所有存储器为连续(不同于常规的链接列表)的事实意味着,处理器高速缓存一般更加有效地操作。字符串列表自身可被链接,从而创建相关联的字符串列表的集合。链接的字符串列表的所述集合可包括加载在vm230中的所有活动vm程序;

●字符串列表的“平坦性”使得字符串列表理想的用于经过队列,所述队列在抢占式线程或不同的过程之间传递复杂信息。有利地,不需要序列化和去序列化;

●因为所有字符串都在单个存储器分配内,所以用于执行vm程序的程序计数器可适用api调用实施为仅到单个存储器分配中的字符串偏移;

●字符串列表可通过经设计以辅助脚本开发人员的相关联的调试代码来容易地操控和/或显示。例如,单步执行和断点变得易于在此框架内实施;

●字符串列表还在代码的其余部分上广泛地使用以用于其它目的。例如,符号表、注册表搜索以及多个其它功能可实施为字符串列表。此共同性简化整体程序大小和复杂性;和/或

●类似于解析器和词法分析抽象,字符串列表抽象是成熟的且得到良好测试的,由此节省相当大的开发和调试努力。

5.8.2.加载vm程序

待在vm230中运行的脚本可首先通过编译器220编译成vm形式(例如,在所描述的实施方案中,被称为“vm程序”的字符串列表)。脚本随后被激活,例如,如列表8中所描述。在执行vm程序时的最后步骤是用传递为参数的适合的选项调用“ma_runmarlin()。”取决于配置设定,ma_runmarlin()直接地在解析器内执行程序(例如,用于测试/调试),或通常通过加载到vm230中执行程序(同时维持到相关联的解析器的链接,例如,以使用符号表)。

在本文中实施为“ma_marlinvmprogram”的加载过程首先经过各种字符串,检查每一行上的操作码(如果存在),并将操作码转换成存储在相关联的“flags”关键字中的二进制值,使得,在执行期间,不再需要字符串比较以便确定操作码。

每一ma_marlinvmprogram实例与当前活动的且在vm230内运行的所有其它ma_marlinvmprogram实例的链链接。vm程序的执行通过添加到ma_marlinvmprogram实例的此链接列表来开始。

默认地,将初始程序计数器设定为ma_marlinvmprogram实例中的第一字符串,即,主脚本的起始,所述主脚本的起始始终是文件中的第一个。在作为稍后在vm程序的文本中声明的静态局部子脚本的脚本开始的情况下,程序计数器初始化为子脚本的起始,如在列表8中所描述。从此点开始,脚本通过对来自vm过程的主循环的“ma_stepmarlinvm()”函数的连续调用,以一次一个操作码的方式与所有其它脚本并行地执行。

5.8.3.定义的vm操作码

在实施方案中,vm230可支持以下操作码的一个或多个:

5.8.4.vm机编程模型

在实施方案中,vm230具有编程模型,所述编程模型具有单个评估堆栈。所有操作可涉及评估堆栈的顶部少量元素,所述评估堆栈表现得像关于算术运算的逆波兰计算器。堆栈的每一元素可具有基础数据类型中的任何类型的值或为未知的。某些操作码预期特定的数据类型,而其它操作码将恰当地操作而不管堆栈中的数据类型。所有基础算术和逻辑运算都通过‘130专利案中的解析器抽象提供(通过插件零)。因此,所述运算在ma_stepprogram()内的实施通过调用库api的ps_evaluation()函数来完成。

在实施方案中,所允许的仅非堆栈运算是到或来自符号或属性的运算,所述符号或属性的名称必须作为字符串推动到堆栈上。

5.8.5.运行vm程序

在实施方案中,顶层ma_stepmarlinvm()函数调用ma_stepprogram()来经过所加载的ma_marlinvmprogram实例的列表,所述ma_stepprogram()将执行“时隙”给予通过每一ma_marlinvmprogram表示的vm程序。ma_stepprogram()函数是执行实际执行的函数。因此,调用链对于vm环境非常浅。ma_stepprogram()函数现将通过将其逻辑分成不同的描述的集合来描述,所述不同的描述中的每一个有效地实施在每一执行步骤中遇到的vm操作码中的一个。

在每一次进入ma_stepprogram()时,初始逻辑执行循环,从字符串标志提取操作码(如果存在),并跳过没有操作码的任何行(例如,其中通过字符串标志表示的操作码等于零的行,表示例如注释行或具有仅标签的行)。

如果操作码是通过基本解析器抽象(见表1)提供的操作码,那么所述操作码通过对ps_evaluation()的调用来实施,因为必要的操作数将已被推动到评估堆栈上。

在实施方案中,push操作码采用各种形式的单个操作数。在实施方案中,push操作码是在于顶部少数堆栈元素上调用另一操作码之前通过其使所有数据值和引用到达评估堆栈上的操作码。

在实施方案中,push操作码将前面为“#”字符的任何操作数视为常量数值,并将适合的值和数据类型推动到堆栈上以作为新顶部元素(即,s[0])。符号“#true”、“#false”以及“#unknown”产生适合的值。否则,数值令牌格式与在基础脚本语言中指定的那些格式(见例如,列表1)相同。数值令牌格式使用用于相关联的解析器的注册词法分析器来识别,并被转换成适合的二进制堆栈值和数据类型。未能识别push操作数可导致“unknown”值被推动到堆栈上,以及可选的错误报告。

在实施方案中,在首先对任何嵌入的换码字符进行解码之后,以字符串引号开始的push操作数被推动到评估堆栈上以作为字符串。可使用通过c语言支持的换码字符的相同的约定。

在实施方案中,以“@”开始的push操作数可被视为装置属性引用,所述装置属性的值可通过调用dm_getdeviceproperty()函数来获得。dm_getdeviceproperty()函数经由装置管理器抽象层162读取装置属性的值,并返回所读取的值。

在实施方案中,直接地引用符号的push操作数前面没有任何特殊字符,且导致评估字符并将字符的等效值推动到评估堆栈上。这执行符号标志“kreferencedsymbol”以便处理通过引用传递的参数。如果无法找到所引用的符号,那么将堆栈的顶部设定为“unknown,”且可报告错误。vm230可包括逻辑(例如,使用字符串标志位),所述逻辑用以确保错误仅在错误对于vm程序中的任何给定指令第一次出现时记录,以便避免错误雪崩。

在实施方案中,jmc操作码负责实施基础脚本语言的各种循环和条件语句的大部分逻辑。jmc操作码采用两个操作数:(i)字符串,所述字符串指定其将实施的特定类型的逻辑(例如,“if”、“trigger”、“while、”“every”、“when”);(ii)标签,如果不满足逻辑,则跳转到所述标签。

在实施方案中,jmc操作码利用与字符串元素相关联的多个标志位(表示行)以便维持状态。此类标志的实例包含:

●“kwaitingforcompletion:”例如,用于“every”语句的实施中。第一次遇到“every”语句时,此标志将为清除的。jmc逻辑是,如果s[0]的值为“unknown,”那么执行无条件跳转。否则,提取s[0]的整数或实数值并将所述值添加到当前时间(作为双精度日期),将字符串标记设定为结果,针对字符串设定“kwaitingforcompletion”标志,且通过将“stepon”设定为“false”来禁止程序计数器的前进。因此,在下一次将时隙给予vm程序时,程序计数器将再次处于jmc指令处,但这次将针对字符串设定“kwaitingforcompletion。”所述逻辑将比较当前时间与保存在标记中的最后时间,且如果当前时间较小,那么逻辑将跳转到指定标签(通过设定程序计数器)。当经过所述时段时,逻辑清除“kwaitingforcompletion”标志,且“every”循环将在下一遍次时重复。

●“previoustrigstate”和“knotthefirsttrigpass:”例如,用于“trigger”语句的实施中。jmc逻辑是,如果s[0]的值为“unknown,”那么执行无条件跳转。否则,如果未设定“knotthefirsttrigpass”标志,那么逻辑设定“knotthefirsttrigpass”标志并使程序计数器前进到下一语句。如果s[0]的值为零(即,假)或其设定并非与“kprevioustrigstate”标志的设定不同,那么逻辑按需要设定“kprevioustrigstate”标志,并将所述标志视为无条件跳转。否则,逻辑通过使程序计数器前进到下一语句来执行条件主体。如果“trigger”语句包含“else”子句,那么“else”子句的标签之后紧跟“not”操作码,且随后紧跟另一jmc操作码(通过编译器220产生)。此否定的结果是,当值在与触发所述触发语句本身的条件主体的方向相反的方向上转变时,“else”子句的第二jmc将触发执行。

在实施方案中,“if、”“if-else、”“elseif”以及“while”逻辑所需的动作简单地为s[0]的值的结果。使用“stepon”的逻辑标志来禁止程序计数器的前进促进线程行为,而不影响所有其它vm程序的并行执行。针对必须处理并行性的其它操作码重复此模式。

在实施方案中,“when”逻辑在适当位置循环,直到条件变成真,由此阻断另外的脚本前进。因此,“when”逻辑与“if”或“trigger”逻辑不同,不同之处在于,所述“when”逻辑阻断当前脚本内的所有执行直到满足条件。

在脚本gui的实施方案中,“trigger”语句始终作为脚本中的第一语句出现,并具有隐含的无限外部循环。因此,“when”和“trigger”语句的语义呈现为类似的。然而,在基础脚本语言内,“when”和“trigger”语句可在脚本内的任何地方且多次出现。并且,不同于经由脚本gui的实施方案创建的gui脚本,trigger语句可具有可选的“else”条件。因此,“trigger”与“when”之间的语义差异是清晰的。

在实施方案中,jmp操作码执行到目标标签的无条件跳转,所述目标标签被指定为jmp操作码的操作数。第一次遇到jmp操作数时,逻辑扫描脚本以寻找指定标签。当找到指定标签时,逻辑将对应的偏移(即,程序计数器值)存放在字符串标记中。因此,逻辑不必在任何随后的遍次上重新扫描脚本,从而提供大量的时间优化。

在实施方案中,call操作码调用内置函数或程序。call操作码仅需要一个操作数,即,“opcount,”所述“opcount”是实际传递的参数的数目。一些函数可接受可变数目的参数。当遇到函数或程序名称时,将所述函数或程序名称作为字符串推动到堆栈上,且随后有序地将参数中的每一个推动到堆栈上,或作为参数表达式赋值的结果而在适当位置结束。因此,call操作码发现函数或程序的名称被称为s[opcount]+1,并调用所述函数或程序,传递“opcount。”所述函数或程序将找到所述函数或程序在堆栈上接受的所有参数,执行函数或程序的逻辑,并在堆栈上在s[opcount]+1处替代函数名称返回结果(或“unknown,”如果是程序的话)。随后将所有参数弹出堆栈。

在实施方案中,load操作码的等效于赋值的操作类似于对解析器抽象解析程序kresolverassign()的调用。load操作码不采用操作码,并预期s[0]为待赋的值且s[1]为包含将值所赋给的符号或属性的名称的字符串。正如push操作码一样,load操作码遵守“kreferencedsymbol”标志,为“reference”参数提供支持。并且,类似于push操作码,load操作码使用dm_setdeviceproperty()函数来设定属性,所述函数导致经由装置管理器抽象层162来写入值。

在实施方案中,ret操作码通过从vm230卸载vm程序并去激活vm程序来结束当前vm程序的执行。vm程序的相关联解析器可保留在存储器中,使得较高级代码和调试器实用程序可仍在处理解析器和符号表之前检查符号表的状态。具有活动相关的终止在包括pass-by-reference参数时受到约束。

在实施方案中,acts操作码同步地设定并运行指定的子vm程序,使得父vm程序在移动到下一指令之前必须等待结束。当子vm程序已开始时,acts指令针对父vm程序中的当前字符串设定“kwaitingforcompletion”标志,并禁止程序计数器的前进。对于子vm程序,设定“kwaitingtillcompletion”和“knestedinvoke”标志,使得,当子vm程序结束时,子vm程序将定位父vm程序并清除用于程序计数器指令的“kwaitingforcompletion。”父vm程序将在授予其的每一随后的vm时隙上固定在同一程序计数器处,直到“kwaitingforcompletion”标志已被清除。此逻辑允许以类似于在同一线程内的函数调用的方式处理子脚本。

在实施方案中,acta操作码是vm230内的线程行为的基础,因为所述acta操作码提供开始自主并行过程的方法。acta操作码设定并运行子vm程序,如针对脚本激活所描述。当子vm程序已开始时,acta指令使程序计数器前进,而不针对当前字符串设定“kwaitingforcompletion”标志。对于子vm程序,仅设定“knestedinvoke”标志,使得,当子vm程序结束时,逻辑知道其不必定位父vm程序以清除“kwaitingforcompletion”标志。

在实施方案中,dact操作码去激活在指令中指定的脚本名称。

在实施方案中,当堆栈需要弹出以便避免堆栈溢流时,通过编译器220产生pop操作码。大部分vm操作执行其自身的堆栈维护。因此,一般不需要明确的pop操作码。然而,涉及跳转的一些复杂行为可需要明确的pop指令来保持事情顺利。

在实施方案中,paws操作码实施“pause”语句,并接受指定所传递的堆栈参数的数目的数值操作数(类似于call操作码)。在实施方案中,始终存在两个参数。paws操作码的操作包括从堆栈提取乘数和时间单位字符串,将其乘积添加到当前时间,并将相加的结果保存到字符串标记中,同时设定相关联的“kwaitingforcompletion”标志并禁止程序计数器的前进。与“every”语句很像,paws操作码将禁止程序计数器的前进,直到已经过指定时间段,此时“kwaitingforcompletion”标志被清除且程序计数器再次开始前进。此实施的线程友好性是在实施方案中“pause”语句不实施为内置函数调用的原因。

6.装置管理器

在实施方案中,每一网关120包括装置管理器160,所述装置管理器提供广泛多种插件式软件驱动器166,所述软件驱动器中的每一个可向装置管理器160动态地注册并符合指定驱动器接口。每一驱动器166可能或可能不对应于可用硬件装置控制器170,且经设计以使用传输层或协议来通信。多个驱动器166的可用性实现异构系统的创建,所述异构系统能够跨越多个传输层和协议与广泛多种不同装置类型通信。能够经由特定传输层通信的可用插件式驱动器166的集合可按需要与对应的硬件控制器170组合以处理所有类型的控制系统要求,而不需要托付于单个基本数据架构。

在实施方案中,驱动器层164确保个别的驱动器166不需要知道数据如何在数据架构内存储并被操控的细节。具体地说,驱动器层164使用可通过系统模式配置的可动态编程的数据驱动的映射接口,在通过数据架构使用的那些装置属性值、名称、缩放、格式化以及类型与通过每一驱动器166在内部使用的那些装置属性值、名称、缩放、格式化以及类型之间转换装置属性值、名称、缩放、格式化以及类型。这允许驱动器166以数据格式不可知方式插入到装置管理器160中,从而使得此类驱动器166相比于常规方法相对较快地被写入和测试。驱动器166基于传输协议和/或装置自由地使用内部表示,并忽略将这些内部表示转换成数据架构的数据格式或从所述数据格式转换出这些内部表示所必需的活动。

在实施方案中,模式在网关120启动时从平台110取出。因此,在平台110处的模式的修改可被传播到订阅平台110的任何数目的网关120。定义驱动器层164的模式可包括用经解译的适配器语言的“片段”写入的指令,所述适配器语言是基础脚本语言的全包含子集。

在实施方案中,装置管理器160在装置控制器170与网关120的部件之间提供双向通信。装置管理器160可从脚本执行环境150(例如,通过由vm230执行的直接函数调用)直接地接收装置相关的命令,或由于对在网关120订阅(例如,经由包括控制器130和通信层140的通信路径,但不包括脚本执行环境150)的数据中发生的对数据(例如,装置属性)的更新而间接地接收装置相关的命令。数据架构中的数据的(例如,装置属性的)改变可源自界面114的gui,或源自脚本执行环境150,所述脚本执行环境运行为平台110上的远程过程,运行为本地网关120的控制器130上的本地过程,和/或运行为远程网关120的控制器130上的远程过程。

用于控制装置的传输层和协议的丰富和连续演进已禁止家庭自动化中的进展。具体地说,创建可与这些层和协议中的全部通信同时保持便宜且易于使用的系统是压倒性的任务。因此,在实施方案中,装置管理器160提供便宜且完全模块化的硬件平台,装置模块可插入所述平台以用于与每一特定的传输层通信;以及匹配的软件架构,所述软件架构简化对用于不同传输协议的多个驱动器的维护。

在实施方案中,装置管理器160使得多个不同驱动器166能够通过api插入到驱动器层164中。驱动器166通过驱动器层164与基础架构部件的其余部分的约定和数据需要隔离,所述驱动器层包括数据驱动的适配器语言,所述适配器语言在值在任一方向上传递时被动态地调用(例如,以改变属性名称、格式化、缩放、类型以及其它方面),使得驱动器层164没有一侧知道在驱动器层164的另一侧上正发生什么。这意味着每一驱动器166可独立地存在且从不需要在系统的其它方面改变时发生改变,从而促进用于广泛范围的传输协议的驱动器的快速创建,而对现有设施或架构没有影响。同样地,较宽的基础架构部件(例如,数据架构、脚本执行环境150等)不需要改变以适应驱动器的改变。可能需要响应于在驱动器层164的一侧或两侧上的改变而做出的唯一改变是模式定义的更新(例如,在平台110上的数据文件中表示)。这实现在驱动器层164的两侧上的独立演进。

在实施方案中,装置管理器160经实施以具有或支持以下属性中的一个或多个:

●将不变接口提供给所有驱动器166,所述不变接口防止每一驱动器166必须考虑通过数据架构使用的协议和表示;

●将不变接口提供给网关120,所述不变接口防止网关120的任何其它部件必须考虑任何给定驱动器166或传输层的独特需要;

●提供适配器编程语言,所述适配器编程语言是所公开的基础脚本语言的全包含子集,且所述适配器编程语言可访问基础脚本语言的内置函数中的一个或多个或大部分以便产生映射。有利地,此共同性使集成人员和开发人员的学习曲线最小化。另外,映射函数可在平台110上的模式内定义,且可为数据驱动且自适应的。用适配器语言写入并实施驱动器层164的程序在本文中可被称为“片段;”

●适配器语言利用与基础脚本语言相同的装置引用令牌结构;

●提供可编写脚本驱动器层164,所述可编写脚本驱动器层根据在平台110上的模式内指定的映射,透明地并高效地更改层164上的属性值、类型、范围、名称等,以适应于每一驱动器166。此柔性数据驱动的驱动器层164跨越装置管理器160双向地执行所有格式和名称改变,使得每一侧都不需要知道另一侧如何操作或另一侧需要的数据格式;

●所有映射和片段在网关120的启动期间从平台110上的模式检索,且平台110上的模式的改变直接地在网关120上更新,而没有与映射所述片段相关联的构建周期,由此使得装置管理器160高度自适应;

●跨越装置管理器160的属性的映射通过片段执行,所述片段即,用适配器编程语言写入的程序;

●为接口提供格式化数据架构的流的能力以便允许脚本gui、其它云过程和/或独立的脚本执行环境150读取并写入装置属性,而不管驱动器;

●将直接api连接提供到在vm230中执行的脚本以便实现最大性能;

●能够通过使用标准化数据模型和基于驱动器的路由而以完全集成(单过程)或远程脚本/控制(多过程)的模式操作;

●能够注册用于各种传输协议的多个同时顺从的插件式驱动器166,且随后,自动地使装置控制器170与驱动器166相关联以用于控制装置控制器170的目的。

●每一装置属性包括无序的已命名键-值对和状态,所述关键字-值对和状态允许在整个数据架构上的改变的控制器传播;

●支持未知属性值和不可达的装置;

●易于使用的驱动器接口,所述接口对驱动器166隐藏数据架构需要,同时简化驱动器的编程模型;

●标准化装置发现过程,所述过程允许驱动器166动态地注册并公布所连接的装置;

●驱动器166可在单独的线程/过程中运行,由此允许合法的驱动器被包装并集成到装置管理器160中;

●能够添加与特定传输层相关联的自定义驱动器166;

●能够创建虚拟装置和/或执行高级路由或控制行为;

●通过装置名称和/或装置识别符进行的装置解析;

●能够通过对表示多个装置的群组的对应的属性的单次赋值来针对多个装置设定属性;

●完全支持数据架构所需的所有行为和协议;

●能够注册控制其它网关120的驱动器166,由此实现用于较大项目的分布式子系统的分层系统的创建;

●一个或多个api,所述api用以简化新驱动器166的创建;

●整个驱动器接口由三个回调函数组成;和/或

●提供通用驱动器(ud)抽象层;相关联的物理到逻辑基础架构,所述基础架构用以将物理装置的属性转换成在通用驱动器中的注册表内的表示(所述表示可在本文中被称为“pdev”);以及构件,所述构件用以注册相关联的逻辑装置表示(所述表示可在本文中被称为“ldevs”)和必要的驱动器内部映射片段,所述映射片段用以在任何装置属性在任一方向上改变时映射到和映射自pdevs和ldevs。如本文中可使用,“tophysical”是指源自数据架构的属性变化,而“tological”是指源自硬件(例如,物理装置)的属性变化。映射逻辑可以类似于本文中描述的适配器语言的方式用基础脚本语言的变型或子集写入,但所述变型或子集比适配器语言强大得多,如通过表示并操控布置的精确表示和/或硬件装置属性和命令(例如,改变字大小,位掩蔽,数组,子结构等)的所有可能形式和包装的需要所需。在一些实施中,大部分驱动器可经由ud抽象层连接,而非直接地连接到装置管理器api中,因为这简化写入驱动器的任务。在实施方案中,ud抽象层是经设计以简化写入顺从驱动器的过程的单独且独立的层。

在实施方案中,装置管理器160是自适应且强大的接口,所述接口可同时连接到多个顺从的插件式驱动器166并平滑所有传输特定的和驱动器特定的急转,使得较高级架构甚至不必考虑这些事情以实现对应的装置的控制。此外,为增强其效用,装置管理器160还可在统一架构中利用通过用户界面部件(例如,在界面114内)、数据联网部件和/或编写脚本部件的任何使用的相同基本数据抽象。通过在整个扩展的且分布式系统上推动此共同性,一直到装置管理器160,可实现简单且通用的用户体验。

6.1.适配器语言

6.1.1.词法结构

根据实施方案,下方的列表9表示根据在‘430专利案中定义的形式化的适配器语言的词法结构:

在实施方案中,除在列表9中的“<begin>”与“<next>”分隔符之间的各种关键字和运算符外,适配器语言支持以下可变词法令牌:

●令牌1:变量或符号值(例如,counter、idx_1、a、varname等);

●令牌2:具有换码的单或多字符常量(例如,“x、”“\n”、“\x34、”“abcd”);

●令牌3:十进制64位整数(例如,1234);

●令牌4和5:具有可选指数的双精度浮点数(例如,1.234、1.3e5);

●令牌6:装置属性(例如,@dev.temperature、@[xxydd].contact、@.prop等);

●令牌7:十六进制64位整数(例如,0xffff、0x34ab);

●令牌8和9:未经使用,因为所有的整数都是相同大小;

●令牌10:八进制64位整数常量(例如,03777);

●令牌11:未经使用,因为所有的整数都是相同大小;和/或

●令牌12和13:具有换码的字符串常量(例如,“helloworld\n”)。

在实施方案中,适配器语言支持与基础脚本语言相同的运算符句法,但消除基础脚本语言中的所有关键字,除了“if、”“else”以及预定义常量“true”、“false”以及“unknown。”因此,除“if”结构外,适配器语言缺少基础脚本语言的所有线程、循环以及控制结构。此简化是批准的,因为驱动器层164的工作仅是将值从一种形式或名称转换成另一形式或名称。由此,适配器语言不需要基础脚本语言的更加复杂的结构。此简化还使驱动器层164易于实施,并消除对用于适配器片段的vm230的等效物的需要。

通过基础脚本语言和适配器语言两者提供的运算符集可类似于在标准c语言内支持的那些运算符集,但不包括自动递增和递减结构,且分别用关键字“and”、“or”以及“not”替换c逻辑运算符“&&、”“||”以及“!。”这使新手程序员容易理解。

正如基础脚本语言一样,在实施方案中,除了内置类型外,基础脚本语言不允许定义类型,所述内置类型可紧密地对应于词法令牌。内置类型可包括:

●布尔型:布尔值(例如,保持为64位整数),所述布尔值可采用“真”或“假”的值。

●整数:64位整数值(但可使用不同大小的整数值);

●实数:双精度浮点值(例如,等效于c中的双精度数);

●字符串:任意长度的字符串值(例如,“helloworld”);

●符号:符号值,所述符号值自动地呈现数据类型和赋给所述符号值的任何项的值(例如,myvariablename),使得符号可具有任何基础类型(例如,布尔型、整数、实数、字符串或未知的);和/或

●属性:装置属性值(例如,@dev.temperature),其中属性的数据类型通过模式和处理所述模式的装置驱动器确定,使得所述属性可为任何基础类型(例如,布尔型、整数、实数、字符串或未知的)。

正如基础脚本语言一样,在实施方案中,适配器语言是动态类型的语言。换句话说,符号呈现数据类型和最近赋给符号的任何项的值。这消除了对与类型定义相关联的句法或逻辑的需要。

如上文所提及,在实施方案中,符号和属性数据类型可赋有基础数据类型中的任何类型,以及表示“unknown”的值。如本文中其它地方将描述,“unknown”值可具有特殊意义,尤其是在给表达式赋值时。

正如基础脚本语言一样,在实施方案中,适配器语言支持块语句(例如,通过括号“{“和“}”包围)。然而,不同于基础脚本语言,在实施方案中,适配器语言不支持任何类型的注释。适配器程序通常足够简单(例如,仅单个语句),使得一般不需要对嵌入式注释的支持。出于此原因,适配器程序可在本文中被称为“片段,”而非“程序。”然而,替代地,适配器语言可例如以与基础脚本语言相似的方式支持注释。

6.1.2.句法

根据实施方案,给出列表9中定义的词法结构并根据在‘130专利案中定义的形式化,下方的列表10表示适配器语言的句法:

列表10中的bnf的区段,从“expression”的lhs产生式开始并以“object”的lhs产生式结束,基本上指定可用于表达式内的所有运算符,和通过bnf内的声明序列实施的对应的运算符优先级规则。

此语法区域与基础脚本语言相同,且因此,将不详细描述此语法区域。此外,在实施方案中,所有这些语言功能都通过基于‘130专利案的解析器技术而内置在库中的代码实施,如通过呈“<@0:n>”形式的语法元素指示。出于此原因,适配器语言的这些方面,包含任意深度的嵌套表达式的赋值,将也不在本文中详细描述。

在实施方案中,适配器语言支持内置函数调用和程序调用,可将零个或更多个逗号分隔的参数传递到所述内置函数和程序。每一参数可为任意表达式(包含嵌套函数调用),所述表达式产生可采用基础数据类型中的任何数据类型的形式的参数值。与此功能相关联的语法产生式包含“rstof_object”、“parameter_list”以及“rstof_param_list。”函数可确定传递到所述函数的参数的数量和数据类型,且许多函数可对于任何给定参数接受超过一个数据类型,并根据传递作为给定参数的数据类型操作。可用内置函数的取样在本文中的其它地方出于说明性目的而描述。

6.1.3.片段结构

列表10中的产生式,在“program”处开始并以“else_body”结束,涉及用适配器语言写入的片段的基础结构。在实施方案中,每一片段包括通过分号分隔的一系列语句。不同于基础脚本语言,在实施方案中,不需要最外层包围块分隔符(即,“{“和“}”)和函数声明。适配器片段可从通过驱动器层164在其被调用时在内部传递的信息得到所述适配器片段需要的所有上下文。

6.1.4.简单语句

在实施方案中,适配器语言提供两个简单的语句形式:(1)赋值语句;以及(2)具有可选的“else”子句的“if”语句。这些简单语句中的每一个可通过分号与下一个分隔,所述分号是语句分隔符。“if”或“else”块的内容可为单个语句或包括另外的内部语句的块语句(即,在通过“{“和“}”定义的块内)。在任何简单语句为合法的情况下,空语句(即,只有“;”)是合法的。

6.1.5.内置函数

在实施方案中,适配器语言可提供内置函数的库。此库可与在基础脚本语言中可用的内置函数的库相同。然而,并非所有所述内置函数都将适用于适配器操作。因此,可用于适配器语言的库可包括与适配器操作相关的内置函数的缩小集合。

以下是可在适配器语言的库中提供的内置函数中的一些的说明性非穷尽性列表,其中“[i]”指示整数参数,“[b]”指示布尔参数,“[f]”指示实数参数,“[s]”指示字符串参数,且“[v]”指示空返回值(即,程序而非函数):

●[i]round([f]realvalue):将实数四舍五入到最近的整数值;

●[i]int([i/r/s]avalue):将整数、实数或字符串值转换成整数值。字符串转换可类似于c中的“strtoll()”函数;

●[f]real([i/r/s]avalue):将整数、实数或字符串值转换成实数值。字符串转换可类似于c中的“strtod()”函数;

●[s]sprintf([s]formatstring,...):类似于c中的“sprintf()”函数,除了整数和实数可变自变量大小始终分别为int64和双精度数;

●[i]setoptions([i]options/[s]optionsstr):用于开始选定的解析器选项。此函数可用于调试脚本的选定部分,而不会通过跟踪其它的每一项而使控制台混乱。字符串形式允许符号化地设定选项。在执行所设定的操作后,此函数返回选项设定以作为结果;

●[i]clroptions([i]options/[s]optionsstr):清除指定的解析选项。此函数与setoptions()相反,并在清除操作后返回选项设定以作为结果。字符串形式允许符号化地清除选项;

●[i]getoptions():获得并返回解析选项的当前设定;

●[s/i/f]indexset([i]index,[s/i/f]set1,...[s/i/f]setn):通过索引从给定成员列表选择特定的成员集,并返回选定成员作为结果。如果指定索引在范围外,那么返回指示“novalue”的值。函数的返回数据类型通过集合成员的数据类型(所述集合成员的数据类型必定全都相同且为整数、实数或字符串数据类型中的一个)确定;

●[i]setindex([s/i/f]src,[s/i/f]set1,…[s/i/f]setn):比较“src”与所提供的可能匹配值的集合中的元素中的每一个,并在找到匹配时返回所找到的匹配的索引(从1开始),或在未找到匹配时返回零。如果“src”为整数,待检查的其余的集合值必定也为整数。类似地,如果“src”为字符串,那么待检查的其余的集合值必定也为字符串,并且,如果“src”为实数,那么待检查的其余的集合值必定也为实数。此函数表示用以针对值的集合中的成员关系检查值的方便方式,并且可用仅单个函数调用来替代大量的个别比较;

●[i]rangeindex([i/f]src,[i/f]set1,…[i/f]setn):类似于setindex()函数,但在集合中寻找匹配的“lessthanorequalto”值,而非相等。因此,此函数可用于索引数值范围的有序集合,由此替代较大数目的条件语句。不同于setindex()函数,在rangeindex()函数中禁止字符串值;和/或

●[s]consolemessage([s]formatstr[,…]):执行与c中的“sprintf()”函数类似的函数,返回所产生的字符串作为结果,且同时将所产生的字符串发送到控制台。此函数可用于产生调试或进展消息。

6.1.6.解析器上下文和符号

类似于基础脚本语言,在适配器语言中,符号一被赋值并接受最近赋给符号的内容的数据类型和值,就在局部范围内被创建。换句话说,适配器语言是动态类型的语言。

在实施方案中,适配器语言的解析器结合值将符号存储为字符串,包含符号的名称,所述值可具有内置数据类型(例如,布尔型、整数、实数、字符串或未知的)中的一个。每当适配器解析器遇到符号名称时,所述解析器可在本地解析器的符号注册表中实施查找以寻找符号名称的条目,且随后在符号注册表中检索或设定数据类型和值。在实施方案中,使用‘430专利案的词法分析器抽象来索引符号注册表以用于快速查找。这使符号查找几乎是瞬时的,而不管符号注册表中的符号的数目。

不同于基础脚本语言,在实施方案中,适配器语言片段在解析器抽象内直接地运行。换句话说,不存在等效于vm230的适配器语言。此简化是由于以下事实:适配器语言没有线程模型,且在解析器内的直接执行实施起来更简单。另外,因为片段一般是琐碎的且仅在装置属性值被读取或写入时执行,所以不太需要优化执行。这是尤其真实的,因为基础语言解译器为当前装置属性值维持内部高速缓存,这意味着读操作通常由内部高速缓存服务,且很少一直“流”至驱动器166。原理是,驱动器166负责在装置属性值已改变时通知装置管理器160(例如,使用dm_devmgrnfy()函数)。然而,如关于基础脚本语言所论述,任一执行形式在功能上是等效的,所以适配器语言全都与基础脚本语言一样利用解析器抽象(例如,用于符号表存储)。然而,在适配器语言的解析器之间不存在父子关系的概念。每一适配器片段在功能上与所有其它适配器片段不同。替代地,如果需要优化,那么可提供与基础语言vm230类似但更简单的适配器vm。

6.1.7.在模式中指定片段

在实施方案中,模式定义用于通过每一所注册的驱动器166来读取或写入每一装置属性(例如,温度、亮度、锁定等)的处理片段。具体地说,模式可将驱动器的每一装置属性映射到数据架构中的装置属性。

下方的列表11说明根据实施方案映射数据架构中的三个装置属性(即,“roomtemp”、“doorlockstatus”以及“brightness”)的实例模式:

在实施方案中,装置管理器160订阅数据架构内的所有模式定义。因此,在开始,对于所有装置属性,装置管理器160从平台110接收模式定义的完整集合。装置管理器160可将接收到的模式定义的集合转换成平坦的装置属性注册表,所述注册表包括用于检索用于任何定义的装置属性的映射的所有必要信息。类似于脚本注册表214,装置属性注册表可基于‘749专利案的字符串列表抽象(即,et_stringlist)。具体地说,每一条目可使用专门化的解析器从模式提取,并记录在字符串列表中(例如,使用da_addpropertymapping()函数)。然而,可使用替代的实施。

记录在字符串列表中的每一条目的格式可为如下:

drivername;;sysmappropname;;driverpropname;;readsnippet;;writesnippet

其中drivername表示装置属性的抽象名称,sysmappropname表示数据架构中的装置属性的名称,driverpropname表示驱动器中的装置属性的名称,readsnippet是用于从装置读取装置属性的适配器片段,且writesnippet是用于将装置属性写入到装置的适配器片段。然而,应理解,可使用其它格式(例如,非基于json的格式)和其它解析器。

在实施方案中,每一字符串列表条目与一个或多个标志相关联,所述标志记录数据架构和驱动器两者的所表示属性的数据类型(例如,布尔型,64位整数,双精度实数,字符串,未知的)。某一条目可使用da_findpropertymapping()函数和所需信息在装置属性注册表中找到,所述所需信息使用da_getpropertymappingfield()函数提取。根据实施方案,与每一字符串列表条目相关联的标志可包括以下各项中的一个或多个:

●“kmapdrivername:”驱动器名称(*valuep=字符串最大长度32);

●“kmapsysmapproperty:”数据架构属性名称(*valuep=字符串最大长度32);

●“kmapdriverproperty:”驱动器属性名称(*valuep=字符串最大长度64);

●“kmapreadprogram:”读取程序(*valuep=字符串最大长度stringbuffsize);

●“kmapwriteprogram:”写入程序(*valuep=字符串最大长度stringbuffsize);

●“kmappropertytype:”数据架构属性类型(*valuep=int16,连续的kboolvalue型的值,...);和/或

●“kmapdrivertype:”驱动器属性类型(*valuep=int16,连续的kboolvalue型的值,...)。

装置属性注册表中的这些标志可通过解析模式来提取,使得,对于每一属性:

●最外“id”值变成“kmapsysmapproperty;”

●在驱动器内的属性名称(例如,列表11中的“thingworx”、“zwave”以及“justtesting”)变成“kmapdrivername;”

●属性的模式的“read”值变成“kmapreadprogram;”

●属性的模式的“write”值变成“kmapwriteprogram;”

●模式的“$ref”值被编码为“kmappropertytype;”

●在驱动器特定的值内的模式的“name”值变成“kmapdriverproperty;”以及

●在驱动器特定的值内的模式的“type”值被编码为“kmapdrivertype。”

鉴于在基础脚本语言的上下文中的解析的论述,应清楚如何通过调用da_addpropertymapping()function来实施传递到ut_parsejson()函数的dm_genericcallback()函数以创建装置属性注册表。

驱动器层164的根本操作是使用驱动器名称和属性类型以检索适合的读或写片段(如果存在)。当从驱动器166取得属性时,检索读片段,且当将属性写入到驱动器166时,检索写片段。驱动器层164随后使用适配器解析器执行检索到的片段以执行转换。如果未找到驱动器名称的映射,那么驱动器层164可执行以下逻辑:

●如果操作为写入,那么将属性传递到驱动器166,所述驱动器可忽略其未识别的任何属性。一个例外是,如果属性状态为“未决,”那么驱动器将属性的状态改变成“确认”以确认接收到属性;以及

●如果操作为读取,那么不将属性传递到数据架构,且忽略属性,除非所述属性是专门未映射的属性的集合中的一个,包含基础和通用装置属性,例如“name、”“id”、“group、”“type”等。此逻辑确保数据架构未用其不理解的内部驱动器产生的属性填满,同时允许驱动器166简化输出其知道的所有属性,而不必确定数据架构关注的是哪些属性。

返回到列表11,将更详细描述适配器语言片段的性质。“roomtemp”和“thingworx”驱动器的第一实例示出,在内部,“thingworx”驱动器具有属性“thermostatshape_roomtemp,”所述属性为实值。数据架构属性“roomtemp”也为实值。不需要缩放以在两个值之间映射。当属性“roomtemp”跨越驱动器层164移动时,仅需要名称改变。

在实施方案中,适配器语言的独特功能是前面为令牌“@@”的任何属性名称是指目标侧的属性。也就是说,对于读取操作,前面为“@@”的名称是指数据架构属性,且对于写入操作,前面为“@@”的名称是指驱动器属性。相反地,前面为仅单个“@”的任何属性名称是指源侧的属性。也就是说,对于读取操作,前面为单个“@”的名称是指驱动器属性,且对于写入操作,前面为单个“@”的名称是指数据架构属性。不同的令牌允许引用不同的数据模型这一事实使适配器语言理想地用于将数据从一种格式或模型映射到另一种,同时维持干净且简单的句法。应注意,用基础脚本语言写入的脚本将一般不需要此特征,因为不需要跨越数据架构内的不同数据模型进行映射。因此,适配器语言中的此特征可能不能类似地可用于基础脚本语言(或可在句法上得到支持,而是被忽略)。

替代地,在赋值的左手侧上出现的任何属性名称是指目标侧的属性。也就是说,对于读取操作,左手侧属性名称是指数据架构属性,且对于写入操作,左手侧属性名称是指驱动器属性。相反地,在赋值的右手侧上出现的任何属性名称是指源侧的属性。也就是说,对于读取操作,右手侧属性名称是指驱动器属性,且对于写入操作,右手侧属性名称是指数据架构属性。赋值语句的不同侧是指不同的数据模型这一事实使适配器语言理想地用于将数据从一种格式或模型映射到另一种,同时维持干净且简单的句法。

参考列表11中的“roomtemp”属性的“thingworx”驱动器的读取片段,基础语言属性引用格式(即,“@dev_name[dev_id].propname”)可通过省略装置名称(“dev_name”)和装置id(“dev_id”)两者来缩短适配器片段以产生“@.propname”的简化格式(例如,列表11中的“@.roomtemp”)。这是因为,在适配器上下文中,装置名称和装置id都不相关,因为片段同样地适用于驱动器为“thingworx”和数据架构属性为“roomtemp”的所有情况。通过省略装置名称和装置id(所述装置名称和装置id在执行片段时可从调用上下文获得),获得通用地适用于属性和驱动器的每一组合的片段。因此,进行属性映射所需的所有事物为到或从数据架构属性或驱动器属性的简单赋值,所述赋值在第一实例中所说明。

“doorlockstatus”的第二实例示出更加复杂的情况:

在此实例中,“thingworx”驱动器在内部将“doorlockshape_lockmode”保持为具有如下两个值的实数:对于锁定为值“255,”且对于未锁定为值“0。”在数据架构侧上,属性“doorlockstatus”保持为具有“locked”或“unlocked”的两个值的字符串。因此,当属性“doorlockshape_lockmode”跨越驱动器层164移动时,名称和数据类型两者都需要改变。

对于列表11中的“doorlockshape_lockmode”属性,“thingworx”驱动器的读取片段使用三元运算符(即,(expression)?trueval:falseval)来完成必要的映射。读取片段还说明内置函数的使用。具体地说,读取片段使用int()函数以便将“doorlockshape_lockmode”属性的实值转换成整数,使得相等运算符(即,“==”)可用于表达条件。写入片段使用与读取片段类似的技术。

“justtesting”驱动器的第三实例说明复杂得多的映射:

在此情况下,“brightness”属性在数据架构中保持为在0至100的范围内的整数。在“justtesting”驱动器中,“lightlevel”属性保持为选自“dark”、“dim”、“normal”、“bright”以及“dazzling”的字符串。将整数值映射到这些字符串值中的一个提出挑战。然而,此挑战可使用适配器语言的内置函数来克服。

例如,在读取片段中,内置setindex()函数用于获得驱动器属性的字符串值的索引,所述字符串值可为“dark、”“dim”、“normal”、“bright”或“dazzling。”在所说明的实例中,setindex()在“lightlevel”属性值为“dark”时将返回1的索引,在“lightlevel”属性值为“dim”时将返回2的索引,在“lightlevel”属性值为“normal”时将返回3的索引,在“lightlevel”属性值为“bright”时将返回4的索引,以及在“lightlevel”属性值为“dazzling”时将返回5的索引。接着,内置indexset()函数将通过setindex()返回的索引应用于值的集合,其中索引1对应于“0,”2对应于“25”,3对应于“50”,4对应于“75,”且5对应于“100,”以返回0、25、50、75或100的整数值。通过将setindex()调用嵌套在indexset()调用内,单行片段可用于将“justtesting”驱动器的“lightlevel”属性的“dark”、“dim”、“normal”、“bright”以及“dazzling”的字符串值分别映射到数据架构的“brightness”属性的0、25、50、75以及100的整数值。

写入片段更加复杂,因为数据架构中的“brightness”属性可设定为不等于0、25、50、75或100的整数值。因此,内置rangeindex()函数用于将数据架构中的“brightness”属性的整数值(所述整数值可在0与100之间)映射到1、2、3、4或5的索引。rangeindex()函数继续执行以便匹配小于或等于指定值的任何数。因此,0的整数值产生索引1,在1与24之间的整数值产生索引2,在25与74之间的整数值产生索引3,在75与99之间的整数值产生索引4,且100的整数值产生索引5。随后内置indexset()函数用于将通过rangeindex()返回的索引1、2、3、4或5分别映射到字符串值“dark”、“dim”、“normal”、“bright”或“dazzling”中的一个。同样地,通过将rangeindex()调用嵌套在indexset()调用内,单行片段可用于将在0与100之间的任何整数值映射到“dark”、“dim”、“normal”、“bright”以及“dazzling”的字符串值中的一个。

出于说明多行片段的使用的目的,来自用于“thingworx”驱动器的“sirenstrobesetting”属性的实例模式在下方说明:

在此实例中,读取和写入片段都利用多行语句,具有中间变量“a”和条件语句。如通过此实例所说明,适配器语言能够用片段表达几乎任何变换。另外,内置函数可按需要扩展以使常用片段操作尽可能地简单和简洁。

所描述的方法的实施方案的一个优点是驱动器层164中的映射完全通过模式数据驱动。更新或添加到这些映射不需要对任何代码进行重新编译。此快速改变的能力促进对连接装置的较大且不断变化的集合的多个驱动器和传输协议的管理,同时降低维护和集成成本以及时间需要。

6.1.8.调用驱动器层

在实施方案中,两个函数涉及驱动器层164的调用:

列表12中所说明的两个函数在成对的函数dm_getdeviceproperty()和dm_setdeviceproperty()内被调用,所述dm_getdeviceproperty()从插件式驱动器166读取属性值,所述dm_setdeviceproperty()将属性值写入到插件式驱动器166。这些成对的函数被vm230和/或控制器130用于在实际上从脚本到装置驱动器166的直接调用中读取和写入属性。对这些函数的调用使得呈通过数据架构指定的格式的数据被路由到装置管理器160,且最后在装置管理器抽象162内被解析成对dm_setdeviceproperty()或dm_getdeviceproperty()的局部调用。

适配器语言解析器的完整操作可通过与本文中描述的基础语言解析器的操作类比而得到。然而,应理解,适配器语言解析器将比基础语言解析器简单得多,因为适配器语言具有比基础语言适配器更简单的句法和语义。

6.2.解析json数据编码标准

类似于脚本管理器210,装置管理器160与控制器130介接,产生呈数据架构的数据格式的包以发送到控制器130,并接收从控制器130发送的呈数据架构的数据格式的包。如本文中在其它地方所提及,在实施方案中,数据架构的此数据格式使用json。关于基础脚本语言详述的相同基本json解析器技术可被装置管理器160用于这些目的,且因此,将不单独地关于装置管理器160进行详细描述。应理解,json的替代数据格式可通过用替代数据格式的解析器来替换json解析器来支持。

6.3.装置驱动器注册表和api

在实施方案中,在所注册的驱动器166与装置管理器160之间的公共接口包括四个api调用:

dm_devmgrinit()函数在系统启动期间通过每一驱动器166调用以注册必要的回调,所述回调允许装置管理器160介接到并调用特定驱动器166。如所说明,驱动器166必须提供三个回调函数以完成连接。第一个llcallbackfn被称为低级驱动器回调函数,并在装置管理器160与驱动器166之间形成主要接口。另外两个回调函数是装置迭代器函数lldeviceiteratorfn和属性迭代器函数llpropertyiteratorfn。全局上下文值globalcontext可通过装置管理器160指定并传递到所调用的任何回调函数,由此允许回调函数访问全局变量及类似者。装置迭代器函数和属性迭代器函数被装置管理器160用于分别在所有装置和其属性上迭代,指定的驱动器166知道所述装置和属性,由此实现所有连接装置(即,虚拟或硬件装置)的当前状态的完整图像。

dm_devmgrterm()函数在系统终止处通过每一驱动器166调用,以注销驱动器166并执行与驱动器166相关联的存储清除或释放。

dm_devmgrinit()函数有可能针对同一驱动器166被调用多次。如果这样,那么对dm_devmgrinit()函数的调用可使内部驱动器使用计数器递增,所述计数器必须在驱动器166被注销且其相关联的存储装置终止之前通过匹配次数调用dm_devmgrterm()函数递减到零。换句话说,在驱动器166可被注销且其相关联的存储装置可被终止之前,对dm_devmgrinit()函数的每一调用必须一一对应于对dm_devmgrterm()函数的调用。

每当驱动器166更改装置属性的值或状态或经历装置属性的值或状态的变化时,dm_devmgrnfy()函数被驱动器166调用。dm_devmgrnfy()函数是以下机制:通过所述机制将在装置级处发生的变化告知系统的其余部分(例如,脚本执行环境150)。

dm_devmgrpoll()函数被每一驱动器166频繁地调用。dm_devmgrpoll()函数是以下机制:通过所述机制,来自系统的其余部分(例如,脚本执行环境150)的新命令和装置属性值通过对所注册的回调函数的调用传送到驱动器166。dm_devmgrpoll()函数的使用约束执行此类异步调用(例如,由通过控制器130、平台110和/或在脚本执行环境150内执行的脚本所进行的装置属性改变引起)所处的时间。这使驱动器166的编程模型变得简单得多,因为所述编程模型不必在任何其它时间处与来自装置管理器160的异步命令或调用竞争,如根据需要,例如在完全抢占式布置中。

6.4.装置管理器和驱动器线程模型

存在装置管理器160、脚本执行环境150以及驱动器166的多个可能的布置,包含其中这些部件中的每一个处于单独的过程中的布置,和/或其中所有这些部件可在不同的计算节点上的布置。每一此布置具有不同的优点和缺点。

最常用的线程模型包括每个使用不同的传输协议(例如,bluetoothtm、z-wavetm、zigbeetm等)以通信方式连接到两个或更多个不同驱动器的脚本执行环境150和装置管理器160的统一过程。所有这些部件都存在于在网关120的控制器130中运行的单个过程内的多个抢占式线程内,其中脚本执行环境150和装置管理器160统一在单个线程中,且驱动器在一个或多个不同线程中。如果存在仅单个驱动器,那么用于所述单个驱动器的线程还可在单个线程中与脚本执行环境150和装置管理器160统一,由此消除两个队列并改进吞吐量。

图7说明根据实施方案的具有两个实例驱动器dr.x和dr.y的实例统一线程模型。在此实例中,dr.x线程720经由传输层726以通信方式连接到四个装置728a至728d。类似地,dr.y线程730经由传输层736以通信方式连接到四个装置738e至738h。应理解,在每一情况下,通信连接可为硬连线的(例如,串行链路、输电线、以太网线缆等),或无线的(例如,无线电、wi-fitm、bluetoothtm、蜂窝网等)。事实上,每一传输协议往往指定所需线程布置,但出于此实例的目的,将假设每一驱动器线程dr.x720和dr.y730拆分成两个工作者线程:(1)分别为读取线程722和732,所述读取线程分别从传输层726和736进行读取;以及(2)分别为写入线程724和734,所述写入线程分别写入到传输层726和736。这些读取和写入线程有效地将每一驱动器线程dr.x720和dr.y730分别连接到装置728和738的集合。读取线程722和732分别将到驱动器线程dr.x720和dr.y730的消息排队,且写入线程724和734分别将来自驱动器线程dr.x720和dr.y730的消息排队。

在实施方案中,驱动器线程720执行无限主循环,所述循环处理来自现实世界装置(即,来自读取线程722)或经过“所设定”的队列的输入,所述队列通过统一的装置管理器和脚本管理器线程715(例如,在所述线程调用dm_setdeviceproperty()函数时)填充。所设定的队列在通过驱动器线程720对dm_devmgrpoll()函数的定期轮询调用期间排出。驱动器线程720中的主循环还处理经由传输层726到现实世界装置(即,到写入线程724)或到统一的装置管理器和脚本管理器线程715的“get”队列的值的输出。驱动器线程720通过调用dm_nfydevmgr()函数来填充所排队列,且统一装置管理器和脚本管理器线程715定期地使所排队列排出(例如,通过调用dm_getdeviceproperty()函数)。

每一驱动器720和730在其自身隔离的线程(所述线程一般与统一装置管理器和脚本管理器线程715不同)内执行这一事实简化驱动器的写入,并允许未经设计用于数据架构的预先存在的驱动器容易地用数据架构包装。这些预先存在的驱动器可存在于完全单独的过程中,其中所有必要的通信使用平坦的“et_stringlist”模型来实施以传输复杂的数据,并避免串行化和去串行化的开销。因为dm_getdeviceproperty()和dm_setdeviceproperty()函数利用所包括的装置的驱动器的知识,所以所述函数可充当在统一装置管理器和脚本管理器线程715与所述线程所连接的各种驱动器(例如,如通过驱动器注册表发现)之间的主要路由机制。

在其它配置中,不同的经注册驱动器可造成不同的路由行为。例如,在基础脚本语言的独立解译器的实施方案中,唯一注册的驱动器是将经编码数据(例如,经json编码的数据)发送到控制器130并从所述控制器接收经编码数据的驱动器。这意味着,就调用dm_getdeviceproperty()和dm_setdeviceproperty()函数而言,有可能在平台110上而非网关120上运行的独立解译器的操作与统一装置管理器和脚本管理器线程715的操作相同。行为和路由上的差异可通过基本驱动器注册表来实现。有利地,这允许在广泛范围的配置中应用相同的代码基础,而不需要专门化行为。换句话说,支持多个驱动器和传输层的初始架构决策被利用并扩展以支持各种架构部件的多个配置。

6.5.驱动器回调

如关于驱动器apidm_devmgrinit()函数所论述,在实施方案中,驱动器166在其向装置管理器160注册时提供三个根本回调。这些回调的c函数原型如下:

最广泛使用的回调函数一般将为dm_devmgrcallbackfn()函数。为说明此回调函数内的逻辑,现将参考下方的列表14描述实例骨架驱动器回调函数,所述骨架驱动器回调函数设计为实际驱动器回调函数的起始点:

列表14中的逻辑已出于说明而目的而简化。虽然需要多个另外的行为来实施真实的驱动器,但这些行为是微妙的且对此描述不重要。

“kdevmgrremovedevice”命令的逻辑移除装置,且“kdevmgrdeleteproperty”命令的逻辑删除装置属性。这些命令就基本传输协议而言实际上意指的内容是待针对每一特定驱动器166确定的事情。当控制器130或平台110试图从网关120移除已知装置(例如,连同可针对装置驱动器维持在内部的数据库一起)时,将发出“kdevmgrremovedevice”命令。例如,装置可从一个网关120移除并添加到另一网关。在装置将从其移除的网关120处,“kdevmgrremovedevice”命令将在装置将从其移除的网关120处发出,而“kdevmgrputdevice”命令将在装置将添加到其上的网关处发出。“kdevmgrdeleteproperty”命令极少被使用,且将可能仅在校正属性的意外添加的过程中出现。

对于“kdevmgrgetproperty”命令,驱动器166必须从指定装置获得所请求的属性值,并用内部驱动器格式将其写入到所输出的缓存“avalue。”此属性值将通过驱动器层164自动转换成数据架构的数据格式。因为“kdevmgrgetproperty”命令通过属性的驱动器名称寻找属性,所以驱动器166不需要关注数据架构的数据格式,或甚至数据架构中的属性名称可能为何。“kdevmgrgetproperty”命令可源自在装置管理器160内对dm_getdeviceproperty()函数的调用。

对于“kdevmgrsetproperty”命令,驱动器166在其识别出指定的装置属性时,将指定的装置属性写入到装置,并将属性状态告知装置管理器160并确认所述属性状态。用“kdevmgrsetproperty”命令传入的属性的状态的值将为“未决的,”因为,在实施方案中,驱动器166是被允许将属性状态改变成“确认”的唯一权威机构。“kdevmgrsetproperty”命令可源自在装置管理器160内对dm_setdeviceproperty()函数的调用。

当控制器130和/或平台110从装置管理器160请求对装置的当前状态的确认时,使用“kdevmgrputdevice”命令。“kdevmgrputdevice”命令并不隐含对改变任何装置属性的请求,而是仅表示用于驱动器166校正装置的当前状态的控制器的和/或平台的图像的机会。因此,“kdevmgrputdevice”命令的逻辑类似于“kdevmgrsetproperty”命令,除了进入的属性值实际上并未写入到装置。

列表14中所说明的五个命令允许控制器130和/或平台110通过装置管理器160和适合的驱动器166,执行控制和活动监视,包含通过在脚本执行环境150中运行的脚本禁止的装置相关的活动。

在实施方案中,两个迭代器回调函数dm_devmgrdeviteratorfn()和dm_devmgrpropiteratorfn(),可被装置管理器160用于在网关120的启动期间将所有连接的装置的全部状态的初始快照发送到控制器130和/或平台110。每一驱动器166可实施其自身的过程以用于发现所述驱动器应进行以经由传输协议在其装置上迭代的操作,且随后在那些装置的任何和所有属性上迭代。驱动器166可忽略控制器130或平台110是否实际上关注任何特定属性。

现将描述在装置管理器160内使用所注册的迭代器的实例伪代码:

尤其地,驱动器166自身可利用通过装置管理器160提供的其它公共api,以便简化驱动器166的实施和操作。确切地说,以下函数和抽象中的一个或多个可通过所注册的驱动器166使用:

●ut_logentry()函数可用于添加webgui的登录条目;

●装置管理器“字典”抽象可用于通过驱动器166进行的所有符号存储,而非常规的数据库;

●可利用装置注册表抽象;

●成对的函数ut_setpropertystate()和ut_getpropertystate()提供跨越所有注册的驱动器166对所有装置和其属性的当前状态的装置管理器的记录的完全访问;

●每一驱动器166可使用基本解析器抽象来实施其解析功能性以用于解译传输协议,所述驱动器经由所述传输协议操作;

●装置管理器160可维持装置群组的内部注册表并提供api函数,例如dm_ingroup(),每一驱动器166可访问所述函数以用于处理装置群组;

●驱动器层164的api可用于驱动器166以用于更加高级的逻辑目的;和/或

●只要可能,驱动器166就可遵循相同的译码标准,并将相同的所发布分配器用作装置管理器160和脚本管理器210,由此使驱动器166可访问所有内置调试功能性(例如,错误报告、泄漏检查等)。

6.6.处理数据架构命令

如本文中在其它地方所论述,在实施方案中,数据架构的数据格式为json。在此实施方案中,处理即将到来的命令的任务本质上是执行包含那些命令的json的解析中的一个。此过程可在根本上与json数据编码标准的解析和用于转换成基础语言脚本的gui脚本的解析相同,如在本文中的其它地方关于基础脚本语言所描述。因此,此处不提供详细说明。替代地,以下列表提供涉及解析“kjson_newmemberval”命令的逻辑的注解:

●如果json路径以“:op”结束,那么这是命令类型;

●如果json路径不以“:status”结束,那么这是属性值设定“kvalueprocessed;”

●如果json路径以“type:{:value[”结束,那么执行专门化的逻辑、合并逗号分隔的值;

●如果json路径以“group:{:value:[:{:$ref”结束,那么所述路径平坦化成装置群组引用,且合并逗号分隔的值;

●如果json路径以“group:{:value:[:{:name”结束,那么所述路径平坦化成群组名称,且合并逗号分隔的值;

●如果json路径以“:ref”或“.id”结束,那么这是装置id;

●如果json路径以“.name:{:value”结束且不包含“group:{value:,”那么装置被注册;以及

●如果json路径以“:status”结束,那么这是属性状态,所述属性状态被赋给“kstatusprocessed。”

在实施方案中,在处理每一“kjson_newmemberval”命令之后,调用dm_processcompleteval()函数。dm_processcompleteval()函数查看“kstatusprocessed”和“kvalueprocessed”标志以确定处理属性需要的所有数据是否都可用。如果是,那么在涉及“群组”和“类型”属性的某些逻辑例外的情况下,dm_processcompleteval()函数调用dm_setdeviceproperty()函数,这最终导致适合的驱动器166被调用。

6.7.构造响应

如本文中在其它地方所论述,在实施方案中,数据架构的数据格式为json。在此实施方案中,产生即将离去的命令的任务本质上是将装置管理器的内部注册表(例如,由对dm_devmgrnfy()函数的调用引起的状态更新)中的一个或多个的条目转换成json格式中的一个。

在实施方案中,不管目的为何,所有内部注册表都基于在‘749专利案中描述的平坦存储器模型来使用“et_stringlist”结构。此逻辑的细节在本文中的其它地方关于vm程序格式描述。在此实施方案中,构造任何json响应实质上归结为将字符串列表中的相关条目分组在一起,且随后将字符串列表转换成json格式。在实施方案中,此模式在整个脚本执行环境150和装置管理器160上重复。在相反方向上,即将到来的json消息一般转换成“et_stringlist”格式以用于内部使用。因此,这些字符串列表在两个方向上经过图7所说明的各种队列。将json转换成内部字符串列表的过程在本文中的其它地方描述,因为,在本文中的其它地方描述的json解析器内,存在对例如dm_registerdevice()、ut_setsymbol()、ut_setpropertystate()、su_setscript()、ma_setsymbol()以及ma_runmarlin()等函数的调用。所有这些函数最终在字符串列表中创建条目,所述条目随后被其它逻辑使用。在实施方案中,字符串列表还对字典抽象很重要。因此,在实施方案中,字符串列表形成基础脚本语言和基础语言解析器内的所有符号值的基础。

现将关于dm_flushstatusupdates()函数描述产生呈数据架构的数据格式(例如,json)的响应的一个实例,所述函数产生呈数据架构的数据格式的输出,所述输出描述所有装置和已通过对dm_devmgrnfy()函数的驱动器调用来改变的属性:

在json为数据格式的实施方案中,以上列表15中的逻辑的最终结果是类似于以下的消息包:

在此情况下,以上json消息通过列表15的逻辑产生,因为“brightness”属性的值通过驱动器设定为25,且同一装置没有其它属性被更改(否则,那些属性将形成同一消息的部分)。“id”、“name”以及“group”属性通过列表15的逻辑添加到消息以用于清晰性,即使那些属性没有改变。

应理解,所有其它情况以与上文描述的dm_flushstatusupdates()函数类似的方式操作。如列表15中所示的相同技术可用于将任何内部字符串列表转换成广泛范围的其它数据格式(即,除json外)以用于广泛范围的其它目的。

6.8.装置群组

在实施方案中,数据架构实现任意命名的装置群组的创建,所述装置群组包括任意数目的装置作为成员。这些装置群组可用于将装置组织成方便的集合以供用户使用。

然而,装置管理器160可扩展这些装置群组的功能性和效用。这些装置群组对数据管理器160表现为虚拟装置,保持在平台110上,没有对应的物理显示。一个扩展是这些装置群组可通过数据架构和通过脚本用于设定任何成员装置的属性的值,所述成员装置具有所述属性。

在实施方案中,装置群组的设定处于dm_setdeviceproperty()函数的实施内,所述函数在下方的列表16中说明:

在列表16中说明的逻辑的净作用是,当给定属性(例如,“brightness”)的给定值赋给装置群组时,所述给定值赋给表示所述装置群组的虚拟装置的属性。逻辑随后提取装置的字符串列表,所述装置是来自装置管理器160的内部群组注册表的装置群组的成员;并循环经过所有成员装置,调用dm_getdeviceproperty()函数以确定装置是否具有给定属性。对于具有给定属性的每一成员装置,逻辑通过调用dm_setdeviceproperty()函数将给定值赋给给定属性。另一方面,对于不具有给定属性的每一成员装置,不执行赋值。

作为实例,假设房屋中的所有装置都是名称为“室内装置”的装置群组的部分。为将房屋中的所有可调光装置变成50%亮度,脚本需要的所有事物为单个语句:

@indoor_devices.brightness=50;

此单个脚本语句将使得装置管理器160循环,如列表16中所说明,将50的值赋给在具有“brightness”属性的“室内装置”群组中的每一装置的“brightness”属性。“室内装置”群组中的没有“brightness”属性的那些装置将保持不变。此给装置分组并赋予属性值的能力简化编写脚本,从而减少通信业务的量,并实现通用脚本的创建,所述通用脚本可通过简单地将在给定设施处的物理装置分配给一个或多个装置群组来在许多不同情况下应用。

尤其地,因为装置群组通过虚拟装置表示,所以如果装置群组先前不具有“brightness”属性,那么当第一次将具有“brightness”属性的装置添加到所述装置群组时,所述装置群组将获取“brightness”属性。这是因为一添加具有“brightness”属性的装置,dm_setdeviceproperty()函数就将使得“改变”消息以装置群组的“确认”状态发送到控制器130和/或平台110。继而,可用于脚本gui中的装置群组的属性的列表随后将自动地包含“brightness”属性。另外,执行中的脚本将能够使用“@indoor_devices.brightness”来读取或写入“brightness”属性,所述“@indoor_devices.brightness”最终解析成对dm_getdeviceproperty()函数的调用(或通过使用内部高速缓存短路)。

6.9.装置管理器初始化

现将描述初始化装置管理器160并注册驱动器166的过程。在实施方案中,在装置管理器160的运行时间操作之前进行的初始化活动包含:

(1)一旦静态地初始化,装置管理器160就首先建立到平台110的连接,且认证自身和网关120,所述装置管理器驻留在所述网关中;

(2)在成功认证(例如,通过来自平台110的响应指示)之后,装置管理器160首先发送“配置”消息,且随后订阅平台110上的模式,所述平台如本文中的其它地方所论述,保持所有属性信息和驱动器层164所需要的驱动器映射。装置管理器160还订阅本地网关120的所有装置。订阅意味着,平台110将发送所有相关项的完整“放置,”且随后,如果任何项或属性改变,那么平台110将发送消息以更新网关120的所有订阅过程,包含装置管理器160、脚本执行环境150和/或本地控制器130;

(3)一旦已接收到模式,装置管理器160就调用dm_getalldevices()函数,并将结果的装置快照发送到平台110和/或控制器130,由此确保所述平台和/或控制器的装置状态的图像匹配通过注册的驱动器166返回的图像;以及

(4)在统一装置管理器和脚本管理器线程715的情况下,对所有脚本的订阅还从平台110发送到脚本执行环境150以被脚本执行环境150使用。

当新驱动器被创建(例如,针对新协议、新装置等)时,新驱动器可添加到模式。因此,在网关120上的订阅模式(例如,作为配置文件存储在平台110上)的装置管理器160的初始化期间,装置管理器160解析模式,包含待激活的所有驱动器的列表和那些驱动器可需要的任何另外的初始化参数(例如,ip地址、端口号等)。随后例如使用dm_devmgrinit()函数来注册经解析的驱动器,使得到装置管理器160的初始化完成时,装置管理器160精确地连接到经定义用于其操作环境的驱动器的集合。

6.10.通用驱动器抽象

在实施方案中,装置管理器160包括通用驱动器(ud)抽象层。图9说明根据实施方案的此通用驱动器抽象层。此通用驱动器抽象层910可通过以标准化方式处理任何驱动器所需的逻辑的大部分而不管传输介质,大幅度地简化并统一在通用驱动器抽象基础上构建的所有驱动器166的实施,使得创建任何驱动器所需的唯一代码仅是从硬件装置读取和/或写入所需要的,如且在被通用驱动器抽象告知(例如,基于在驱动器注册时设定的配置参数)时。此抽象允许以真的与驱动器无关且与传输无关的方式,快速且可靠地实施针对现有和新传输协议的接口。因此,通用驱动器抽象层910可表示装置管理器160的强大的特征。

在实施方案中,所有驱动器166是直接地基于通用抽象层910,而非装置管理器抽象层162。通用驱动器抽象层910向装置管理器抽象层162注册每一驱动器166,由此允许通用驱动器抽象代码本身插入在装置管理器抽象层162与所述装置管理器抽象层的每一不同的所注册低级驱动器166的回调和传输特定代码之间。在通用驱动器抽象层910在装置管理器160内的位置中,所述通用驱动器抽象层可提供其自身的行为和注册需要,以便实现所有可能的驱动器活动(例如,轮询、事件驱动的活动、硬件读取和/或写入操作、恢复、调试控制台界面、pdev至ldev映射、通过映射片段基于属性变化进行的调度等)。在许多情况下,结果是所需的驱动器特定的代码仅为数百行,即,仅足够在请求时与基本传输机制通信。图9说明仅少量可能的驱动器166,包含zwavetm驱动器166b、phidgettm驱动器166c以及modbustm驱动器166d,这些驱动器分别支持zwavetm、phidgettm以及modbustm。这些驱动器166中的一些,例如zwave驱动器166b,可比其它驱动器更加复杂,因为例如zwavetm驱动器166b可需要将维护和发现功能性并入在其本身的协议内。

在实施方案中,驱动器166包含实施虚拟装置的虚拟驱动器166a。尽管虚拟驱动器166a可向通用驱动器抽象层910注册,但所述虚拟驱动器不需要物理至逻辑映射层920的复杂性,且因此,不需要利用物理至逻辑映射层920的注册表。所有其它驱动器166(例如,驱动器166b至166e)一般将利用这些注册表,因为这些驱动器将通常需要与物理装置和传输协议交互。

在实施方案中,通用驱动器抽象层910向装置管理器抽象层162注册其自身的回调函数,同时在内部管理通过相应的驱动器166注册的任何回调函数。通用驱动器抽象层910向装置管理器抽象层162注册的回调函数可包括以下逻辑:

●如果ll代码已向通用驱动器抽象层910注册装置类型特定的回调函数,那么在登录时调用装置类型特定的回调函数,且随后在退出时再次调用装置类型特定的回调函数;

●对于“kdevmgrputdevice”和“kdevmgrsetproperty”命令,调用驱动器特定的低级回调,且如果未被禁止,则通过调用dm_devmgrnfy()函数来处理通知;

●对于“kdevmgrgetproprty”命令,调用低级回调;以及

●对于“kdevmgrdeleteproperty”和“kdevmgrremovedevice”命令,调用低级回调并自动地处理通知。

在实施方案中,通用驱动器抽象层910还提供内置装置和属性迭代器(例如,以被装置管理器抽象层162使用),其通过使用标准注册表来操作,由此允许大部分驱动器166避免必需自身实施此功能性。然而,驱动器166可选择通过向通用驱动器抽象层910注册替代的迭代器来覆盖这些默认迭代器。

在实施方案中,通用驱动器抽象层910提供标准化通用驱动器线程,所述线程实施初始化每一驱动器166(和任何物理装置)并在针对来自物理装置的属性变化进行轮询的循环中运行每一驱动器166所必需的逻辑。此逻辑还可处理通用驱动器线程的终止和清除。通用驱动器线程可为“协作”线程,因为所述通用驱动器线程通过所述架构的主循环逻辑调度,且在驱动器166的执行期间,其它线程,例如vm230和/或其它驱动器166,被阻断。此协作通用驱动器线程的优点是,所述通用驱动器线程可使用api,所述api访问全局变量和注册表而不必担心造成其它上下文中的混淆。这与抢占式“工作者”线程形成对比,所述线程与所有其它活动异步地且并行地执行与传输层的通信。通常,工作者线程必须通过以下操作来获得其输入并写入其输出:变得暂时性协作,或将协作通用驱动器线程的这些活动排队以进行处理。

根据实施方案,协作通用驱动器线程的基础逻辑可如下实施:

在实施方案中,这是通用驱动器抽象层910的全部逻辑,除了少数效用函数。大部分复杂性与通过物理至逻辑层920创建并维护的注册表和映射环境相关联,所述物理至逻辑层通过所注册的驱动器166的代码明确地调用。

在实施方案中,通用驱动器抽象层910具有以下属性中的一个或多个:

●提供虚拟驱动器,所述虚拟驱动器包含使“智能”行为与不同的虚拟装置类型相关联的能力;

●提供一个或多个api以简化新驱动器的创建;

●提供通用驱动器抽象以简化驱动器166的逻辑;

●提供物理/逻辑抽象以在装置属性在任一方向上变化时,借助映射片段映射到物理装置(pdev)和一个或多个相关联的逻辑装置(ldevs)的注册表表示和从所述注册表映射。映射片段可用基本的基础脚本语言的第二变型写入(所描述的适配器语言是基础脚本语言的第一变型);和/或

●对每一驱动器到调试和维护控制台的接口提供抽象支持。

6.11.虚拟驱动器

在实施方案中,虚拟驱动器166a负责实施虚拟装置,即,没有对应的硬件的装置。因为虚拟装置的属性不驻留在通过较大环境提供的标准属性注册表中,所以当例如通过脚本写入虚拟装置属性时,一般不需要进行任何操作,因为新值已被写入到注册表。当通过脚本读取虚拟装置属性时,它的值可从注册表获得。因此,一般来说,预期虚拟驱动器166a没有超过通过本文中在其它地方描述的通用驱动器回调提供的行为的积极任务。

在实施方案中,虚拟驱动器166a能够注册装置实施器,所述装置实施器允许创建具有复杂且活动的属性行为的虚拟装置。此类虚拟装置可用于将功能性添加到数据架构。为说明此概念,现将论述两个实例:“定时器”装置,和“数据流”装置。

装置实施器可在虚拟驱动器166a的初始化期间注册,且本质上注册通过通用驱动器抽象层910调用的另外装置类型特定的回调函数,如在列表17中所说明。注册这些回调的虚拟装置类型可被称为“智能”虚拟装置(所述虚拟装置可在本文中被称为“s-vdev”),而不注册这些回调函数的虚拟装置是有效被动存储装置或“哑”虚拟装置(所述虚拟装置可在本文中被称为“vdev”)。“定时器”装置的典型的s-vdev注册可看起来如下:

“devinittermfn”回调函数负责装置类型特定的初始化和终止,如在“定时器”装置的以下实例中所说明:

“定时器”装置的对应的轮询函数如下说明:

如上文所示出,轮询函数处理与定时器的到期相关联的所有逻辑,同时还动态地更改轮询速率以使装置实施开销最小化。

用于处理在定时器状态被更改(例如,通过用户在界面114的gui中或在脚本中更改)时发生的情况的逻辑,在所注册的装置类型的回调函数内的“kdevmgrsetproperty”情况中找到,如下:

以上代码产生活动的虚拟定时器装置,所述装置的调用经由通用驱动器抽象层910完全控制。其它驱动器166有可能利用此功能性来创建“混合”装置。当基于物理/逻辑抽象层910时,这些驱动器可实施在物理/逻辑抽象层910的片段(例如,用类似于适配器语言并类似地基于基础脚本语言的通用驱动器语言写入)内的任何逻辑。

智能虚拟装置的另一实例是“数据流”装置。“数据流”装置是复杂得多的虚拟装置,所述虚拟装置的多至例如十个“信道”属性值可通过其它装置属性值驱动(例如,经由注册表,且因此不管驱动器),且所述虚拟装置的那些信道属性值和所述信道属性值的任何改变可准确地记录到平台110(例如,且在界面114的gui中观察到)。因此,任何装置属性的详细按时间排序历史可在平台110上创建。本质上,“数据流”装置充当实现对装置属性的时间历史的检查的内置示波器或逻辑分析器。“数据流”装置可使用在根本上与“定时器”装置类似的所注册回调函数来实施。

6.12.物理/逻辑层

在实施方案中,物理/逻辑层920驻留在通用驱动器抽象层910下方,并通过使用与所涉及的pdev和ldev相关联的脚本,将物理装置表示(pdev)映射到逻辑装置表示(ldev)。这些映射可用基础脚本语言写入,或用类似于用于在驱动器层164中创建片段的适配器语言的基础脚本语言的子集写入。在基于通用驱动器抽象层910的驱动器166的情况下,pdev和ldev属性可保持在以与标准架构注册表相同或类似的方式实施的注册表的完全单独的集合中,但仅对向通用驱动器抽象层910注册的驱动器可见。

在实施方案中,物理/逻辑层920解决两个问题:(1)将硬件数据结构和命令协议映射到pdev属性并从pdev属性映射;以及(2)每当装置属性在任一方向上改变时,通过在适当时调用映射片段来将pdev和ldev属性映射到彼此和从彼此映射。ldev可与通过公布ldev而为系统的其余部分所知道(即,经由驱动器层164)的装置相关联。物理装置可具有复杂的结构,所述结构经设计以精确地映射到特定硬件布置,并使将硬件值传递到传输协议和从传输协议传递硬件值的过程自动化,使得低级驱动器代码本身不需要知道这如何进行。低级驱动器代码简单地读取和写入值,如、在以及当它被请求用通过物理/逻辑层920提供的传输所需要的所有参数来这样做。因此,低级驱动器代码相对较简单,且问题移动到pdev、ldev以及用于将任何给定pdev连接到一个或多个子ldev的映射片段的规范中,所述子ldev继而经由驱动器层164映射到数据架构。

正如适配器语言一样,用于在物理/逻辑层920中写入映射片段的物理/逻辑语言可为基础脚本语言的变型。然而,所述映射片段运行的上下文通过所涉及的pdev和ldev和在pdev或ldev中的属性预定义,所述属性使得映射片段在第一位置运行。如适配器语言一样,每当映射片段运行时,物理/逻辑语言可具有从一个装置到另一装置的隐含方向。当在从pdev到ldev的方向上运行时,此方向可被称为“ktological,”且当在从ldev至pdev的方向上运行时,此方向可被称为“ktophysical。”类似于适配器语言,此方向性可通过使用“@”令牌或“@@”令牌来指示,所述“@”令牌指示属性与映射的源侧上的装置相关,所述“@@”令牌指示属性与映射的目标侧上的装置相关。在映射的任一侧上的属性可按需要简单地通过使用适合的令牌在任何片段上下文中指定、读取和写入。

为说明物理/逻辑层920内的逻辑如何工作,将描述现实世界的实例。所述实例将使用通用输入/输出(gpio)modbustm装置来示出此装置可如何经由物理/逻辑层920一直来回映射数据架构装置属性和界面114的gui。所选择的gpio装置是datanabai8_r13(具有8个模拟输入和13个继电器输出的装置)。所述实例将尝试在此硬件装置上映射通用输入/输出(i/o)引脚中的一些,以便创建混合装置,所述混合装置表现得与专用恒温器硬件装置相同。为了进行此操作,gpio装置上的ain必须连接到热敏电阻以便测量温度,且两个继电器输出需要连接到空调和加热器单元的控件。用适合的映射片段,可创建与实际恒温器没有差别的混合装置。

首先,gpio装置的modbustm规范可转换成通过物理/逻辑层920使用的格式。在所描述的实例中,此格式是xml。然而,应理解,其它格式是可能的。modbustm定义根据8位和16位寄存器和一位逻辑“线圈”来定义装置。这些硬件寄存器具有特定的目的且可被包装。每一寄存器在装置内具有唯一地址。这是与在本文中的其它地方所论述的数据架构属性或内部注册表不同的表示数据的方式。在从装置规范创建的xml中对ai8_r13物理装置类型的定义可为如下:

装置属性顺序地列出在<properties>字段内。在此实例中,每一装置属性具有基于装置规范的<name>字段,匹配硬件的类型的<type>字段,以驱动器需要或理解的格式(例如,在此情况下为整数)指定属性地址的<address>字段,以及指定此装置属性是否需要被读取和写入或是否可被忽略的<used>字段。尤其地,装置属性类型包括大小设定的整数(例如,int8、int16、int32等),且还可包括至多二维的数组(例如,int16[8][5])。这简单地反映硬件,所述硬件必须得到匹配以便承担打包和解包工作,否则所述工作将必须通过低级驱动器代码执行。这意味着,因为必须在执行物理至逻辑和/或逻辑至物理映射时访问这些装置属性的映射片段是基于基础脚本语言,所以基础脚本语言应能够理解大小设定的整数,以及在装置属性内索引的数组(例如,“@@.input[3][4]”)。虽然先前尚未关于基础脚本语言描述此特征,但所述特征可为基础脚本语言和其变型中固有的,即使所述特征通常可仅在硬件考量所需要时在映射片段内使用。一般地,到这些装置属性从驱动器层164的另一侧输出时,已在物理/逻辑层920或驱动器层164中解析非标准数据类型大小的所有证据。

gpio装置映射到其上并从其映射的逻辑恒温器装置类型(lthermostat)的定义可为如下:

尤其地,逻辑恒温器装置类型的定义缺少非标准数据类型大小,且更接近在数据架构内的恒温器装置类型的规范,但在许多方面不同。

如所说明,lthermostat从祖先逻辑装置类型“ldevice”继承一些属性,即,“id”、“name”以及“type”属性,所述属性通过由驱动器层164实施的映射来桥接到对应的数据架构装置类型“thermostat”的间距,所述“thermostat”本身可如下定义:

如lthermostat一样,公共装置类型的恒温器从祖先装置类型“pubdevice”继承基础属性。如在本文中的其它地方所描述,驱动器层164将ldev中的属性双向地映射到公共装置类型中的对应的属性。因为ldev定义在向通用驱动器抽象层910注册的所有驱动器上共用,所以ldev属性往往为在所有不同驱动器上所需的基础属性的集合,以便经由驱动器层164进行连接。因此,从pdev到ldev到公共装置的过程是逐渐简化和抽象成新手用户应容易理解的形式中的一个过程。

向通用驱动器抽象层910注册的所有驱动器166可共用ldev类型。因此,对于在“通用”条件下的所有驱动器,在驱动器层164中可仅存在一个条目。这意味着,所有驱动器166将相同地从ldev层向上操作,而没有对低级驱动器代码来进一步考虑除pdev定义外的任何事情的任何需要,所述pdev定义本身可与驱动器的代码以及寻址和命令模式紧密相关。

作为参考,在lthermostat装置类型中出现的属性的一些实例驱动器层164定义如下:

一旦已指定所有装置类型定义,就创建pdev和ldev的实际实例。这些可经由xml如下定义:

如所说明,pdev定义以适合于传输的格式指定装置地址,并指定装置类型。此信息用于创建装置,并经由modbustm驱动器166d开始与装置通信。装置的属性在mb_ai8_r13装置类型中定义,且<address>、<access>以及<type>字段指令驱动器166d如何和何时读取和写入那些装置属性。已从物理装置的硬件读取属性值,物理/逻辑层920可接收呈在pdev中指定的格式(例如,int16[8])的所提取值,按需要对所述值解包,并将所述值写入到内部驱动器pdev注册表值。然而,因为pdev未经由驱动器层164连接,所以这些属性值都对系统的其余部分不可见(即,在物理/逻辑层920的另一侧上)。

为使这些属性值可见,可在适合时将所述属性值移动到在“mbblahblahxxx01ch1”中定义的ldev中。ldev装置可从给定ldev规范直接地创建。所述ldev装置的所有属性类型都是已知的,且可通过系统的其余部分经由驱动器层164写入到ldev中。然而,在另一方向上,另外的逻辑可用于使这些属性成为可写入到对应的pdev的形式。

这些逻辑位都在pdev和ldev的<mappings>字段中指定。<mappings>字段可包含任何数目的个别<mapping>条目,所述<mapping>条目每个指定待运行的驱动器映射片段,用于映射的目标装置(源装置通过上下文暗指),将在驱动器映射片段运行时交给所述驱动器映射片段的任何参数(如果需要),以及源属性的列表,所述源属性中的任何属性在其在隐含的写入方向上发生改变时,将触发待运行的指定驱动器映射片段。对于ldev规范,隐含的写入方向是“ktophysical,”且目标装置通过定义为父pdev。对于某一pdev,可存在多个子ldev装置。因此,虽然所述方向始终是“ktological,”但目标装置可随每一映射改变。这允许通过专用映射片段集合来处理映射逻辑的完整集合,所述映射片段中的每一个聚焦于特定的改变的属性。这可尤其适用于一般化装置处理,例如,在zwavetm的情况下,其中属性被发现且可基于动态发现的命令类别来独立地处理,所述装置声称能够支持所述命令类别。

所引用的映射片段“tothermostat_ai8_r13”的定义可如下在列表18中:

因为混合恒温器从基本上“哑”gpio信号产生,所以此片段可表示最坏情况,只要关注的片段复杂性。大部分映射片段可仅为几行长。如所说明,在列表18中用xml表示的片段的代码包括两个可选地参数化的脚本定义。这两个脚本定义中的每一个用全包含的基础脚本语言的子集写入(例如,没有基础脚本语言的实时特征)。

在实施方案中,物理/逻辑层920和驱动器层164中的片段必须一直运行到结束,而不会变得在无限循环中悬挂或执行其它长度的操作,因为这些片段延迟对与同一驱动器相关联的其它装置的处理。如果在片段的调用之间需要持续的状态,那么所述持续的状态可通过将状态值存储到所涉及的装置的可见或隐藏的属性(例如,隐藏属性通过列表18的所说明片段中的前导下划线字符“_”指示)中来实施。例如,列表18中的恒温器逻辑相当广泛地进行此操作。尤其地,列表18中的片段还使用基础脚本语言的扩展数组句法(例如,“@@.relay[coolrelay]=off”),以及其从装置中的映射规范传递将用于脚本中的参数的能力。

使装置与装置类型相关联并填写必要的映射可略复杂。因此,在实施方案中,通过物理/逻辑层920提供的抽象提供模板(例如,在xml中指定),所述模板可基于物理装置类型来选择。这些模板可使创建pdev、ldev以及用于新近添加的装置的映射片段的过程自动化。例如,如果用户经由zwave驱动器将新硬件恒温器装置连接到网关120,那么下方的模板可自动地提供(例如,在用户界面中显示):

如所说明,模板将pdev和ldev以及相关联的映射(其可在本文中统称为“处理树”)的定义打包在一起。特定的装置使用到处理树中的装置索引来引用。当使用模板实例化装置时,索引值“0”在其通过在运行时间处赋值的实际的pdev引用使用时被替换。索引值“1”和向上表示已创建的ldev装置,且在实例化期间被类似地替换。

现将根据实施方案通过实例描述驱动器之间的差异以及处理那些差异的方式。zwavetm硬件恒温器的pdev类型的定义在下方说明:

给定zwave的command_class/command架构和以下事实:在zwavetm的情况下,装置公布其支持的类别和版本,则此所说明的pdev类型定义可通过在连接所述装置(例如,到网关120)时查询装置来自动地产生。这可通过解析zwavetmxml规范以提取任何给定命令类别版本的所有可读取和可写入属性来完成。这些提取的属性随后可被转换成属性名称和相关联的数据类型,以便在连接过程期间以完全自动化的方式产生以上装置类型。在zwavetm的情况下,属性地址是十六进制序列,所述十六进制序列对应于命令类别、版本、命令以及需要的其它属性/值用以从基于zwave的硬件“get”属性的路径,如在zwavetm规范中详述。zwavetm驱动器166b能够解译这些路径,以便自动地构造每一属性的get和set命令中的全部。这意味着,zwavetm驱动器166b可在不修改的情况下处理任何新装置和装置的较旧版本。

尤其地,此自动产生的pdev类型使用子结构属性或从zwavetm规范产生的子结构属性的数组。这些子结构属性在以上说明中以“.”字符开始。在实施方案中,基础脚本语言不仅能够处理基本数组,而且能够处理那些数组内的子结构属性。然而,基础脚本语言的此特征可极少地用于需要此特征的硬件传输的映射片段外。

尤其地,<access>字段不仅指定属性是否是可读取的和/或可写入的,而且可包含轮询优先级(即,必须多么频繁地轮询属性),所述轮询优先级可试探性地从zwavetm规范提取,其中优先级“0”指示“在重启后读取一次,”优先级“1”指示最大轮询速率(例如,轮询之间的125ms间隔),优先级“2”指示最大轮询速率的一半,优先级“3”指示最大轮询速率的四分之一,等等,例如,至可设定为分钟、小时、天或更长的轮询速率。随后,这些速率可在必要时在按装置的基础上动态地更改。

除所说明的zwavetm驱动器166b外的驱动器可不同地解译<address>字段。例如,phidgettm驱动器166c可解译<address>字段以作为phidgettm库函数的名称,必须调用所述函数以便获得对应的属性。应理解,对<address>字段的更加独特的解译类似地通过物理/逻辑层920支持。

6.13.物理/逻辑api

在实施方案中,驱动器166的实施通过将初始化程序函数传递到物理/逻辑层920的api的rg_registerdriver()函数来向通用驱动器抽象层910注册。从zwave驱动器166b获取的典型的初始化程序函数的实例在下方说明:

此函数在zwave驱动器166b被指定为活动的时被调用。否则,注册是潜在的。对此初始化程序函数的调用的结果是在本文中的其它地方论述的通用驱动器线程的创建,连同通用驱动器线程需要的各种参数和另外的标准回调函数的设定。这些驱动器回调中的大部分仅解析至对通过物理/逻辑层920提供的抽象逻辑的标准调用。因此,可省略注册,使得使用默认值,但此处包含注册以使在调试器中读取堆栈爬行的能力变得容易。例如,以上的zw_zwavelowlevelcallback()函数由单行组成:

ret=pl_standardlowlevelcallback(drivername,aparser,adevref,rawdevname,adevproperty,acommand,atype,avalue,globalcontext,options,status,flags);

类似地,zw_zwavepollfn()函数也由用适合的参数对pl_standardpollinglogic()函数的单行调用组成。zw_initzwavefn()和zw_termszwavefn()的可选注册在新近创建的通用驱动器线程内处理专门化的初始化和终止活动。所有其它注册的函数在以上代码中充分地描述。

在实施方案中,物理/逻辑层920提供对以下另外的功能性中的一个或多个的访问:

●用以处理传输通信的标准抢占式工作者线程的创建;

●用于经由专门的注册表对构成驱动器的pdev和ldev的属性的简化访问的api;

●基于如在xml装置规范中定义的装置树的迭代器,所述装置规范与在驱动器属性注册表中的那些装置规范相反;

●用以在对应的属性注册表值更改时运行需要被运行的映射片段的逻辑。在实施方案中,映射片段直接地在解译性的基础语言解析器内运行,而非在虚拟机内运行。然而,如果执行原因指定使用虚拟机来运行经编译的映射片段,那么替代于基础语言解析器或除基础语言解析器外,还可使用虚拟机。

●用以经由驱动器层164将任何属性传递到数据架构和从数据架构传递任何属性的逻辑;

●用以处理驱动器166的控制台界面的逻辑;

●api函数pl_converttological()和pl_converttophysical(),所述函数处理通过物理/逻辑层920的抽象的所有数据流;

●用以处理驱动器层164的需要的内置基础语言函数;

●api函数,所述函数用以经由抢占式工作者线程将来自物理装置的属性改变打包、入队以及出队到通用驱动器线程内的注册表中;

●api函数,所述函数用以将来自通用驱动器线程内的注册表的属性改变打包、入队以及出队到抢占式工作者线程中;

●供在抢占式驱动器代码内使用的抽象互斥api函数;和/或

●驱动器166常常需要的其它效用函数。

根据实施方案,在下方说明物理/逻辑层920的api的pl_standardworkerthread()函数:

在实施方案中,地址作为参数被传递到以上函数的另外的函数实际上形成标准方式,所有驱动器166以所述方式向物理/逻辑层920注册所述驱动器的自定义代码。这些逻辑函数(grabdevstate、recvnewvals、sendnewvals)利用通过物理/逻辑层920提供的另外的api函数,结合驱动器特定的传输代码来处理实施轮询和事件驱动的行为两者所需的一切事物。这些逻辑函数可趋向于在驱动器166上看起来类似,仅在经由基本驱动器传输层与物理装置通信所需的内容的细节上不同。除这些逻辑函数外,在遍历物理/逻辑层920时所涉及的所有其它逻辑,通过调用适合的映射片段,可通过物理/逻辑层920的抽象透明地处理。

6.14.开发控制台

在实施方案中,可提供到装置管理器160(和/或其它部件,例如脚本执行环境150)的直接连接以供开发人员、增值经销商和/或用以详细地调试和/或配置每一网关120的技术支持使用。此直接连接可通过控制台界面实施,所述控制台界面使得用户能够输入直接指令(例如,基于文本的命令)且使得能够向用户显示那些命令的结果(例如,基于文本的输出)。

在实施方案中,控制台界面可通过用户命令在传送到整个装置管理器160(和脚本执行环境150)与传送到特定驱动器166之间切换,所述特定驱动器实施一系列驱动器特定的命令和访问在驱动器层164下方的架构的功能。此双重访问允许在真实的硬件发生故障或其它问题的情况下较容易调试。

在实施方案中,将“help”键入到控制台中将产生可用控制台命令的以下列表:

前几个命令涉及控制编辑、添加、重命名以及删除脚本。高级开发人员可完全无需脚本gui并直接用基础脚本语言开发脚本,由此能够访问不可通过脚本gui表达的特征。

命令的下一集合提供检查并修改配置和调试选项和设置的能力。存在这些调试和配置功能的扩展集合,所述调试和配置功能适用于脚本执行环境150、装置管理器160以及驱动器166。

命令的下一集合允许公共装置属性(与驱动器特定的私有属性相反)、驱动器层164的片段、全局参数等的显示和更改。

“memory”命令显示所有存储器分配和使用的最新列表。

“dump”命令显示所有永久性数据(即,其值在重启或断电过程上永久的数据,例如存储在非易失性存储器中)的状态。一般来说,所有重要的值和状态保持为永久性数据。因此,发出此命令可提供所有重要状态的快照。

“flush”命令可用于从非活动驱动器的所有注册表清除状态。

“version”命令打印当前软件版本的细节。

“quit”命令终止控制台应用。

“+”命令重复所输入的先前命令。

“driver”命令允许用户切换以与在来自“driver”命令的输出中列出的活动驱动器中的任何驱动器通信。例如,下方的序列将控制台的注意点切换到虚拟驱动器166a,且随后显示可用于直接与虚拟驱动器166a通信的命令套系。如所说明,控制台提示改变以反映驱动器名称,所述驱动器名称是控制台的当前关注点:

因为虚拟驱动器166a未层堆在物理传输的顶部并不使用物理/逻辑层920,所以所述虚拟驱动器的命令集是通过物理/逻辑层920的抽象针对其它驱动器自动地提供的那些命令的句法兼容子集。例如,如果已选择phidget驱动器166c(“phidget_usb”)而非虚拟驱动器166a,那么以下可用命令将被示出:

主要地通过物理/逻辑层920的抽象提供的此驱动器命令集主要地在所有驱动器166上相同,除了虚拟驱动器166a。驱动器166可向控制台(和帮助菜单)在其相应的初始化程序函数内注册另外的驱动器特定的命令。

“device”命令显示通过“dref”识别的pdev或ldev的所有已知属性。“device”命令还可用于启用或停用给定装置。停用的装置继续存在,但不从任何物理装置的硬件读取或写入值且不触发任何映射片段。暂时性停用装置可用于隔离故障的原因。

“set”命令从控制台直接地设定ldev或pdev属性。如果所述改变触发映射片段,那么物理/逻辑层920将运行所触发的映射片段,且可引起映射的另一侧上的改变。再次地,此直接地在驱动器中设定装置属性的能力可用于开发和调试情况。

“show”命令显示任何驱动器“部件”的规范(例如,在xml中)。驱动器部件可为例如ldev、pdev、装置类型、映射片段或模板。所有这些不同部件类型的内容的实例已在本文中的其它地方提供。

“add”命令允许用户定义新部件且随后将其内容输入到控制台中(例如,通过将部件定义键入或复制-粘贴到控制台中)。输入被写入到永久性存储装置且可用于随后使用。“add”命令可针对不同的部件类型实施某些内部命名约定。低级“add”命令将仅在手动构造处理树时使用。新部件定义在输入时被解析,以便确保所述新部件定义在句法上正确。未能正确地解析的任何部件定义将不被写入到永久性存储装置。

“networkadd”命令可用于添加新装置。“networkadd”命令并入有另外的行为,包含自动地检测每一装置类型并使用与检测到的装置类型相关联的模板来创建整个处理树的能力。

“remove”命令处理给定驱动器部件,和对在任何注册表和永久性存储装置中的所移除驱动器部件的所有引用。装置的处理可暗指取决于所涉及的驱动器的另外的清除,且因此,所述装置的处理通过使用“networkremove”命令来更好地处理以避免与硬件状态不一致。

“replace”命令允许用户用新定义替换部件定义(例如,通过将新部件定义键入或复制-粘贴到控制台中),且因此,允许用户编辑现有部件定义。同样,控制台仅在新部件定义正确地解析时,用新部件定义替换旧部件定义。

“rename”命令允许用户在任何处理树或注册表内对部件永久地命名以及对部件的所有引用。

“pdevs”命令列出与选定驱动器相关联的所有pdev的基础细节。

“ldevs”命令列出与选定驱动器相关联的所有ldev的基础细节。

“snippets”命令列出与选定驱动器相关联的所有驱动器映射片段的基础细节。通配符(例如,“*”)可用于检查所有片段而不管选定驱动器。

“ldevtypes”命令列出所有已知的逻辑装置类型。因为ldev类型在所有驱动器上共用,所以此列表与选定驱动器无关。

“pdevtypes”命令列出在所有驱动器上的所有已知的物理装置类型。

“templates”命令列出在所有驱动器上的所有已知驱动器模板。

“network”命令提供对选定驱动器的传输“network”的基础管理。此管理主要地包括用于硬件装置的添加和移除的标准化过程,且通过物理/逻辑层920的抽象提供。不同的传输层具有关于感测装置何时已连接或断开的不同功能。因此,为了在所有驱动器上保持行为标准(例如,以使用户的学习曲线变容易),全部的“networkadd”和“networkremove”过程应通过自定义函数的注册来配置,例如网络响应器函数,通过在zwave驱动器166b的实例初始化程序函数中的zw_consnwrkresponderfn()函数表示。网络响应器函数可在控制台线程内调用,并允许逻辑控制网络管理的过程,以便避免在添加或移除操作失败时混淆的可能性。zw_consnwrkresponderfn()的实例代码可为如下:

如在以上实例中所说明,网络响应器函数适当地对逻辑动作中的每一个作出响应,要求所述网络响应器函数通过物理/逻辑层920的抽象逻辑来执行所述逻辑动作。尤其地,api的du_forwardconsolecmd()函数用于将命令从协作控制台线程(例如,所述协作控制台线程不能直接地访问物理装置的硬件)传递到抢占式工作者线程(例如,所述抢占式工作线程可直接地访问物理装置的硬件)和从所述抢占式工作者线程传递命令。除zwave驱动器166b外,驱动器的网络响应器函数可以类似方式实施。

7.通信层

在实施方案中,通信层140处理与网关120中的控制器130的tcp通信,或在其它配置中,处理直接地与平台110(例如,远程云服务)的tcp通信。消息可在脚本执行环境150内在单独的抢占式“工作者”线程中接收和发送。所有消息可完全地由用数据架构的数据格式编码的文本包组成。所有类型的数据架构命令简单地为用数据架构的数据格式(例如,json)编码的包,包含实施命令和/或其它重要数据的特定元素。

在实施方案中,在脚本执行环境150中,“接收”工作者接收到脚本执行环境150的消息(例如,来自平台110和/或控制器130),并在接收队列中将所述消息排队,同时主过程线程从接收队列拉出排队的消息并处理所述消息。类似地,在脚本执行环境150中,主过程线程用数据架构的数据格式对来自脚本执行环境150的消息(例如,到平台110和/或控制器130)编码,并在发送队列中将经编码的消息排队,同时“发送”工作者从发送队列拉出排队的消息并经由tcp将所述消息发送到既定目的地。

在实施方案中,与适合的目的地(例如,平台110和/或控制器130)建立通信所必需的信息被传递到通信层140的初始化例程。此信息可包括例如ip地址、端口、用户名和/或密码或密钥。一旦与目的地的特定实例的通信已建立,到所述目的地的所有随后的通信可是与所述特定实例。数据架构是这样,使得如果数据值通过网关120上的脚本执行环境150中的执行脚本改变,那么此改变正常地被发送到控制器130以作为“change”命令,且随后自动地转发到平台110。“change”命令可从平台110另外转发(例如)到脚本gui、到其它网关120、到订阅已被改变的数据的其它过程等。一个此过程是装置管理器160在相同的网关120上运行。

图8a说明根据实施方案的基础架构的独立变型,其中脚本执行环境(包括脚本管理器210和vm230)和装置管理器160执行为不同的过程,有可能在不同机器上。例如,脚本执行环境150可在云中(例如,在平台110上,而非在网关120上)执行,而装置管理器160可在某一过程中在网关120上执行。在此情况下,一个脚本执行环境150可用于控制多个网关120上的多个装置管理器160。此外,脚本执行环境150与装置管理器160之间的消息将经由网络(例如因特网)在平台110与网关120之间传递。替代地,脚本执行环境150和装置管理器160可在不同的过程中在同一网关120上执行。在此情况下,脚本执行环境150与装置管理器160之间的消息不直接在这两者之间传递,而是通过通信层140和/或控制器130转发。从脚本执行环境150到通信层140到控制器130或平台110的通信路径p1,以及从控制器130或平台110到通信层140到数据架构插件式驱动器810到装置管理器160的通信路径p2,是在基础架构的独立变型中用于脚本执行环境150与装置管理器160之间的通信的通信路径的特性。

如上文所提及,脚本执行环境150和装置管理器160的独立的变型可在网关120外运行(例如,在云中)。脚本执行环境150还可运行用于其它机器架构(例如,pc、服务器等)而无需修改。脚本执行环境150的独立的基于云的变型可用于架构节点,所述节点对大量网关120具有权力并运行跨越连接到许多不同网关120的装置的脚本,所述不同网关可能具有较宽地理分布。多个脚本执行环境150可直接地在平台110内或经由平台110通信。例如,第一网关120上的第一脚本执行环境150可通过经由第一网关上的通信层140将消息传递到平台110而与第二网关120上的第二脚本执行环境150通信,所述平台110通过第二网关上的通信层140将消息转发到第二脚本执行环境150。然而,绕过控制器130的此类通信一般仅适用于测试或适用于在脚本执行环境150控制的网关120外运行的脚本执行环境150。对于在网关120内执行的脚本执行环境150,通信将是正常地与所述网关120的控制器130。

然而,在实施方案中,网关120的正常配置将作为单一统一过程(但可能具有多个线程)执行脚本执行环境150和装置管理器160。根据实施方案,此配置在图8b中说明。尤其地,统一的脚本执行环境150和装置管理器160对应于图7中的统一的装置管理器和脚本管理器线程715。在此配置中,通过装置管理器160管理的装置的属性的任何改变通过内部api从vm230直接传递到装置管理器160。有利地,此方法可减少脚本动作与实际的外部硬件的对应的改变之间的时延,且反之亦然。因为装置管理器160将还告知本地控制器130任何装置属性何时发生改变(例如,经由从装置管理器160到通信层140到控制器130的路径),所以系统的其余部分将与在所述事实后的改变保持同步,如与在独立的变型的实施方案中请求改变相反。因此,装置属性值将用真实的硬件状态而始终为最新的(有可能具有由通信信道导致的略微的时延)。

8.图形用户界面(gui)

在实施方案中,平台110提供界面114,所述界面包括web应用,所述应用向用户提供针对在工业控制和家庭自动化领域以及任何其它领域中的自动化装置来读取、控制以及创建脚本的能力。此web应用可合并数据架构、所公开的脚本语言、图形用户界面以及装置管理器。

在实施方案中,web应用通过暴露的应用设计接口(api)提供对数据架构的web访问。api可被广泛范围的客户端应用使用,所述客户端应用包含例如,其它web应用(例如,设计用于特定的应用)、移动装置、第三方机器到机器框架等。

在实施方案中,web应用提供gui,所述gui使得用户能够创建、编辑脚本并将脚本部署到一个或多个网关120。web应用可使得熟练的用户能够以粒度细节控制网关120,同时仍为新手用户提供直观的用户界面。

在实施方案中,web应用在单个应用内支持多个装置控制标准,同步跨越多个客户端的属性,即使在缺乏因特网连接性的情况下也提供功能系统,针对多个领域(例如,家庭、商业以及工业领域)创建可行产品,并允许用户控制大量的网关120和/或自动化装置。

9.实例用例

现将描述一些实例用例。应理解,这些用例仅提供用于说明控制脚本的少量非限制性实际应用。

9.1.餐车制冷温度监视

在此实例用例中,用户运行餐车链。支持每一餐车的食品冷却器和冷冻机对每一个别的餐车和作为整体的链的成功至关重要,所述食品冷却器和冷冻机对联邦和州食品保障条例的遵守亦是如此。食品的恰当的制冷或冷冻影响其口感、外观、营养含量以及安全性。因此,州和联邦食品和药品管理局(fda)要求,密切监视所有商用制冷单元的温度。如果制冷单元的温度在长于特定时间的时间上高于或低于建议的范围,那么存储在受影响的制冷单元中的食品可能不能使用。

不幸的是,几乎所有商用制冷单元都将恒温器放置成靠近所述单元的门。为确保单元的门的正常短时打开和关闭不导致不正确的温度读数,辅助温度监视器应安装在远离单元的门处。如果在单元的门打开时出现温度上升,那么在门已关闭5至10分钟后,单元中的温度应返回到正常操作范围内。如果温度未返回到正常操作范围内,那么每一州fda已建立协议以用于确定所述单元中的食品是否可使用或出售。

为证实对这些条例的遵守,每一州fda公布并审查在正常操作范围外的温度范围的定期报告。在此实例中,用户已针对以下情况建立其自己的策略:她在单元的温度在某一时间段上在正常操作范围外时想要雇员怎么做,以及那些雇员应对储存在此单元中的食品做什么。

商用大型制冷机单元的操作的平均温度范围一般在36℉与45℉之间。如果食品储存在低于36℉的温度下,那么存在冷冻不应被冷冻的食品(例如,牛奶和其它乳制品)的风险,且如果食品储存在高于45℉的温度下,那么存在食品将变质的风险。美国fda要求制冷产品必须保持在41℉下或更低。但食品在未被冷冻时越冷,食品将持续的时间越长,从而使38℉为商用制冷的理想温度。

商用大型冷冻机单元的操作的平均温度范围一般在5℉与-10℉之间。如果食品储存在低于-10℉的温度下,那么存在冷冻机冻伤的风险,且如果食品储存在高于5℉的温度下,那么食品可能不能恰当地冷冻和/或可能不能保持不变质。

为监视并报告制冷温度,确保食品新鲜度,且遵守州和联邦fda要求和审查,用户在此实例中希望:

●将温度传感器安装成远离每一餐车的大型制冷机和大型冷冻机的门,以确保最准确的读数并使门的打开和关闭的影响最小化;

●建立对适当的制冷机和冷冻机温度的监视、报告以及报警;以及

●建立集成的制冷机和冷冻机门监视以帮助确定对超出范围的温度的报警或警告是否可能已由单元的门被打开太长时间或由单元的可能故障造成。

用户可使用所公开的基础架构通过以下操作来实施这些希望:在每一餐车中,安装(a)具有蜂窝数据连接的网关(例如,网关120),(b)在大型制冷机单元中远离单元的门并连接到网关的温度传感器,(c)在大型冷冻机单元中远离单元的门并连接到网关的温度传感器,(d)连接到网关的大型制冷机门传感器,(e)连接到网关的大型冷冻机门传感器,以及(f)连接到网关的可听声装置。

接着,用户可经由平台110的界面114的gui通过以下操作来配置所述安装:(a)给每一安装的网关命名(例如,经由界面114的管理gui),其中每一网关表示一个餐车;(b)针对大型制冷机单元创建登录脚本和报警脚本(例如,经由界面114的脚本gui);以及(c)针对大型冷冻机单元创建登录脚本和报警脚本(例如,经由界面114的脚本gui)。

制冷机单元和冷冻机单元中的每一个的登录脚本将定期的温度测量结果从相应的单元中的温度传感器发送到平台110(经由蜂窝数据连接)。登录时段可根据用户所需要和脚本gui中所指定而以多种方式设定(例如,每小时地、每天地、每天在特定时间处、每六个小时等)。另外,通过每一登录脚本定期地发送的温度测量结果可以一种或多种数据格式(例如,microsoftexceltm等电子表格格式、逗号分隔的值(csv)、便携式文件格式(pdf)等)存储在平台110处并通过用户下载。

制冷机单元和冷冻机单元中的每一个的报警脚本在来自相应的单元中的温度传感器的温度测量结果在第二时间段上在正常操作范围外时,在第一时间段上经由所安装的可听声装置触发可听警报,并将日志条目发送到平台110(经由蜂窝数据连接),所述日志条目包括温度测量结果超出正常操作范围的日期和时间,在从检测到温度测量结果在正常操作范围外的时刻直到温度测量结果返回到正常操作范围的每一设定时间间隔中来自相应的温度传感器的温度测量结果,和/或温度测量结果返回到正常操作范围的日期和时间。用于制冷机单元的脚本可将正常操作范围定义为在35℉与41℉之间,而用于冷冻机单元的脚本可将正常操作范围定义为在-10℉与5℉之间。第一时间段可定义为三十秒,第二时间段可定义为五分钟,且所设定的时间间隔可定义为一分钟。当然,用户可将这些变量的值设定为她所期望的任何值(例如,经由界面114的脚本gui)。另外,两个报警脚本可在温度测量结果在第一时间段到期之前返回到正常操作范围时断开可听警报。此外,报警日志条目可以一种或多种数据格式存储在平台110处并通过用户下载。

作为可听报警的替代方案或除可听报警外,制冷机单元和冷冻机单元中的每一个的报警脚本还可在满足报警条件时发送警告消息。例如,每当来自相应单元中的温度传感器的温度测量结果在某一时间段(可通过用户配置)上在正常操作范围外时,报警脚本可通过平台110或直接地经由蜂窝数据连接发射警告消息,以及如上文所描述将日志条目发送到平台110。例如,警告消息可为文本消息(例如,短消息服务(sms)消息)或电子邮件消息,所述消息包括发送警告消息的网关的名称(所述网关可以其安装在其中的餐车命名,例如“truck1”),报警的日期和时间,和/或与报警相关的一个或多个温度测量结果。类似地,当温度测量结果返回到正常操作范围时,每一报警脚本还可发送报警解除消息,以指示报警条件已被清除。在每一情况下,当经由脚本gui创建报警脚本时,用户可指定警告消息的一个或多个接收方(例如,通过从联系人数据库选择联系记录,输入手机号码和/或电子邮件地址等)。

在针对制冷机和冷冻机单元两者创建登录和报警脚本后,用户可与平台110的界面114的gui交互以将四个脚本下载到每一餐车中安装的每一网关。

在此实例中,警告消息将可能的条例违反告知用户,使得用户可证实并利用适当的操作步骤用文件证明遵守条例。另外,日志条目连同用户用适当的操作步骤对遵守条例的文件可用于遵守州fda审查。

9.2.餐车制冷门监视

此用例实例将利用与上文相同的用户。由于通过餐车准备并供应食品所需的近距离和快节奏,烹饪人员通常使餐车的大型制冷机或冷冻机单元的门打开。如上文所论述,这可造成食品安全的问题并引起健康破坏。因此,用户已建立食品处理、准备、烹饪以及供应标准并训练所有她的雇员。为监视她的雇员的表现,用户随机地访问她的餐车以品尝食品并观察她的雇员。然而,雇员在用户不在时可能懒于遵守所建立的标准。因此,用户希望不显眼地监视每一餐车上的制冷机和冷冻机单元的门。

用户可使用所公开的基础架构通过以下操作实施这些希望:在每一餐车中,安装(a)具有蜂窝数据连接的网关(例如,网关120),(b)连接到网关的大型制冷机门传感器,(c)连接到网关的大型冷冻机门传感器,以及(d)连接到网关的可听声装置。

接着,用户可经由平台110的界面114的gui通过以下操作来配置所述安装:(a)给每一安装的网关命名(例如,经由界面114的管理gui),其中每一网关表示一个餐车;(b)针对大型制冷机单元创建登录脚本和报警脚本(例如,经由界面114的脚本gui);以及(c)针对大型冷冻机单元创建登录脚本和报警脚本(例如,经由界面114的脚本gui)。

制冷机单元和冷冻机单元中的每一个的登录脚本将日志条目发送到平台110(经由蜂窝数据连接),所述日志条目每个包括通过相应的门传感器检测到的在相应单元的门的打开与关闭状态之间的每一次转变的日期、时间以及转变(例如,打开或关闭)。日志条目可在其创建时(例如,在门打开或关闭时)被发送。这些日志条目可以一种或多种数据格式存储在平台110处并通过用户下载。

制冷机单元和冷冻机单元中的每一个报警脚本在门传感器检测到相应单元的门在第二时间段上打开时,经由所安装的可听声装置在第一时间段上触发可听警报,并将日志条目发送到平台110(经由蜂窝数据连接),所述日志条目包括门打开的日期、时间和/或持续时间。第一时间段可定义为三十秒,且第二时间段可定义为两分钟。当然,用户可将这些变量的值设定为她所期望的任何值(例如,经由界面114的脚本gui)。另外,两个报警脚本可在门在第一时间段到期之前返回到关闭状态时断开可听警报。此外,报警日志条目可以一种或多种数据格式存储在平台110处并通过用户下载。

在针对制冷机和冷冻机单元两者创建登录和报警脚本后,用户可与平台110的界面114的gui交互以将四个脚本下载到每一餐车中安装的每一网关。

10.实例处理装置

图10是说明实例有线或无线系统1000的框图,所述有线或无线系统可结合本文中描述的各种实施方案一起使用。例如,系统1000可用作上文描述的机制、过程、方法或功能(例如,用以存储和/或执行所公开的逻辑和/或一个或多个软件模块中的任一个)中的一个或多个或结合其使用,且可表示平台110、网关120(例如,网关120的控制器130)和/或本文中描述的装置中的任一个的部件。系统1000可为服务器或任何常规的个人计算机,或能够进行有线或无线数据通信的任何其它处理器启用的装置。还可使用其它计算机系统和/或架构,如所属领域的技术人员将清楚。

系统1000优选地包含一个或多个处理器,例如处理器1010。可提供另外的处理器,例如用以管理输入/输出的辅助处理器,用以执行浮点算术运算的辅助处理器,具有适合于信号处理算法的快速执行的架构的专用微处理器(例如,数字信号处理器),从属于主处理系统的从属处理器(例如,后端处理器),用于双或多处理器系统的另外的微处理器或控制器,或协处理器。此类辅助处理器可为离散的处理器,或可与处理器1010集成。可与系统1000一起使用的处理器的实例包含但不限于处理器、处理器以及处理器,所有所述处理器可购自california的santaclara的intelcorporation。

处理器1010优选地连接到通信总线1005。通信总线1005可包含用于促进在存储装置与系统1000的其它外围部件之间的信息传递的数据信道。通信总线1005还可提供用于与处理器1010通信的信号集,包含数据总线、地址总线以及控制总线(未示出)。通信总线1005可包括任何标准或非标准总线架构,例如,遵守工业标准架构(isa)的总线架构,扩展工业标准架构(eisa),微信道架构(mca),外围部件互连(pci)本地总线,或通过电气电子工程师协会(ieee)公布的标准,包含ieee488通用接口总线(gpib)、ieee696/s-100及类似者。

系统1000优选地包含主存储器1015,且还可包含辅助存储器1020。主存储器1015提供用于在处理器1010上执行的程序的指令和数据的存储,例如上文描述的函数和/或模块中的一个或多个。应理解,存储在存储器中并通过处理器1010执行的程序可根据任何合适的语言来写入和/或编译,所述语言包含但不限于c/c++、java、javascript、perl、visualbasic、.net及类似者。主存储器1015通常为基于半导体的存储器,例如动态随机存取存储器(dram)和/或静态随机存取存储器(sram)。其它基于半导体的存储器类型包含例如同步动态随机存取存储器(sdram)、rambus动态随机存取存储器(rdram)、铁电体随机存取存储器(fram)及类似者,包含只读存储器(rom)。

辅助存储器1020可以可选地包含内部存储器1025和/或可移除介质1030。可移除介质1030以任何众所周知的方式读取和/或写入。可移除存储介质1030可为例如磁带驱动器、压缩光盘(cd)驱动器、数字通用光盘(dvd)驱动器、其它光学驱动器、闪存存储器驱动器等。

可移除存储介质1030是非暂时性计算机可读介质,所述介质在其上存储有计算机可执行代码(即,软件)和/或数据。存储在可移除存储介质1030上的计算机软件或数据被读取到系统1000中以用于通过处理器1010执行。

在替代实施方案中,辅助存储器1020可包含用于允许将计算机程序或其它数据或指令加载到系统1000中的其它类似构件。此类构件可包含例如外部存储介质1045和通信接口1040,所述通信接口允许将软件和数据从外部存储介质1045传递到系统1000。外部存储介质1045的实例可包含外部硬盘驱动器、外部光学驱动器、外部磁光驱动器等。辅助存储器1020的其它实例可包含基于半导体的存储器,例如可编程只读存储器(prom)、可擦除可编程只读存储器(eprom)、电可擦除只读存储器(eeprom)或闪存存储器(类似于eeprom的面向块的存储器)。

如以上所提及,系统1000可包含通信接口1040。通信接口1040允许在系统1000与外部装置(例如,打印机)、网络或其它信息源之间传递软件和数据。例如,计算机软件或可执行代码可经由通信接口1040从网络服务器传递到系统1000。通信接口1040的实例包含内置网络适配器、网络接口卡(nic)、个人计算机存储卡国际协会(pcmcia)网络卡、卡总线网络适配器、无线网络适配器、通用串行总线(usb)网络适配器、调制解调器、网络接口卡(nic)、无线数据卡、通信端口、红外接口、ieee1394火线或能够介接系统550与网络或另一计算装置的任何其它装置。通信接口1040优选地实施行业公布的协议标准,例如以太网ieee802标准、光纤信道、数字用户线路(dsl)、异步数字用户线路(adsl)、帧中继、异步传输模式(atm)、综合服务数字网(isdn)、个人通信服务(pcs)、传输控制协议/因特网协议(tcp/ip)、串行线路因特网协议/点到点协议(slip/ppp)等等,但还可实施自定义或非标准接口协议。

经由通信接口1040传递的软件和数据一般呈电通信信号1055的形式。这些信号1055可经由通信信道1050提供给通信接口1040。在实施方案中,通信信道1050可为有线或无线网络,或任何多种其它通信链路。通信信道1050携载信号1055且可使用多种有线或无线通信构件来实施,包含电线或线缆、光纤、常规的电话线、手机链路、无线数据通信链路、射频(“rf”)链路或红外链路等等。

计算机可执行的代码(即,计算机程序或软件)存储在主存储器1015和/或辅助存储器1020中。计算机程序还可经由通信接口1040接收,并存储在主存储器1015和/或辅助存储器1020中。此类计算机程序在执行时使得系统1000执行如本文中的其它地方所描述的所公开的实施方案的各种功能。

在此描述中,术语“计算机可读介质”用于指代用于将计算机可执行代码(例如,软件和计算机程序)提供到系统1000的任何非暂时性计算机可读存储介质。此介质的实例包含主存储器1015、辅助存储器1020(包含内部存储器1025、可移除介质1030以及外部存储介质1045)以及以通信方式与通信接口1040耦合的任何外围装置(包含网络信息服务器或其它网络装置)。这些非暂时性计算机可读介质是用于将可执行代码、编程指令以及软件提供到系统1000的构件。

在使用软件实施的实施方案中,软件可存储在计算机可读介质上,并借助可移除介质1030、i/o接口1035或通信接口1040而加载到系统1000中。在此实施方案中,软件以电通信信号1055的形式加载到系统1000中。软件在通过处理器1010执行时,优选地使得处理器1010执行本文中在其它地方描述的特征和功能。

在实施方案中,i/o接口1035在系统1000的一个或多个部件与一个或多个输入和/或输出装置之间提供接口。实例输入装置包含但不限于键盘、触摸屏或其它触敏装置、生物感测装置、计算机鼠标、轨迹球、基于笔的指向装置及类似者。输出装置的实例包含但不限于阴极射线管(crt)、等离子体显示器、发光二极管(led)显示器、液晶显示器(lcd)、打印机、真空荧光显示器(vfd)、表面传导电子发射显示器(sed)、场发射显示器(fed)及类似者。

系统1000还包含可选的无线通信部件,所述部件促进经由话音网络和/或数据网络的无线通信。无线通信部件包括天线系统1070、无线电系统1065以及基带系统1060。在系统1000中,射频(rf)信号在无线电系统1065的管理下经由空气通过天线系统1070发送和接收。

在一个实施方案中,天线系统1070可包括一个或多个天线和一个或多个多路复用器(未示出),所述多路复用器执行交换功能以为天线系统1070提供发送和接收信号路径。在接收路径中,接收到的rf信号可从多路复用器耦合到低噪声放大器(未示出),所述放大器放大接收到的rf信号并将放大后的信号发送到无线电系统1065。

在替代实施方案中,无线电系统1065可包括一个或多个无线电装置,所述无线电装置经配置以经由不同频率通信。在实施方案中,无线电系统1065可将解调器(未示出)和调制器(未示出)合并在一个集成电路(ic)中,解调器和调制器还可为单独的部件。在进入路径中,解调器除去rf载波信号,留下基带接收音频信号,所述基带接收音频信号从无线电系统1065发送到基带系统1060。

如果接收到的信号包含音频信息,随后基带系统1060对信号解码并将其转换成模拟信号。随后信号被放大且发送到扬声器。基带系统1060还从麦克风接收模拟音频信号。这些模拟音频信号通过基带系统1060转换成数字信号并编码。基带系统1060还对数字信号译码以用于传输,并产生基带发送音频信号,所述音频信号被路由到无线电系统1065的调制器部分。调制器混合基带发送音频信号与rf载波信号,从而产生rf发送信号,所述rf发送信号被路由到天线系统1070,且可经过功率放大器(未示出)。功率放大器放大rf发送信号并将其路由到天线系统1070,其中信号被交换到天线端口以用于传输。

基带系统1060还以通信方式与处理器1010耦合,所述处理器可为中央处理单元(cpu)。处理器1010访问数据存储区1015和1020。处理器1010优选地经配置以执行可存储在主存储器1015或辅助存储器1020中的指令(即,计算机程序或软件)。计算机程序还可从基带处理器1060接收,并存储在主存储器1010或辅助存储器1020中,或在接收后执行。此类计算机程序在执行时使得系统1000执行所公开的实施方案的各种功能。例如,数据存储区1015或1020可包含各种软件模块。

各种实施方案还可主要地使用例如专用集成电路(asic)或现场可编程门阵列(fpga)等部件在硬件中实施。相关领域的技术人员还将明白能够执行本文中描述的功能的硬件状态机的实施。各种实施方案还可使用硬件和软件的组合实施。

此外,所属领域的技术人员应了解,结合以上描述的图式和本文中公开的实施方案来描述的各种说明性逻辑块、模块、电路以及方法步骤通常可实施为电子硬件、计算机软件或两者的组合。为清楚地说明硬件和软件的此可互换性,各种说明性部件、块、模块、电路以及步骤已在上文大体上就其功能性而言来描述。此功能性是实施为硬件还是软件取决于施加于整体系统的特定应用和设计约束。技术人员可针对每一特定应用以不同的方式实施所描述的功能性,但此类实施决策不应被解释为造成偏离本发明的范围。另外,在模块、块、电路或步骤内的功能的分组是为了便于描述。在不脱离本发明的情况下,特定功能或步骤可从一个模块、块或电路移动到另一个。

此外,结合本文中所公开的实施方案描述的各种说明性逻辑块、模块、功能以及方法可用以下各项实施或执行:通用处理器、数字信号处理器(dsp)、asic、fpga或其它可编程逻辑装置、离散门或晶体管逻辑、离散硬件部件或其经设计以执行本文中描述的功能的任何组合。通用处理器可为微处理器,但在替代方案中,所述处理器可为任何处理器、控制器、微控制器或状态机。处理器还可实施为计算装置的组合,例如,dsp和微处理器的组合、多个微处理器、结合dsp内核的一个或多个微处理器或任何其它此类配置。

另外,结合本文中公开的实施方案描述的方法或算法的步骤可直接地用硬件、用于通过处理器执行的软件模块或用这两者的组合实施。软件模块可驻留在ram存储器、闪存存储器、rom存储器、eprom存储器、eeprom存储器、寄存器、硬盘、可移除盘、cd-rom或包含网络存储介质的任何其它形式的存储介质中。示例性存储介质可耦合到处理器,使得所述处理器可从存储介质读取信息,并将信息写入到存储介质。在替代方案中,存储介质可与处理器成一体。处理器和存储介质还可驻留在asic中。

本文中描述的软件部件中的任何软件部件可采用多种形式。例如,部件可为独立的软件包,或部件可为作为“工具”并入在大型软件产品中的软件包。所述软件包可从网络(例如,网站)下载以作为独立的产品或作为用于安装在现有软件应用中的插件包。所述软件包还可用作客户端-服务器软件应用、用作web启用的软件应用和/或用作移动应用。

提供以上对所公开的实施方案的描述以使得所属领域的任何技术人员能制作或使用本发明。所属领域的技术人员将容易地明白这些实施方案的各种修改,且在不脱离本发明的精神或范围的情况下,本文中描述的一般原理可应用于其它实施方案。因此,应理解,本文中呈现的描述和图式表示本发明的当前优选的实施方案,且因此表示被本发明广泛地涵盖的主题。还应理解,本发明的范围完全涵盖可对所属领域的技术人员变得明显的其它实施方案,且因此本发明的范围不受限制。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1