svghmi/svghmi.py
branchsvghmi
changeset 3269 5d174cdf4d98
parent 3267 5f20f391ae31
child 3270 38f7122ccbf9
equal deleted inserted replaced
3268:d22782b9591f 3269:5d174cdf4d98
   277 class SVGHMI(object):
   277 class SVGHMI(object):
   278     XSD = """<?xml version="1.0" encoding="utf-8" ?>
   278     XSD = """<?xml version="1.0" encoding="utf-8" ?>
   279     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   279     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   280       <xsd:element name="SVGHMI">
   280       <xsd:element name="SVGHMI">
   281         <xsd:complexType>
   281         <xsd:complexType>
   282           <xsd:attribute name="OnStart" type="xsd:string" use="optional"/>
   282           <xsd:attribute name="OnStart" type="xsd:string" use="optional" default="chromium {url}"/>
   283           <xsd:attribute name="OnStop" type="xsd:string" use="optional"/>
   283           <xsd:attribute name="OnStop" type="xsd:string" use="optional" default="echo 'please close chromium window at {url}'"/>
   284           <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional"/>
   284           <xsd:attribute name="EnableWatchdog" type="xsd:boolean" use="optional" default="false"/>
   285           <xsd:attribute name="WatchdogInitial" type="xsd:integer" use="optional"/>
   285           <xsd:attribute name="OnWatchdog" type="xsd:string" use="optional" default="chromium {url}"/>
   286           <xsd:attribute name="WatchdogInterval" type="xsd:integer" use="optional"/>
   286           <xsd:attribute name="WatchdogInitial" type="xsd:integer" use="optional" default="30"/>
       
   287           <xsd:attribute name="WatchdogInterval" type="xsd:integer" use="optional" default="5"/>
       
   288           <xsd:attribute name="Port" type="xsd:integer" use="optional" default="8008"/>
       
   289           <xsd:attribute name="Interface" type="xsd:string" use="optional" default="localhost"/>
       
   290           <xsd:attribute name="Path" type="xsd:string" use="optional" default=""/>
   287         </xsd:complexType>
   291         </xsd:complexType>
   288       </xsd:element>
   292       </xsd:element>
   289     </xsd:schema>
   293     </xsd:schema>
   290     """
   294     """
   291 
   295 
   530 """)
   534 """)
   531             target_file.close()
   535             target_file.close()
   532 
   536 
   533         res += ((target_fname, open(target_path, "rb")),)
   537         res += ((target_fname, open(target_path, "rb")),)
   534 
   538 
       
   539         port = self.GetParamsAttributes("SVGHMI.Port")["value"]
       
   540         interface = self.GetParamsAttributes("SVGHMI.Interface")["value"]
       
   541         path = self.GetParamsAttributes("SVGHMI.Path")["value"].format(name=view_name)
       
   542         enable_watchdog = self.GetParamsAttributes("SVGHMI.EnableWatchdog")["value"]
       
   543         url="http://"+interface+("" if port==80 else (":"+str(port))
       
   544             ) + (("/"+path) if path else ""
       
   545             ) + ("#watchdog" if enable_watchdog else "")
       
   546 
   535         svghmi_cmds = {}
   547         svghmi_cmds = {}
   536         for thing in ["Start", "Stop", "Watchdog"]:
   548         for thing in ["Start", "Stop", "Watchdog"]:
   537              given_command = self.GetParamsAttributes("SVGHMI.On"+thing)["value"]
   549              given_command = self.GetParamsAttributes("SVGHMI.On"+thing)["value"]
   538              svghmi_cmds[thing] = (
   550              svghmi_cmds[thing] = (
   539                 "Popen(" +
   551                 "Popen(" +
   540                 repr(shlex.split(given_command.format(port="8008", name=view_name))) +
   552                 repr(shlex.split(given_command.format(
       
   553                     port=port, 
       
   554                     name=view_name,
       
   555                     url=url))) +
   541                 ")") if given_command else "pass # no command given"
   556                 ")") if given_command else "pass # no command given"
   542 
   557 
   543         runtimefile_path = os.path.join(buildpath, "runtime_%s_svghmi_.py" % location_str)
   558         runtimefile_path = os.path.join(buildpath, "runtime_%s_svghmi_.py" % location_str)
   544         runtimefile = open(runtimefile_path, 'w')
   559         runtimefile = open(runtimefile_path, 'w')
   545         runtimefile.write("""
   560         runtimefile.write("""
   546 # TODO : multiple watchdog (one for each svghmi instance)
   561 # TODO : multiple watchdog (one for each svghmi instance)
   547 def svghmi_watchdog_trigger():
   562 def svghmi_{location}_watchdog_trigger():
   548     {svghmi_cmds[Watchdog]}
   563     {svghmi_cmds[Watchdog]}
   549 
   564 
   550 svghmi_watchdog = None
   565 svghmi_watchdog = None
   551 
   566 
   552 def _runtime_{location}_svghmi_start():
   567 def _runtime_{location}_svghmi_start():
   553     global svghmi_watchdog
   568     global svghmi_watchdog, svghmi_servers
       
   569 
       
   570     srv = svghmi_servers.get("{interface}:{port}", None)
       
   571     if srv is not None:
       
   572         svghmi_root, svghmi_listener, path_list = srv 
       
   573         if '{path}' in path_list:
       
   574             raise Exception("SVGHMI {view_name}: path {path} already used on {interface}:{port}")
       
   575     else:
       
   576         svghmi_root = Resource()
       
   577         svghmi_root.putChild("ws", WebSocketResource(HMIWebSocketServerFactory()))
       
   578 
       
   579         svghmi_listener = reactor.listenTCP({port}, Site(svghmi_root), interface='{interface}')
       
   580         path_list = []
       
   581         svghmi_servers["{interface}:{port}"] = (svghmi_root, svghmi_listener, path_list)
       
   582 
   554     svghmi_root.putChild(
   583     svghmi_root.putChild(
   555         '{view_name}',
   584         '{path}',
   556         NoCacheFile('{xhtml}',
   585         NoCacheFile('{xhtml}',
   557         defaultType='application/xhtml+xml'))
   586             defaultType='application/xhtml+xml'))
       
   587 
       
   588     path_list.append("{path}")
   558 
   589 
   559     {svghmi_cmds[Start]}
   590     {svghmi_cmds[Start]}
   560 
   591 
   561     svghmi_watchdog = Watchdog(
   592     if {enable_watchdog}:
   562         {watchdog_initial}, 
   593         if svghmi_watchdog is None:
   563         {watchdog_interval}, 
   594             svghmi_watchdog = Watchdog(
   564         svghmi_watchdog_trigger)
   595                 {watchdog_initial}, 
       
   596                 {watchdog_interval}, 
       
   597                 svghmi_{location}_watchdog_trigger)
       
   598         else:
       
   599             raise Exception("SVGHMI {view_name}: only one watchdog allowed")
       
   600 
   565 
   601 
   566 def _runtime_{location}_svghmi_stop():
   602 def _runtime_{location}_svghmi_stop():
   567     global svghmi_watchdog
   603     global svghmi_watchdog, svghmi_servers
       
   604 
   568     if svghmi_watchdog is not None:
   605     if svghmi_watchdog is not None:
   569         svghmi_watchdog.cancel()
   606         svghmi_watchdog.cancel()
   570         svghmi_watchdog = None
   607         svghmi_watchdog = None
   571 
   608 
   572     svghmi_root.delEntity('{view_name}')
   609     svghmi_root, svghmi_listener, path_list = svghmi_servers["{interface}:{port}"]
       
   610     svghmi_root.delEntity('{path}')
       
   611 
       
   612     path_list.remove('{path}')
       
   613 
       
   614     if len(path_list)==0:
       
   615         svghmi_root.delEntity("ws")
       
   616         svghmi_listener.stopListening()
       
   617         svghmi_servers.pop("{interface}:{port}")
       
   618 
   573     {svghmi_cmds[Stop]}
   619     {svghmi_cmds[Stop]}
   574 
   620 
   575         """.format(location=location_str,
   621         """.format(location=location_str,
   576                    xhtml=target_fname,
   622                    xhtml=target_fname,
   577                    view_name=view_name,
   623                    view_name=view_name,
   578                    svghmi_cmds=svghmi_cmds,
   624                    svghmi_cmds=svghmi_cmds,
       
   625                    port = port,
       
   626                    interface = interface,
       
   627                    path = path,
       
   628                    enable_watchdog = enable_watchdog,
   579                    watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"],
   629                    watchdog_initial = self.GetParamsAttributes("SVGHMI.WatchdogInitial")["value"],
   580                    watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
   630                    watchdog_interval = self.GetParamsAttributes("SVGHMI.WatchdogInterval")["value"],
   581                    ))
   631                    ))
   582 
   632 
   583         runtimefile.close()
   633         runtimefile.close()