-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpylogix_logger_drbitboy.py
246 lines (201 loc) · 8.5 KB
/
pylogix_logger_drbitboy.py
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
"""
simple read list in loop, interval = 0.5 seconds (default)
Read a list of tags, log value changes
"""
import re
import sys
import time
import pylogix
import datetime
import logger_classes as LC
if "__main__" == __name__:
####################################################################
### Start prologue
### 1) Process command-line options
av1 = sys.argv[1:]
### 1.1) PLC tags to read: --tag=Tag0=[ --tag=Tag1[...]]
tags = [a[6:] for a in av1 if a[:6]=='--tag=']
### 1.1.1) Ensure at least one tag was specified
assert tags,"""
Usage:
python pylogix_logger_drbitboy \\
\\
Tag names to log (one required): \\
\\
--tag=TAG0[ --tag=TAG2[ ...]] \\
\\
PLC connection information: \\
\\
[--ip=192.168.1.10] \\
[--micro8xx] \\
\\
Logging inter-sample interval, s: \\
\\
[--interval=0.5] \\
\\
Flat ASCII log: \\
\\
[--flat-ascii=path.txt] \\
\\
CSV Flat ASCII log: \\
\\
[--flat-csv=path.csv] \\
\\
eXcel log: \\
\\
[--excel=path.xlsx] \\
[--excel-max-rows=0] \\
\\
*** N.B. 0 => no limit on rows \\
\\
Google Sheets log: \\
\\
[--gapi-ssheet-id=...] \\
[--gapi-sheet-name=...] \\
[--gapi-creds=credentials.json] \\
[--gapi-pickle=token.pickle] \\
[--gapi-max-rows=20] \\
\\
MariaDB/MySQL log: \\
\\
[--mysql-db=test_...] \\
\\
-> MySQLdb.connect() keyword args: \\
\\
[--mysql-host=...] \\
[--mysql-user=...] \\
[--mysql-password=''] \\
[--mysql-read_default_group=''] \\
\\
Debugging: \\
\\
[--debug]
"""
### 1.2) PLC configuration:
###
### --ip=192.168.1.10 ### IP address
### --micro8... ### If PLC is Micro8xx
###
ipaddr = (["192.168.1.10"]
+[a[5:] for a in av1 if a[:5]=='--ip=']
)[-1]
micro8xx = ['--micro8' in [a[:8].lower() for a in av1]]
### 1.3) Inter-sample interval, seconds: --interval=0.5
intrvl = float(([0.5]
+[a[11:] for a in av1 if a[:11]=='--interval=']
)[-1]
)
### 1.4) Filename for flat ASCII log: --flat-ascii=ascii_log.txt
flatxt = ([False]
+[a[13:] for a in av1 if a[:13]=='--flat-ascii=']
)[-1]
### 1.5) Filename for CSV log: --flat-csv=csv_log.csv
csv = ([False]
+[a[11:] for a in av1 if a[:11]=='--flat-csv=']
)[-1]
### 1.6) Filename for eXcel log: --excel=xl_log.xlsx
### --excel-max-rows=0
xl = ([False]
+[a[8:] for a in av1 if a[:8]=='--excel=']
)[-1]
xl_max_rows = ([False]
+[a[17:] for a in av1 if a[:17]=='--excel-max-rows=']
)[-1]
### 1.7) Google sheet API - only used if spreadsheet ID is not False
###
### --gapi-ssheet-id=... ### Spreadsheet identifier
### [--gapi-sheet-name=PLCLOGPOC] ### Sheet name
### [--gapi-pickle=token.pickle] ### Pickled credentials
### [--gapi-creds=credentials.json] ### Credentials JSON file
###
ssheet_id = ([False]
+[a[17:] for a in av1 if a[:17]=='--gapi-ssheet-id=']
)[-1]
sheet_name = (['PLCLOGPOC']
+[a[18:] for a in av1 if a[:18]=='--gapi-sheet-name=']
)[-1]
pickle_file = (['token.pickle']
+[a[14:] for a in av1 if a[:14]=='--gapi-pickle=']
)[-1]
creds_file = (['credentials.json']
+[a[13:] for a in av1 if a[:13]=='--gapi-creds=']
)[-1]
gapi_max_rows = ([200]
+[a[16:] for a in av1 if a[:16]=='--gapi-max-rows=']
)[-1]
### 1.8) MariaDB/MySQL database log:
### --mysql-db=... ### MariaDB/MySQL server database name
### --mysql-KEY=VALUE ### MySQLdb.connect keyword arg KEY=VAL
### E.g.
### --mysql-host=localhost ### Host running DB server
### --mysql-user=test ### DB server username
### --mysql-passwd='' ### DB server user password
### --mysql-read_default_group='' ### ~/.my.cnf dflt group ID
mysql_db = ([False]
+[a[11:] for a in av1 if a[:11]=='--mysql-db=']
)[-1]
rgx_mysql = re.compile('^--mysql-([A-Za-z0-9_]+)=(.*)$')
mysql_kwargs = dict()
for arg in av1:
match = rgx_mysql.match(arg)
if None is match: continue
key,val = match.groups()
mysql_kwargs[key] = val
### 1.9) PYLOGIX_LOGGER debugging
debug = '--debug' in av1
### 2) Open pylogix communications
with pylogix.PLC(ipaddr) as comm:
### 2.1) Set up pylogix Read options as lambda function
### 2.1.1) Micro8xx cannot read sequence of tags; accomplish
### same via list comprehension
comm.Micro800 = micro8xx
if micro8xx: R = lambda : [comm.Read(tag) for tag in tags]
else : R = lambda : comm.Read(tags).Value
### 2.2) Build list of loggers, from logger_classes module
pyloggers = list()
app = pyloggers.append
### 2.2.1) Flat ASCII log "Name - Value - Timestamp"
if flatxt:
app(LC.PYLOGIX_LOGGER_FLAT_ASCII(flatxt,R(),debug=debug))
### 2.2.2) CSV log "Name,Value,Timestamp"
if csv:
app(LC.PYLOGIX_LOGGER_CSV(csv,R(),debug=debug))
### 2.2.3) eXcel workbook log
if xl:
app(LC.PYLOGIX_LOGGER_EXCEL(xl
,R()
,max_rows=xl_max_rows
,debug=debug
)
)
### 2.2.4) Google Sheet API log
if ssheet_id:
app(LC.PYLOGIX_LOGGER_GOOGLE_SHEET(R()
,SS_ID=ssheet_id
,SHEET_NAME=sheet_name
,TOKEN_FILE=pickle_file
,CREDENTIAL_FILE=creds_file
,max_rows=gapi_max_rows
,debug=debug
)
)
### 2.2.5) MariaDB/MySQL log
if mysql_db:
app(LC.PYLOGIX_LOGGER_MYSQL(R()
,debug=debug
,**mysql_kwargs
)
)
### End prologue
################################################################
################################################################
### Here's the beef:
### - In a loop, log new elements that differ from old elements
################################################################
while True:
try:
for pylogger in pyloggers: pylogger.log_news(R())
time.sleep(intrvl) ### Wait before repeating
except KeyboardInterrupt:
print('\n\n\n') ### Help cmd line editor
break ### Exit loop on CONTROL+C