initial commit lets start
This commit is contained in:
@@ -0,0 +1,43 @@
|
|||||||
|
package builders
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"plcopenxmlbuilder/models"
|
||||||
|
"schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Twincat3Builder struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTwincat3Builder() *Twincat3Builder {
|
||||||
|
return &Twincat3Builder{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tc *Twincat3Builder) Marshal(s *schema.Project) ([]byte, error) {
|
||||||
|
plcopenxml := models.NewPLCopenXML()
|
||||||
|
|
||||||
|
proj := plcopenxml.AddProject()
|
||||||
|
proj.AddFileHeader(s.Information.CompanyName, s.Information.ProductName, s.Information.Version)
|
||||||
|
proj.AddContentHeader(s.ProjectName)
|
||||||
|
app := proj.AddApplication(models.URL_PLCOPENXML, models.HANDLE_IMPLEMENTATION)
|
||||||
|
|
||||||
|
switch s.GenerateType {
|
||||||
|
//PLC
|
||||||
|
case 0:
|
||||||
|
err := app.AddResources(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//Application
|
||||||
|
case 1:
|
||||||
|
//Files
|
||||||
|
case 2:
|
||||||
|
}
|
||||||
|
|
||||||
|
content, err := xml.MarshalIndent(plcopenxml.Project, " ", " ")
|
||||||
|
content = append([]byte(xml.Header), content...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return append([]byte(xml.Header), content...), nil
|
||||||
|
}
|
||||||
+99257
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
|||||||
|
package facades
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"plcopenxmlbuilder/builders"
|
||||||
|
"schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GenerateType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
PLC GenerateType = iota
|
||||||
|
Application
|
||||||
|
Files
|
||||||
|
)
|
||||||
|
|
||||||
|
type Builder interface {
|
||||||
|
Marshal(s *schema.Project) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBuilder(platform string, generateType GenerateType) (Builder, error) {
|
||||||
|
var builder Builder
|
||||||
|
|
||||||
|
switch platform {
|
||||||
|
case "twincat3":
|
||||||
|
builder = builders.NewTwincat3Builder()
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("no builder for %s found", platform)
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
module plcopenxmlbuilder
|
||||||
|
|
||||||
|
go 1.26.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
|
schema v0.0.0
|
||||||
|
)
|
||||||
|
|
||||||
|
replace schema => ../schema
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddData struct {
|
||||||
|
XMLName xml.Name `xml:"addData"`
|
||||||
|
Data []*Data `xml:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAddData() *AddData {
|
||||||
|
return &AddData{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AddData) AddProjectInformation(name, handleUnknown string) *ProjectInformation {
|
||||||
|
|
||||||
|
d := a.addNewData(fmt.Sprintf("%s/%s", name, XML_PROJECTINFORMATION), handleUnknown)
|
||||||
|
d.ProjectInformation = &ProjectInformation{}
|
||||||
|
|
||||||
|
return d.ProjectInformation
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AddData) AddApplication(name, handleUnknown string) *Data {
|
||||||
|
return a.addNewData(fmt.Sprintf("%s/%s", name, XML_APPLICATION), handleUnknown)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AddData) AddTasksettings(name, handleUnknown, kindOfTask, intervalUnit string, interval int) (*TaskSettings, error) {
|
||||||
|
data := a.addNewData(fmt.Sprintf("%s/%s", name, XML_TASKSETTINGS), handleUnknown)
|
||||||
|
|
||||||
|
data.TaskSettings = &TaskSettings{
|
||||||
|
KindOfTask: kindOfTask,
|
||||||
|
Interval: interval,
|
||||||
|
IntervalUnit: intervalUnit,
|
||||||
|
}
|
||||||
|
return data.TaskSettings, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AddData) addNewData(name, handleUnknown string) *Data {
|
||||||
|
d := NewData(name, handleUnknown)
|
||||||
|
a.Data = append(a.Data, d)
|
||||||
|
return d
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type Array struct {
|
||||||
|
XMLName xml.Name `xml:"array"`
|
||||||
|
Lower int `xml:"lower,attr"`
|
||||||
|
Upper int `xml:"upper,attr"`
|
||||||
|
BaseType BaseType `xml:"baseType"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type ArrayValue struct {
|
||||||
|
XMLName xml.Name `xml:"arrayValue"`
|
||||||
|
Value *Value `xml:"value"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Attribute struct {
|
||||||
|
XMLName xml.Name `xml:"Attribute"`
|
||||||
|
Name string `xml:"Name"`
|
||||||
|
Value string `xml:"Value"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Attributes struct {
|
||||||
|
XMLName xml.Name `xml:"Attributes"`
|
||||||
|
Attribute []*Attribute `xml:"Attribute"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type BaseType struct {
|
||||||
|
XMLName xml.Name `xml:"baseType"`
|
||||||
|
Derived *Derived `xml:"derived,omitempty"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Configurations struct {
|
||||||
|
XMLName xml.Name `xml:"configurations"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
const (
|
||||||
|
URL_PLCOPENXML = "http://www.3s-software.com/plcopenxml"
|
||||||
|
XML_PROJECTINFORMATION = "projectinformation"
|
||||||
|
XML_APPLICATION = "application"
|
||||||
|
XML_TASKSETTINGS = "tasksettings"
|
||||||
|
|
||||||
|
XMLNS_Project = "http://www.plcopen.org/xml/tc6_0200"
|
||||||
|
|
||||||
|
HANDLE_IMPLEMENTATION = "implementation"
|
||||||
|
)
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ContentHeader struct {
|
||||||
|
XMLName xml.Name `xml:"contentHeader"`
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
ModificationDateTime string `xml:"modificationDateTime,attr"`
|
||||||
|
CoordinateInfo CoordinateInfo `xml:"coordinateInfo"`
|
||||||
|
AddData *AddData `xml:"addData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ContentHeader) SetCurrentCreationDateTime() {
|
||||||
|
//format "2026-08-25T21:35:38.4736792"
|
||||||
|
c.ModificationDateTime = time.Now().Format("2006-01-02T15:04:05.0000000")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ContentHeader) SetCoordinateDefault() {
|
||||||
|
c.CoordinateInfo.Default()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ContentHeader) AddAddData() *AddData {
|
||||||
|
if c.AddData == nil {
|
||||||
|
c.AddData = NewAddData()
|
||||||
|
}
|
||||||
|
return c.AddData
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CoordinateInfo struct {
|
||||||
|
XMLName xml.Name `xml:"coordinateInfo"`
|
||||||
|
Fbd Fbd `xml:"fbd"`
|
||||||
|
Ld Ld `xml:"ld"`
|
||||||
|
Sfc Sfc `xml:"sfc"`
|
||||||
|
CreationDateTime string `xml:"creationDateTime,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CoordinateInfo) Default() {
|
||||||
|
c.Fbd.Default()
|
||||||
|
c.Ld.Default()
|
||||||
|
c.Sfc.Default()
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
XMLName xml.Name `xml:"data"`
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
HandleUnknown string `xml:"handleUnknown,attr"`
|
||||||
|
ProjectInformation *ProjectInformation `xml:"ProjectInformation,omitempty"`
|
||||||
|
Resource *Resourse `xml:"resource,omitempty"`
|
||||||
|
TaskSettings *TaskSettings `xml:"TaskSettings,omitempty"`
|
||||||
|
Attributes *Attributes `xml:"Attributes,omitempty"`
|
||||||
|
InterfaceAsPlainText *InterfaceAsPlainText `xml:"InterfaceAsPlainText,omitempty"`
|
||||||
|
ObjectId *ObjectId `xml:"ObjectId,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewData(name, handleUnknown string) *Data {
|
||||||
|
return &Data{
|
||||||
|
Name: name,
|
||||||
|
HandleUnknown: handleUnknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Data) AddResources(proj *schema.Project) error {
|
||||||
|
for _, device := range proj.Devices {
|
||||||
|
res := d.AddResource(device.Name)
|
||||||
|
err := res.AddTasks(device)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Data) AddResource(name string) *Resourse {
|
||||||
|
d.Resource = &Resourse{
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
return d.Resource
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DataTypes struct {
|
||||||
|
XMLName xml.Name `xml:"dataTypes"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type Derived struct {
|
||||||
|
XMLName xml.Name `xml:"derived"`
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Documentation struct {
|
||||||
|
XMLName xml.Name `xml:"documentation"`
|
||||||
|
Xhtml Xhtml `xml:"xhtml"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Fbd struct {
|
||||||
|
XMLName xml.Name `xml:"fbd"`
|
||||||
|
Scaling Scaling `xml:"scaling"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fbd *Fbd) Default() {
|
||||||
|
fbd.Scaling.Default()
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileHeader struct {
|
||||||
|
XMLName xml.Name `xml:"fileHeader"`
|
||||||
|
CompanyName string `xml:"companyName,attr"`
|
||||||
|
ProductName string `xml:"productName,attr"`
|
||||||
|
ProductVersion string `xml:"productVersion,attr"`
|
||||||
|
CreationDateTime string `xml:"creationDateTime,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FileHeader) SetCurrentCreationDateTime() {
|
||||||
|
//format "2026-08-25T21:35:38.4736792"
|
||||||
|
f.CreationDateTime = time.Now().Format("2006-01-02T15:04:05.0000000")
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type GlobalVars struct {
|
||||||
|
XMLName xml.Name `xml:"globalVars"`
|
||||||
|
Variable []*Variable `xml:"variable"`
|
||||||
|
AddData []*AddData `xml:"addData"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type InitialValue struct {
|
||||||
|
XMLName xml.Name `xml:"initialValue"`
|
||||||
|
ArrayValue *ArrayValue `xml:"arrayValue,omitempty"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Instances struct {
|
||||||
|
XMLName xml.Name `xml:"instances"`
|
||||||
|
Configurations Configurations `xml:"configurations"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InterfaceAsPlainText struct {
|
||||||
|
XMLName xml.Name `xml:"InterfaceAsPlainText"`
|
||||||
|
Xmlns string `xml:"xmlns,attr"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Ld struct {
|
||||||
|
XMLName xml.Name `xml:"ld"`
|
||||||
|
Scaling Scaling `xml:"scaling"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ld *Ld) Default() {
|
||||||
|
ld.Scaling.Default()
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ObjectId struct {
|
||||||
|
XMLName xml.Name `xml:"ObjectId"`
|
||||||
|
Value string `xml:",chardata"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewObjectId() *ObjectId {
|
||||||
|
id := uuid.New()
|
||||||
|
return &ObjectId{Value: id.String()}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
type PLCopenXML struct {
|
||||||
|
Project *Project `xml:"project"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPLCopenXML() *PLCopenXML {
|
||||||
|
plcopenxml := &PLCopenXML{}
|
||||||
|
plcopenxml.AddProject()
|
||||||
|
return plcopenxml
|
||||||
|
}
|
||||||
|
|
||||||
|
func (openXML *PLCopenXML) AddProject() *Project {
|
||||||
|
openXML.Project = &Project{
|
||||||
|
Xmlns: XMLNS_Project,
|
||||||
|
}
|
||||||
|
return openXML.Project
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PouInstance struct {
|
||||||
|
XMLName xml.Name `xml:"pouInstance"`
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
TypeName string `xml:"typeName,attr"`
|
||||||
|
Documentation *Documentation `xml:"documentation,omitempty"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Pous struct {
|
||||||
|
XMLName xml.Name `xml:"pous"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Project struct {
|
||||||
|
XMLName xml.Name `xml:"project"`
|
||||||
|
Xmlns string `xml:"xmlns,attr"`
|
||||||
|
FileHeader FileHeader `xml:"fileHeader"`
|
||||||
|
ContentHeader ContentHeader `xml:"contentHeader"`
|
||||||
|
Types Types `xml:"types"`
|
||||||
|
Instances Instances `xml:"instances"`
|
||||||
|
AddData *AddData `xml:"addData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) AddFileHeader(companyName, productName, productversion string) {
|
||||||
|
p.FileHeader = FileHeader{
|
||||||
|
CompanyName: companyName,
|
||||||
|
ProductName: productName,
|
||||||
|
ProductVersion: productversion,
|
||||||
|
}
|
||||||
|
p.FileHeader.SetCurrentCreationDateTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) AddContentHeader(projectName string) {
|
||||||
|
p.ContentHeader = ContentHeader{
|
||||||
|
Name: projectName,
|
||||||
|
}
|
||||||
|
p.FileHeader.SetCurrentCreationDateTime()
|
||||||
|
p.ContentHeader.SetCoordinateDefault()
|
||||||
|
p.ContentHeader.AddAddData().AddProjectInformation(URL_PLCOPENXML, HANDLE_IMPLEMENTATION)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) AddApplication(url, handleUnknown string) *Data {
|
||||||
|
if p.AddData == nil {
|
||||||
|
p.AddData = NewAddData()
|
||||||
|
}
|
||||||
|
return p.AddData.AddApplication(url, handleUnknown)
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type ProjectInformation struct {
|
||||||
|
XMLName xml.Name `xml:"ProjectInformation"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"plcopenxmlbuilder/utils"
|
||||||
|
"schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Resourse struct {
|
||||||
|
XMLName xml.Name `xml:"resource"`
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
Task []*Task `xml:"task"`
|
||||||
|
GlobalVars *GlobalVars `xml:"globalVars,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resourse) AddTasks(dev *schema.Device) error {
|
||||||
|
for _, task := range dev.Tasks {
|
||||||
|
if err := utils.CheckKindOfTask(task.KindOfTask); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := utils.CheckIntervalUnit(task.IntervalUnit); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
t, err := r.AddTask(task.Name, task.KindOfTask, task.IntervalUnit, task.Interval, task.Priority)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.AddPouInstances(task)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resourse) AddTask(name, kindOfTask, intervalUnit string, interval, priority int) (*Task, error) {
|
||||||
|
t := &Task{
|
||||||
|
Name: name,
|
||||||
|
Priority: priority,
|
||||||
|
}
|
||||||
|
t.SetInterval(interval)
|
||||||
|
|
||||||
|
err := t.AddAddData(kindOfTask, intervalUnit, interval)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r.Task = append(r.Task, t)
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Scaling struct {
|
||||||
|
XMLName xml.Name `xml:"scaling"`
|
||||||
|
X int `xml:"x,attr"`
|
||||||
|
Y int `xml:"y,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Scaling) Default() {
|
||||||
|
s.X = 1
|
||||||
|
s.Y = 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Sfc struct {
|
||||||
|
XMLName xml.Name `xml:"sfc"`
|
||||||
|
Scaling Scaling `xml:"scaling"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sfc *Sfc) Default() {
|
||||||
|
sfc.Scaling.Default()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type SimpleValue struct {
|
||||||
|
XMLName xml.Name `xml:"simpleValue"`
|
||||||
|
Value string `xml:"value,attr"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type StructValue struct {
|
||||||
|
XMLName xml.Name `xml:"structValue"`
|
||||||
|
Value []*Value `xml:"value,omitempty"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Task struct {
|
||||||
|
XMLName xml.Name `xml:"task"`
|
||||||
|
Name string `xml:"name,attr"`
|
||||||
|
Interval string `xml:"interval,attr"`
|
||||||
|
Priority int `xml:"priority,attr"`
|
||||||
|
PouInstance []*PouInstance `xml:"pouInstance"`
|
||||||
|
AddData *AddData `xml:"addData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Task) AddAddData(kindOfTask, intervalUnit string, interval int) error {
|
||||||
|
if t.AddData != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
t.AddData = NewAddData()
|
||||||
|
_, err := t.AddData.AddTasksettings(URL_PLCOPENXML, HANDLE_IMPLEMENTATION, kindOfTask, intervalUnit, interval)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert interval to plcopenxml format in value in milliseconds
|
||||||
|
func (t *Task) SetInterval(interval int) {
|
||||||
|
//convert to secconts
|
||||||
|
i := interval / 1000
|
||||||
|
if i < 1 {
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
t.Interval = fmt.Sprintf("PT%dS", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Task) AddPouInstances(task *schema.Task) {
|
||||||
|
for _, prg := range task.Programs {
|
||||||
|
t.AddPouInstance(prg.Name, prg.TypeName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Task) AddPouInstance(name, typeName string) *PouInstance {
|
||||||
|
pI := &PouInstance{
|
||||||
|
Name: name,
|
||||||
|
TypeName: typeName,
|
||||||
|
Documentation: &Documentation{
|
||||||
|
Xhtml: Xhtml{
|
||||||
|
Xmlns: XMLNS,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
t.PouInstance = append(t.PouInstance, pI)
|
||||||
|
return pI
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TaskSettings struct {
|
||||||
|
XMLName xml.Name `xml:"TaskSettings"`
|
||||||
|
KindOfTask string `xml:"KindOfTask,attr"`
|
||||||
|
Interval int `xml:"Interval,attr"`
|
||||||
|
IntervalUnit string `xml:"IntervalUnit,attr"`
|
||||||
|
Watchdog *Watchdog `xml:"Watchdog"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type Type struct {
|
||||||
|
XMLName xml.Name `xml:"type"`
|
||||||
|
Array *Array `xml:"array,omitempty"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Types struct {
|
||||||
|
XMLName xml.Name `xml:"types"`
|
||||||
|
DataTypes DataTypes `xml:"dataTypes"`
|
||||||
|
Pous Pous `xml:"pous"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type Value struct {
|
||||||
|
XMLName xml.Name `xml:"value"`
|
||||||
|
StructValue *StructValue `xml:"structValue,omitempty"`
|
||||||
|
SimpleValue *SimpleValue `xml:"simpleValue,omitempty"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "encoding/xml"
|
||||||
|
|
||||||
|
type Variable struct {
|
||||||
|
XMLName xml.Name `xml:"variable"`
|
||||||
|
Type Type `xml:"type"`
|
||||||
|
InitialValue *InitialValue `xml:"initialValue,omitempty"`
|
||||||
|
Documentation *Documentation `xml:"documentation,omitempty"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Watchdog struct {
|
||||||
|
XMLName xml.Name `xml:"Watchdog"`
|
||||||
|
Enabled bool `xml:"Enabled,attr"`
|
||||||
|
TimeUnit string `xml:"TimeUnit,attr"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
XMLNS = "http://www.w3.org/1999/xhtml"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Xhtml struct {
|
||||||
|
XMLName xml.Name `xml:"xhtml"`
|
||||||
|
Xmlns string `xml:"xmlns,attr"`
|
||||||
|
Text string `xml:",chardata"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"plcopenxmlbuilder/facades"
|
||||||
|
"schema"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCreatePLCOpenXML(t *testing.T) {
|
||||||
|
builder, err := facades.NewBuilder("twincat3", facades.PLC)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
proj := schema.Project{
|
||||||
|
ProjectName: "CH_BE_STEFFISBURG_SCHOENAU_SPORTANLAGE_TA03",
|
||||||
|
Information: schema.Information{
|
||||||
|
CompanyName: "Buehler & Scherler",
|
||||||
|
ProductName: "PLCopenXML Builder",
|
||||||
|
Version: "0.0.1",
|
||||||
|
},
|
||||||
|
Devices: []*schema.Device{{
|
||||||
|
Name: "SPS001",
|
||||||
|
Tasks: []*schema.Task{
|
||||||
|
{
|
||||||
|
Name: "Main",
|
||||||
|
KindOfTask: "Cyclic",
|
||||||
|
IntervalUnit: "ms",
|
||||||
|
Interval: 100,
|
||||||
|
Priority: 10,
|
||||||
|
Programs: []*schema.Program{
|
||||||
|
{
|
||||||
|
Name: "Main",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlBytes, err := builder.Marshal(&proj)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log(string(xmlBytes))
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const (
|
||||||
|
CYCLIC = "Cyclic"
|
||||||
|
FREEEWHEEL = "Freewheel"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckKindOfTask(kindOfTask string) error {
|
||||||
|
switch kindOfTask {
|
||||||
|
case FREEEWHEEL, CYCLIC:
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("%s kindOfTask not supported", kindOfTask)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
SECOND = "s"
|
||||||
|
MILLISECOND = "ms"
|
||||||
|
MICROSECOND = "us"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckIntervalUnit(intervalUnit string) error {
|
||||||
|
switch intervalUnit {
|
||||||
|
case SECOND, MILLISECOND, MICROSECOND:
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("%s interval unit not supported", intervalUnit)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user