forked from robinson/gos7
-
Notifications
You must be signed in to change notification settings - Fork 0
/
control.go
113 lines (106 loc) · 3.2 KB
/
control.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package gos7
// Copyright 2018 Trung Hieu Le. All rights reserved.
// This software may be modified and distributed under the terms
// of the BSD license. See the LICENSE file for details.
import (
"encoding/binary"
"fmt"
)
//implement PLC hot start interface
func (mb *client) PLCHotStart() error {
requestData := make([]byte, len(s7HotStartTelegram))
copy(requestData, s7HotStartTelegram)
request := NewProtocolDataUnit(requestData)
//send
response, err := mb.send(&request)
if err == nil {
if length := len(response.Data); length > 18 { // 18 is the minimum expected
if int(response.Data[19]) != pduStart {
err = fmt.Errorf(ErrorText(errCliCannotStartPLC))
} else {
if int(response.Data[20]) == pduAlreadyStarted {
err = fmt.Errorf(ErrorText(errCliAlreadyRun))
} else {
err = fmt.Errorf(ErrorText(errCliCannotStartPLC))
}
}
} else {
err = fmt.Errorf(ErrorText(errIsoInvalidPDU))
}
}
return err
}
//implement of PLC Colde Start interface
func (mb *client) PLCColdStart() error {
requestData := make([]byte, len(s7ColdStartTelegram))
copy(requestData, s7ColdStartTelegram)
request := NewProtocolDataUnit(requestData)
//send
response, err := mb.send(&request)
if err == nil {
if length := len(response.Data); length > 18 { // 18 is the minimum expected
if int(response.Data[19]) != pduStart {
err = fmt.Errorf(ErrorText(errCliCannotStartPLC))
} else {
if int(response.Data[20]) == pduAlreadyStarted {
err = fmt.Errorf(ErrorText(errCliAlreadyRun))
} else {
err = fmt.Errorf(ErrorText(errCliCannotStartPLC))
}
}
} else {
err = fmt.Errorf(ErrorText(errIsoInvalidPDU))
}
}
return err
}
func (mb *client) PLCStop() error {
requestData := make([]byte, len(s7StopTelegram))
copy(requestData, s7StopTelegram)
request := NewProtocolDataUnit(requestData)
//send
response, err := mb.send(&request)
if err == nil {
if length := len(response.Data); length > 18 { // 18 is the minimum expected
if int(response.Data[19]) != pduStop {
err = fmt.Errorf(ErrorText(errCliCannotStopPLC))
} else {
if int(response.Data[20]) == pduAlreadyStarted {
err = fmt.Errorf(ErrorText(errCliAlreadyStop))
} else {
err = fmt.Errorf(ErrorText(errCliCannotStopPLC))
}
}
} else {
err = fmt.Errorf(ErrorText(errIsoInvalidPDU))
}
}
return err
}
//
func (mb *client) PLCGetStatus() (status int, err error) {
//initialize
requestData := make([]byte, len(s7GetStatusTelegram))
copy(requestData, s7GetStatusTelegram)
request := NewProtocolDataUnit(requestData)
//send
response, err := mb.send(&request)
if err == nil {
if length := len(response.Data); length > 30 { // 30 is the minimum expected
if result := binary.BigEndian.Uint16(response.Data[27:]); result == 0 {
if int(response.Data[44]) == 0 || int(response.Data[44]) == 8 || int(response.Data[44]) == 4 {
status = int(response.Data[44])
} else {
// Since RUN status is always 8 for all CPUs and CPs, STOP status
// sometime can be coded as 3 (especially for old cpu...)
status = s7CpuStatusStop
}
} else {
err = fmt.Errorf(ErrorText(CPUError(uint(result))))
}
} else {
err = fmt.Errorf(ErrorText(errIsoInvalidPDU))
}
}
return
}