svghmi/svghmi.py
branchsvghmi
changeset 2771 361366b891ca
parent 2768 31785529a657
child 2772 3f1dd8312710
equal deleted inserted replaced
2770:41fc23fd21c4 2771:361366b891ca
   197 
   197 
   198         # TODO check if programs need to be declared separately
   198         # TODO check if programs need to be declared separately
   199         # "programs_declarations": "\n".join(["extern %(type)s %(C_path)s;" %
   199         # "programs_declarations": "\n".join(["extern %(type)s %(C_path)s;" %
   200         #                                     p for p in self._ProgramList]),
   200         #                                     p for p in self._ProgramList]),
   201 
   201 
   202         # TODO generate C code to observe/access HMI tree variables
   202         # C code to observe/access HMI tree variables
   203         svghmi_c_filepath = paths.AbsNeighbourFile(__file__, "svghmi.c")
   203         svghmi_c_filepath = paths.AbsNeighbourFile(__file__, "svghmi.c")
   204         svghmi_c_file = open(svghmi_c_filepath, 'r')
   204         svghmi_c_file = open(svghmi_c_filepath, 'r')
   205         svghmi_c_code = svghmi_c_file.read()
   205         svghmi_c_code = svghmi_c_file.read()
   206         svghmi_c_file.close()
   206         svghmi_c_file.close()
   207         svghmi_c_code = svghmi_c_code % { 
   207         svghmi_c_code = svghmi_c_code % { 
   208             "variable_decl_array": ",\n".join(variable_decl_array),
   208             "variable_decl_array": ",\n".join(variable_decl_array),
   209             "extern_variables_declarations": "\n".join(extern_variables_declarations),
   209             "extern_variables_declarations": "\n".join(extern_variables_declarations),
   210             "buffer_size": buf_index,
   210             "buffer_size": buf_index,
   211             "var_access_code": targets.GetCode("var_access.c"),
   211             "var_access_code": targets.GetCode("var_access.c"),
   212             "PLC_ticktime": self.GetCTRoot().GetTicktime()
   212             "PLC_ticktime": self.GetCTR().GetTicktime()
   213             }
   213             }
   214 
   214 
   215         gen_svghmi_c_path = os.path.join(buildpath, "svghmi.c")
   215         gen_svghmi_c_path = os.path.join(buildpath, "svghmi.c")
   216         gen_svghmi_c = open(gen_svghmi_c_path, 'w')
   216         gen_svghmi_c = open(gen_svghmi_c_path, 'w')
   217         gen_svghmi_c.write(svghmi_c_code)
   217         gen_svghmi_c.write(svghmi_c_code)
   218         gen_svghmi_c.close()
   218         gen_svghmi_c.close()
   219 
   219 
   220         return (["svghmi"], [(gen_svghmi_c_path, IECCFLAGS)], True), ""
   220         # Python based WebSocket HMITree Server
       
   221         svghmiserverfile = open(paths.AbsNeighbourFile(__file__, "svghmi_server.py"), 'r')
       
   222         svghmiservercode = svghmiserverfile.read()
       
   223         svghmiserverfile.close()
       
   224 
       
   225         runtimefile_path = os.path.join(buildpath, "runtime_svghmi.py")
       
   226         runtimefile = open(runtimefile_path, 'w')
       
   227         runtimefile.write(svghmiservercode)
       
   228         runtimefile.close()
       
   229 
       
   230         return ((["svghmi"], [(gen_svghmi_c_path, IECCFLAGS)], True), "",
       
   231                 ("runtime_svghmi0.py", open(runtimefile_path, "rb")))
   221 
   232 
   222 class SVGHMI(object):
   233 class SVGHMI(object):
   223     XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
   234     XSD = """<?xml version="1.0" encoding="utf-8" ?>
   224     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   235     <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   225       <xsd:element name="SVGHMI">
   236       <xsd:element name="SVGHMI">
   226         <xsd:complexType>
   237         <xsd:complexType>
   227           <xsd:attribute name="enableHTTP" type="xsd:boolean" use="optional" default="false"/>
   238           <xsd:attribute name="enableHTTP" type="xsd:boolean" use="optional" default="false"/>
   228           <xsd:attribute name="bindAddress" type="xsd:string" use="optional" default="localhost"/>
   239           <xsd:attribute name="bindAddress" type="xsd:string" use="optional" default="localhost"/>
   243             "bitmap":    "ImportSVG",  # should be something different
   254             "bitmap":    "ImportSVG",  # should be something different
   244             "name":    _("Inkscape"),
   255             "name":    _("Inkscape"),
   245             "tooltip": _("Edit HMI"),
   256             "tooltip": _("Edit HMI"),
   246             "method":   "_StartInkscape"
   257             "method":   "_StartInkscape"
   247         },
   258         },
       
   259 
       
   260         # TODO : HMITree button
       
   261         #        - can drag'n'drop variabes to Inkscape
       
   262 
   248     ]
   263     ]
   249 
   264 
   250     def _getSVGpath(self, project_path=None):
   265     def _getSVGpath(self, project_path=None):
   251         if project_path is None:
   266         if project_path is None:
   252             project_path = self.CTNPath()
   267             project_path = self.CTNPath()
   292         when _generate_softPLC have been called
   307         when _generate_softPLC have been called
   293         @param locations: ignored
   308         @param locations: ignored
   294         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   309         @return: [(C_file_name, CFLAGS),...] , LDFLAGS_TO_APPEND
   295         """
   310         """
   296 
   311 
       
   312         location_str = "_".join(map(str, self.GetCurrentLocation()))
       
   313         view_name = self.BaseParams.getName()
       
   314 
   297         svgfile = self._getSVGpath()
   315         svgfile = self._getSVGpath()
       
   316 
       
   317         res = ([], "", False)
       
   318 
       
   319         target_fname = "sghmi_"+location_str+".xhtml"
       
   320 
       
   321         target_path = os.path.join(self._getBuildPath(), target_fname)
       
   322         target_file = open(target_path, 'w')
       
   323 
   298         if os.path.exists(svgfile):
   324         if os.path.exists(svgfile):
   299 
   325 
   300             # TODO : move to __init__
   326             # TODO : move to __init__
   301             transform = XSLTransform(os.path.join(ScriptDirectory, "gen_index_xhtml.xslt"),
   327             transform = XSLTransform(os.path.join(ScriptDirectory, "gen_index_xhtml.xslt"),
   302                           [("GetSVGGeometry", lambda *_ignored:self.GetSVGGeometry()),
   328                           [("GetSVGGeometry", lambda *_ignored:self.GetSVGGeometry()),
   307             svgdom = etree.parse(svgfile)
   333             svgdom = etree.parse(svgfile)
   308 
   334 
   309             # call xslt transform on Inkscape's SVG to generate XHTML
   335             # call xslt transform on Inkscape's SVG to generate XHTML
   310             result = transform.transform(svgdom)
   336             result = transform.transform(svgdom)
   311            
   337            
       
   338             result.write(target_file, encoding="utf-8")
   312             # print(str(result))
   339             # print(str(result))
   313             # print(transform.xslt.error_log)
   340             # print(transform.xslt.error_log)
   314 
   341 
   315             # TODO
   342             # TODO
   316             #   - Errors on HMI semantics
   343             #   - Errors on HMI semantics
   317             #   - ... maybe something to have a global view of what is declared in SVG.
   344             #   - ... maybe something to have a global view of what is declared in SVG.
   318 
   345 
   319         else:
   346         else:
   320             # TODO : use default svg that expose the HMI tree as-is 
   347             # TODO : use default svg that expose the HMI tree as-is 
   321             pass
   348             target_file.write("""<!DOCTYPE html>
   322 
   349 <html>
   323 
   350 <body>
   324         res = ([], "", False)
   351 <h1> No SVG file provided </h1>
   325 
   352 </body>
   326         targetpath = os.path.join(self._getBuildPath(), "target.xhtml")
   353 </html>
   327         targetfile = open(targetpath, 'w')
   354 """)
   328 
   355 
   329         # TODO : DOM to string
   356         target_file.close()
   330         targetfile.write("TODO")
   357 
   331         targetfile.close()
   358         runtimefile_path = os.path.join(buildpath, "runtime_svghmi1_%s.py" % location_str)
   332         res += (("target.js", open(targetpath, "rb")),)
   359         runtimefile = open(runtimefile_path, 'w')
   333 
   360         runtimefile.write("""
   334         # TODO add C code to expose HMI tree variables to shared memory
   361 def _runtime_svghmi1_%(location)s_start():
   335         # TODO generate a description of shared memory (xml or CSV) 
   362     svghmi_root.putChild('%(view_name)s',File('%(xhtml)s'))
   336         #      that can be loaded by svghmi QTWeb* app or svghmi server
   363 
   337 
   364         """ % {"location": location_str,
       
   365                "xhtml": target_fname,
       
   366                "view_name": view_name})
       
   367 
       
   368         runtimefile.close()
       
   369 
       
   370         res += (("runtime_svghmi1_%s.py" % location_str, open(runtimefile_path, "rb")),)
   338 
   371 
   339         return res
   372         return res
   340 
   373 
   341     def _ImportSVG(self):
   374     def _ImportSVG(self):
   342         dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "",  _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN)
   375         dialog = wx.FileDialog(self.GetCTRoot().AppFrame, _("Choose a SVG file"), os.getcwd(), "",  _("SVG files (*.svg)|*.svg|All files|*.*"), wx.OPEN)