svghmi/svghmi.py
branchsvghmi
changeset 3270 38f7122ccbf9
parent 3269 5d174cdf4d98
child 3274 16066300b254
equal deleted inserted replaced
3269:5d174cdf4d98 3270:38f7122ccbf9
    45 
    45 
    46 hmi_tree_root = None
    46 hmi_tree_root = None
    47 
    47 
    48 on_hmitree_update = None
    48 on_hmitree_update = None
    49 
    49 
       
    50 maxConnectionsTotal = 0
       
    51 
    50 class SVGHMILibrary(POULibrary):
    52 class SVGHMILibrary(POULibrary):
    51     def GetLibraryPath(self):
    53     def GetLibraryPath(self):
    52          return paths.AbsNeighbourFile(__file__, "pous.xml")
    54          return paths.AbsNeighbourFile(__file__, "pous.xml")
    53 
    55 
    54     def Generate_C(self, buildpath, varlist, IECCFLAGS):
    56     def Generate_C(self, buildpath, varlist, IECCFLAGS):
    55         global hmi_tree_root, on_hmitree_update
    57         global hmi_tree_root, on_hmitree_update, maxConnectionsTotal
    56 
    58 
    57         """
    59         """
    58         PLC Instance Tree:
    60         PLC Instance Tree:
    59           prog0
    61           prog0
    60            +->v1 HMI_INT
    62            +->v1 HMI_INT
   194 
   196 
   195         # TODO check if programs need to be declared separately
   197         # TODO check if programs need to be declared separately
   196         # "programs_declarations": "\n".join(["extern %(type)s %(C_path)s;" %
   198         # "programs_declarations": "\n".join(["extern %(type)s %(C_path)s;" %
   197         #                                     p for p in self._ProgramList]),
   199         #                                     p for p in self._ProgramList]),
   198 
   200 
       
   201         for CTNChild in self.GetCTR().IterChildren():
       
   202             if isinstance(CTNChild, SVGHMI):
       
   203                 maxConnectionsTotal += CTNChild.GetParamsAttributes("SVGHMI.MaxConnections")["value"]
       
   204 
       
   205 
   199         # C code to observe/access HMI tree variables
   206         # C code to observe/access HMI tree variables
   200         svghmi_c_filepath = paths.AbsNeighbourFile(__file__, "svghmi.c")
   207         svghmi_c_filepath = paths.AbsNeighbourFile(__file__, "svghmi.c")
   201         svghmi_c_file = open(svghmi_c_filepath, 'r')
   208         svghmi_c_file = open(svghmi_c_filepath, 'r')
   202         svghmi_c_code = svghmi_c_file.read()
   209         svghmi_c_code = svghmi_c_file.read()
   203         svghmi_c_file.close()
   210         svghmi_c_file.close()
   206             "extern_variables_declarations": "\n".join(extern_variables_declarations),
   213             "extern_variables_declarations": "\n".join(extern_variables_declarations),
   207             "buffer_size": buf_index,
   214             "buffer_size": buf_index,
   208             "item_count": item_count,
   215             "item_count": item_count,
   209             "var_access_code": targets.GetCode("var_access.c"),
   216             "var_access_code": targets.GetCode("var_access.c"),
   210             "PLC_ticktime": self.GetCTR().GetTicktime(),
   217             "PLC_ticktime": self.GetCTR().GetTicktime(),
   211             "hmi_hash_ints": ",".join(map(str,hmi_tree_root.hash()))
   218             "hmi_hash_ints": ",".join(map(str,hmi_tree_root.hash())),
       
   219             "max_connections": maxConnectionsTotal
   212             }
   220             }
   213 
   221 
   214         gen_svghmi_c_path = os.path.join(buildpath, "svghmi.c")
   222         gen_svghmi_c_path = os.path.join(buildpath, "svghmi.c")
   215         gen_svghmi_c = open(gen_svghmi_c_path, 'w')
   223         gen_svghmi_c = open(gen_svghmi_c_path, 'w')
   216         gen_svghmi_c.write(svghmi_c_code)
   224         gen_svghmi_c.write(svghmi_c_code)
   285           <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional" default="chromium {url}"/>
   293           <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional" default="chromium {url}"/>
   286           <xsd:attribute name="WatchdogInitial" type="xsd:integer" use="optional" default="30"/>
   294           <xsd:attribute name="WatchdogInitial" type="xsd:integer" use="optional" default="30"/>
   287           <xsd:attribute name="WatchdogInterval" type="xsd:integer" use="optional" default="5"/>
   295           <xsd:attribute name="WatchdogInterval" type="xsd:integer" use="optional" default="5"/>
   288           <xsd:attribute name="Port" type="xsd:integer" use="optional" default="8008"/>
   296           <xsd:attribute name="Port" type="xsd:integer" use="optional" default="8008"/>
   289           <xsd:attribute name="Interface" type="xsd:string" use="optional" default="localhost"/>
   297           <xsd:attribute name="Interface" type="xsd:string" use="optional" default="localhost"/>
   290           <xsd:attribute name="Path" type="xsd:string" use="optional" default=""/>
   298           <xsd:attribute name="Path" type="xsd:string" use="optional" default="{name}"/>
       
   299           <xsd:attribute name="MaxConnections" type="xsd:integer" use="optional" default="16"/>
   291         </xsd:complexType>
   300         </xsd:complexType>
   292       </xsd:element>
   301       </xsd:element>
   293     </xsd:schema>
   302     </xsd:schema>
   294     """
   303     """
   295 
   304 
   560         runtimefile.write("""
   569         runtimefile.write("""
   561 # TODO : multiple watchdog (one for each svghmi instance)
   570 # TODO : multiple watchdog (one for each svghmi instance)
   562 def svghmi_{location}_watchdog_trigger():
   571 def svghmi_{location}_watchdog_trigger():
   563     {svghmi_cmds[Watchdog]}
   572     {svghmi_cmds[Watchdog]}
   564 
   573 
   565 svghmi_watchdog = None
   574 max_svghmi_sessions = {maxConnections_total}
   566 
   575 
   567 def _runtime_{location}_svghmi_start():
   576 def _runtime_{location}_svghmi_start():
   568     global svghmi_watchdog, svghmi_servers
   577     global svghmi_watchdog, svghmi_servers
   569 
   578 
   570     srv = svghmi_servers.get("{interface}:{port}", None)
   579     srv = svghmi_servers.get("{interface}:{port}", None)
   571     if srv is not None:
   580     if srv is not None:
   572         svghmi_root, svghmi_listener, path_list = srv 
   581         svghmi_root, svghmi_listener, path_list = srv
   573         if '{path}' in path_list:
   582         if '{path}' in path_list:
   574             raise Exception("SVGHMI {view_name}: path {path} already used on {interface}:{port}")
   583             raise Exception("SVGHMI {view_name}: path {path} already used on {interface}:{port}")
   575     else:
   584     else:
   576         svghmi_root = Resource()
   585         svghmi_root = Resource()
   577         svghmi_root.putChild("ws", WebSocketResource(HMIWebSocketServerFactory()))
   586         factory = HMIWebSocketServerFactory()
       
   587         factory.setProtocolOptions(maxConnections={maxConnections})
       
   588 
       
   589         svghmi_root.putChild("ws", WebSocketResource(factory))
   578 
   590 
   579         svghmi_listener = reactor.listenTCP({port}, Site(svghmi_root), interface='{interface}')
   591         svghmi_listener = reactor.listenTCP({port}, Site(svghmi_root), interface='{interface}')
   580         path_list = []
   592         path_list = []
   581         svghmi_servers["{interface}:{port}"] = (svghmi_root, svghmi_listener, path_list)
   593         svghmi_servers["{interface}:{port}"] = (svghmi_root, svghmi_listener, path_list)
   582 
   594 
   590     {svghmi_cmds[Start]}
   602     {svghmi_cmds[Start]}
   591 
   603 
   592     if {enable_watchdog}:
   604     if {enable_watchdog}:
   593         if svghmi_watchdog is None:
   605         if svghmi_watchdog is None:
   594             svghmi_watchdog = Watchdog(
   606             svghmi_watchdog = Watchdog(
   595                 {watchdog_initial}, 
   607                 {watchdog_initial},
   596                 {watchdog_interval}, 
   608                 {watchdog_interval},
   597                 svghmi_{location}_watchdog_trigger)
   609                 svghmi_{location}_watchdog_trigger)
   598         else:
   610         else:
   599             raise Exception("SVGHMI {view_name}: only one watchdog allowed")
   611             raise Exception("SVGHMI {view_name}: only one watchdog allowed")
   600 
   612 
   601 
   613 
   626                    interface = interface,
   638                    interface = interface,
   627                    path = path,
   639                    path = path,
   628                    enable_watchdog = enable_watchdog,
   640                    enable_watchdog = enable_watchdog,
   629                    watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"],
   641                    watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"],
   630                    watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
   642                    watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
       
   643                    maxConnections = self.GetParamsAttributes("SVGHMI.MaxConnections")["value"],
       
   644                    maxConnections_total = maxConnectionsTotal
   631                    ))
   645                    ))
   632 
   646 
   633         runtimefile.close()
   647         runtimefile.close()
   634 
   648 
   635         res += (("runtime_%s_svghmi.py" % location_str, open(runtimefile_path, "rb")),)
   649         res += (("runtime_%s_svghmi.py" % location_str, open(runtimefile_path, "rb")),)