22 #License along with this library; if not, write to the Free Software |
22 #License along with this library; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 import os, sys, getopt |
25 import os, sys, getopt |
26 |
26 |
27 try: |
|
28 import wx, re |
|
29 from wx.lib.embeddedimage import PyEmbeddedImage |
|
30 from threading import Thread |
|
31 from types import * |
|
32 havewx = True |
|
33 except: |
|
34 havewx = False |
|
35 |
|
36 if havewx: |
|
37 defaulticon = PyEmbeddedImage( |
|
38 "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABc5J" |
|
39 "REFUSIl9lW1MW9cZx3/n2vf6BQO2MZiXGBISILCVUEUlitYpjaKpXZJ1XZZ2kzJVY9r6IeLD" |
|
40 "pGTaNG3KtGmNNGlbpW3VFhRp0l6aZCllpVUqtVNJtBFKE5QXLxCjpCYEY7DBr9hcm3vPPgQY" |
|
41 "IQmPdKR7/vd5/v/n5dxzhZSSNeYBOoGDQGcoFPINDAyUDQ0NOUdGRmyGYSiBQGCpoaGhuGnT" |
|
42 "psShQ4f6WltbewEBVAK3gCBgrjJKKZFSKlLKeillt5Ty40gkMnnw4MFFQG60ysrKZHd3dyoe" |
|
43 "j//bNM0Le/fuPd/e3r5lmRMpJWK5ghrgFeBIT09P4/Hjx73pdFo47HaaNlfRutnJru0OKsoE" |
|
44 "E3GVqaSNa6EUw1dvIKWkoqKCrVu3FoeHh9WamppfRiKRn6wUYAUcwE7g2e7u7vrTp09XGIZB" |
|
45 "W1Mdv3qtmoBPrG0hHVsMhKLj6nqOqOWn/Pjnv2dgYIC5uTl1uSM71/pbgUbg6bNnz/rPnDnj" |
|
46 "dzoddO0P8Oo+jY2suDDD1Zv9DA1dfghXVbVBCFEqpcwAKEDTxMSE58SJE8+oqsq3nq/l1X0a" |
|
47 "QihYtNLHLqRET03wuYp7fO9r26mpKlsVUBSl0W63V6/shZTyyIEDB344Njb21JYaG7/5bgkA" |
|
48 "Dm8zTS/+7bHZLy0mSN+7yNztt8nPjYHFwfvXDf1P70zZ0ok0LS0tZy9fvvxNAGswGFQnJyef" |
|
49 "KnM5+NHLzuUDsrFZ7R68zS/hrGon1PcNMPI0BIzs9tcCNvNfDqxW64uqqvqKxWJc6e3trVVV" |
|
50 "leaAk6ryJ5N/9tH3GXv7Je7/5xermN3diMPXCkDfgrkg3UU0txWLxeLw+/1fB1BGR0frbTYb" |
|
51 "TXWWDbNeysUoZKbIRIZBPviOzKU8ejLMHyPFcMprrweQ7iUAXC7XPiGEak2lUk02m42mWn1D" |
|
52 "gfrnTiKNIrbyzSAUjEKWCx+/Mf+HyELBrLBvBhAIKDdgGsrLy+sAv1UIUa1pGv7yxQ0FbGX1" |
|
53 "D+0LQmHW7fVavE5Mo/gAFCCcoOs6NpvNA7gVRVGCmqYRz1hXg7NFU39rjshawjcuvs4P+o/y" |
|
54 "24uvE1+I4VCdfGfXUb76+VdWfQQCkbJSKBQoFApJTdMsCvApQDSlAjCTN7I/y5CNllpq1wqE" |
|
55 "YmPciIzwwdi7BKevreK7Gp5dfbYoFoozJrquo+v6rMViWbQCV4QQzGTsQJY3kzIhvFpgfYte" |
|
56 "7jhCMp9kk7uep+ueWcWj6f8Xqioq8ck0xcIS6XT6vpRy3gqMqKpqRBfKLLNF1ZRV6YBiPDrw" |
|
57 "vduefwTL6hl6b74FgFVR0T4rJTU3jcvlymcymal8Ph+z9vf3p7u6uv5y/vz5bw994ld2fmUH" |
|
58 "7nYFRVG4Gb3Guv8FpmmQzCcIJ+5w8c5HRFL3UYRC+ZKX633j6LpObW3tDcMwrsODq4Jbt27V" |
|
59 "HT58+N7o6KgCYHfY2f2lXfi+6CJbnsAwjUeyXzFFKLgdHqb+mmL8xh22bduWmJycfHN2dvbX" |
|
60 "uVwuoQC0tbXlKisrYytBi/lFZsKzOErtTyQWCOxWO36ljvl/FLk+dJOSkhJTUZR35+fn+3K5" |
|
61 "XAIeXNcASz6fbxzwrxDYVQdqpARvs498IYchDUxpogiBVVFxqE7U/5Zx4c8fEo/FKS0tlR0d" |
|
62 "HZ8ODg6+l06nr6zwrAp4PJ6Qpmlf2L9/fywYDFaOXB0RI1dHaGpuoq29Fa1Uxe62YeZMInei" |
|
63 "jAY/IRqNAtDZ2blUV1fXPzg4+F5VVdU/H6p0eYjqsWPHvnz37t0XwuHw7d27d4eTyeTvLl26" |
|
64 "FJiamnpim6qrq9mzZ094fHz875FI5J3p6ekr631WBARgaWlpCezYsePeuXPnzFAo5Dp58uS+" |
|
65 "dDp91GKxNBYKBW82m3Vomqa7XK7pbDYbnJmZuR2LxYL5fP79WCyWeeys1h/D9e97enqsp06d" |
|
66 "8mWzWU+xWPTkcjmXaZpxwzDCsVhsbqNggP8BMJOU3UUUf+0AAAAASUVORK5CYII=") |
|
67 |
|
68 #---------------------------------------------------------------------- |
|
69 starticon = PyEmbeddedImage( |
|
70 "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABbpJ" |
|
71 "REFUSIl9lltsFNcdxn9nZnbHs15fd23j9TXYC0UCKzEhMQ+oIS2g1kQ1pbFStX0opFWsovSh" |
|
72 "rUqp2pS2ioTUolaKFOGHqGkiJcKRuDhOaZRiZCsCXyBgCBBfMfbu+oa9s17wzuzl9MH24mDD" |
|
73 "XzoPc/6fft+c72jOGSGlZEVlAU8D9cB20zQ9HR0duRcvXszq7e01EomEUlFREa+srLR8Pl+g" |
|
74 "sbHx3zk5ORcAFfACA8Bt4CFUSomUUkgpS6SUB6SUH5umOXLgwIEHqqrKJfGao7S0VB49ejRo" |
|
75 "2/YnUsrT+/fvb66pqSldYiKlRCytoBB4Gfjx6dOnq5qamjwTExOKqqqU+QrYUJFN7QY32Qbc" |
|
76 "vSeYCGtcux1i5M5dAPx+P1VVVQvnzp0ziouLfx8MBt9cXoAGZABbgZ1HjhwpO378eEEymaSi" |
|
77 "tIBjPy9lU5nKoyWExF2yjy+mN3HsH+/Q3d3NwMCAsZTI9pVaDXgK2Hr27Nn85ubmEpdh8IMX" |
|
78 "ffxirwshVrGXHBQSC/dIRvoZGuz/WkvTtHIhhCGlXABQgI2Tk5P5hw8f3uZwOGj8VjGHXnoC" |
|
79 "HJCpJFbkLtr8FXbX+XC79HRPVVW/qqre9LtIKX/S0NDwy76+vq1lhTr/fM2NAmTk+fHv/dea" |
|
80 "BlZkDHP0PHODH2NHg1gykw8/X7Dfb7vjTNgJqqurT3R1db0GoF2/fl0fGhqqdWca/K7RhZLO" |
|
81 "WSBU55oGGXlVZORVkeV7nsFPDqKL+9TWJCI3n9rojX2mYhjGj4QQv5FSziunTp0qdjqd4hvl" |
|
82 "Lnz5j49lrPMNhv7zM6b63knPuQpryMj3A9A2L++nvDaZXheqqrrXrVu3D0C5detWudPpxO/T" |
|
83 "Hk8HYnOD3J+8yr3bH6XnZNImHg3xfsgenfHo5QAyJwFAdnb2HiGEppmmWa3rOhtKrCcalNT9" |
|
84 "llTSwvBsXISn4nRdbJ5/czRsWvlGhQAEYtFg0kl2dnYZUKgB5U6nk5L82BMNXIU1X3uOWFH5" |
|
85 "eWIuy/YYWcjU4qQAxQ22bWMYhgfIU1RV/UrXdWaiDyOyUiLROktoJfDtC8fZfWQbb//v75ix" |
|
86 "MDlGnvjVC3+gflNDWiMQKPMalmVh2/a8w+HQFKAHIBR2ABCOS+uN6cTMoFstXmlwZbSba7tv" |
|
87 "8hfzT7z+7k+ZnZ0BoK5yR1qjCBV7MoVt29i2PaWqqq0BvUIIQqYORHlrKj6R9BoVj0b04oY9" |
|
88 "nEt+yvz3Y5yR/+Xap3XsDb/EtvV1aY1DdTA7HsW2bCKRyLiUclYBelRVldNWAfPSm4oV5ZQJ" |
|
89 "Vn/G9Zv2oWt6Ous7e4K81XiC1wNNBO6OIWKgB7Mwp000TYuFw+GxWCw2qbS2tk7k5uae/eDD" |
|
90 "Fn594p6SFyxRCjKLUBWF8fBoegTNMVLLm/kwdMyGGON/nePLklv0dl/Cii3gdrtvAzdg8aig" |
|
91 "vb296uDBgwMjIyMCwFvoZXv9NvRnIKqHSckUyQdJrtfexPqm5LGVAuNdVaofcCVywfpexLYD" |
|
92 "CsDOnTvnioqKzGXdzNQMV9tvkJEyUITyeOAjpYyAc9gxYc/GWyK2HYDF4xog6fV6h1i8FwCo" |
|
93 "LK/EncwhkWGxEH9AXLMXM2H1CpQBifI3yeapZ+70d43+cSo4+95yL23g8XiGFUWp3bVrV/Ty" |
|
94 "5ctZnR2ddHZ08uxzz1K9eT1GRhJls1gFlsfieK+WpJ5e/3z7pcuXzmia1rJSs3xlOg8dOvTD" |
|
95 "8fHx7wQCgb4tW7bMm6b55/Pnz+eGw+FFGJDT5iT1XRWlfxHMZ06+/Vz9dCAQeG9kZKR1x44d" |
|
96 "nSdPnkyuZSAArbq6eqOiKAP9/f3xlpaWgra2tlei0eiryWSyKGKa2TcaL+muwcxU5aDf9Gi+" |
|
97 "L0Oh0BehUOiaZVlnAoHAzFr7Ih75bVnVb2pqcvf09Phi0ei6+/rUC6lw1k0p5bSUctThcIwP" |
|
98 "Dw/HnwT4P6CDl+TMvD0JAAAAAElFTkSuQmCC") |
|
99 |
|
100 #---------------------------------------------------------------------- |
|
101 stopicon = PyEmbeddedImage( |
|
102 "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABPRJ" |
|
103 "REFUSImdlllsVGUUx3/f/e4sd5iZLjNt6XSFdtgkjWFRePABDaCBGgjamIg81CU0aoxbRHww" |
|
104 "+EDkhWjEB5rYGEMUxQTCJg8EoQ2BbgrFCNJWltplgC63naEzd+bO50NLLVAq4STfwz3nfP/f" |
|
105 "PSf3O98VSikmmQ94HFgDLDdNM1BfX5955swZX0tLi5FKpbSSkpJkaWlpIhQKdVdVVX2XkZFx" |
|
106 "EpBAEGgHLgH/iSqlUEoJpVSBUqpaKXXYNM0r1dXVt6WUajx5ylVYWKi2bdvWY1nWUaXUgQ0b" |
|
107 "NtRWVFQUjmuilEKMV5ALvAhsPHDgQFlNTU2gr69Pk1JSFMphTomfRXO8+A243i/oG9I5f6mX" |
|
108 "K1evAxAOhykrKxs9duyYkZ+f/0lPT8/2OwXogBtYDKzYunVr0c6dO3Ns26akMIcdbxQyv0hy" |
|
109 "rwmh8Bas5/eb89nxRR1NTU20t7cb4x1ZPjlXB2YBiw8ePJhdW1tb4DEMXng6xJtrPQhxn/Y4" |
|
110 "QSM12o89fJnOjst3hXRdLxZCGEqpUQANmBuJRLK3bNmy1OFwUPVMPm9VTiMOqLRNYvg6+shv" |
|
111 "rFoWwutxTcSklGEpZXDiXZRSr6xbt+6dtra2xUW5Lr7c7EUD3Flhwmu/nRKQGO7CvHaCwY7D" |
|
112 "WNEeEmoGe0+PWnuOXHWmrBTl5eW7GxsbNwPoFy5ccHV2di7yzjD4uMqDNtFngZDOKQHurDLc" |
|
113 "WWX4Qk/ScfRVXCLGoorU8J+z5gbjxyWGYbwshPhQKTWi7d+/P9/pdIp5xR5C2Q9uS1fDp3T+" |
|
114 "8jo32uomfJ7cCtzZYQCOjKhYOmgxI+hBSumdOXPmegDt4sWLxU6nk3BIf7A6EB/sIBY5R/+l" |
|
115 "nyd8yrZIRnvZ02tduxVwFQOojBQAfr9/tRBC103TLHe5XMwpSEwLKFj2EWk7gRGYOyaeTtJ4" |
|
116 "pnZk+7UhM5FtlAhAIMYAESd+v78IyNWBYqfTSUF2fFqAJ7firufhRFSdTg36rIDhQ6XHnAI0" |
|
117 "L1iWhWEYASBLl1L+JaWcfSuqk+u3AUikRer4ADffg/w7gt80fs35r34k3BYh2xNAarooAJ4d" |
|
118 "vsHgaP8EWMR17GiaVo8r0+Fw6DrQDDzXO+RgQSjBUFIlPh+wB0vLZD6TrLWrkWRXB29fGAK6" |
|
119 "pql1rNXVmrCklJYGtAgh6DXHDsuuG8k+O9M5895tq+atpSwwZ9o2TjZlWTGl1IAGNEsp1c1E" |
|
120 "DiMqmI7nZRQJ7j/G6xZWMS/vsYcGkEzG4vF4RDt06FBfZmbmwR/27uOD3f1aVk+BljMjD6lp" |
|
121 "/DN07a4VTYw8tL4rrQZgbNixadOm90+dOvX82cZmcbaxmWBukOVrlvJudw1R1xDp8a+kuPM6" |
|
122 "Gx8S4LXtCIwNO1asWDGYl5dn3gneunGLc7/+gTttoAntQRrTmgMmpimAHQwGOycnlBaX4rUz" |
|
123 "8LszMRweXLr7kWB35oMdCAT+1jRt0cqVK6Otra2+hvoGGuobWPLEEsoXzkbPkLhvR4CBRwJY" |
|
124 "Xq/3SGVlZbq7u7utsrJyxDTNz06cOJHZ0tRCS1MLAKuRwNQT9v8AyV27dn1fXl7eqmlae11d" |
|
125 "XXLfvn0/+Xy+l6LR6Gu2befFYjFfzrk2FzeHp7mK7jdxz2/LffGamhpvc3NzyLKsbFd3z1PG" |
|
126 "aHyBTKdjum0POGzbFAp7qo0xVOtJZdf/C/wRDnL5FYGSAAAAAElFTkSuQmCC") |
|
127 |
|
128 def usage(): |
27 def usage(): |
129 print """ |
28 print """ |
130 Usage of Beremiz PLC execution service :\n |
29 Usage of Beremiz PLC execution service :\n |
131 %s {[-n name] [-i ip] [-p port]|-h|--help} working_dir |
30 %s {[-n name] [-i ip] [-p port] [-x enabletaskbar]|-h|--help} working_dir |
132 -n - zeroconf service name |
31 -n - zeroconf service name |
133 -i - ip of interface to bind to (x.x.x.x) |
32 -i - ip of interface to bind to (x.x.x.x) |
134 -p - port number |
33 -p - port number |
135 -h - print this help text and quit |
34 -h - print this help text and quit |
|
35 -x - enable/disable wxTaskbarIcon (0:disable 1:enable) |
136 |
36 |
137 working_dir - directory where are stored PLC files |
37 working_dir - directory where are stored PLC files |
138 """%sys.argv[0] |
38 """%sys.argv[0] |
139 |
39 |
140 try: |
40 try: |
141 opts, args = getopt.getopt(sys.argv[1:], "i:p:n:h") |
41 opts, args = getopt.getopt(sys.argv[1:], "i:p:n:x:h") |
142 except getopt.GetoptError, err: |
42 except getopt.GetoptError, err: |
143 # print help information and exit: |
43 # print help information and exit: |
144 print str(err) # will print something like "option -a not recognized" |
44 print str(err) # will print something like "option -a not recognized" |
145 usage() |
45 usage() |
146 sys.exit(2) |
46 sys.exit(2) |
176 WorkingDir = args[0] |
80 WorkingDir = args[0] |
177 elif len(args) == 0: |
81 elif len(args) == 0: |
178 WorkingDir = os.getcwd() |
82 WorkingDir = os.getcwd() |
179 args=[WorkingDir] |
83 args=[WorkingDir] |
180 |
84 |
|
85 if enablewx: |
|
86 try: |
|
87 import wx, re |
|
88 from wx.lib.embeddedimage import PyEmbeddedImage |
|
89 from threading import Thread |
|
90 from types import * |
|
91 havewx = True |
|
92 except: |
|
93 havewx = False |
|
94 |
|
95 if havewx: |
|
96 defaulticon = PyEmbeddedImage( |
|
97 "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABc5J" |
|
98 "REFUSIl9lW1MW9cZx3/n2vf6BQO2MZiXGBISILCVUEUlitYpjaKpXZJ1XZZ2kzJVY9r6IeLD" |
|
99 "pGTaNG3KtGmNNGlbpW3VFhRp0l6aZCllpVUqtVNJtBFKE5QXLxCjpCYEY7DBr9hcm3vPPgQY" |
|
100 "IQmPdKR7/vd5/v/n5dxzhZSSNeYBOoGDQGcoFPINDAyUDQ0NOUdGRmyGYSiBQGCpoaGhuGnT" |
|
101 "psShQ4f6WltbewEBVAK3gCBgrjJKKZFSKlLKeillt5Ty40gkMnnw4MFFQG60ysrKZHd3dyoe" |
|
102 "j//bNM0Le/fuPd/e3r5lmRMpJWK5ghrgFeBIT09P4/Hjx73pdFo47HaaNlfRutnJru0OKsoE" |
|
103 "E3GVqaSNa6EUw1dvIKWkoqKCrVu3FoeHh9WamppfRiKRn6wUYAUcwE7g2e7u7vrTp09XGIZB" |
|
104 "W1Mdv3qtmoBPrG0hHVsMhKLj6nqOqOWn/Pjnv2dgYIC5uTl1uSM71/pbgUbg6bNnz/rPnDnj" |
|
105 "dzoddO0P8Oo+jY2suDDD1Zv9DA1dfghXVbVBCFEqpcwAKEDTxMSE58SJE8+oqsq3nq/l1X0a" |
|
106 "QihYtNLHLqRET03wuYp7fO9r26mpKlsVUBSl0W63V6/shZTyyIEDB344Njb21JYaG7/5bgkA" |
|
107 "Dm8zTS/+7bHZLy0mSN+7yNztt8nPjYHFwfvXDf1P70zZ0ok0LS0tZy9fvvxNAGswGFQnJyef" |
|
108 "KnM5+NHLzuUDsrFZ7R68zS/hrGon1PcNMPI0BIzs9tcCNvNfDqxW64uqqvqKxWJc6e3trVVV" |
|
109 "leaAk6ryJ5N/9tH3GXv7Je7/5xermN3diMPXCkDfgrkg3UU0txWLxeLw+/1fB1BGR0frbTYb" |
|
110 "TXWWDbNeysUoZKbIRIZBPviOzKU8ejLMHyPFcMprrweQ7iUAXC7XPiGEak2lUk02m42mWn1D" |
|
111 "gfrnTiKNIrbyzSAUjEKWCx+/Mf+HyELBrLBvBhAIKDdgGsrLy+sAv1UIUa1pGv7yxQ0FbGX1" |
|
112 "D+0LQmHW7fVavE5Mo/gAFCCcoOs6NpvNA7gVRVGCmqYRz1hXg7NFU39rjshawjcuvs4P+o/y" |
|
113 "24uvE1+I4VCdfGfXUb76+VdWfQQCkbJSKBQoFApJTdMsCvApQDSlAjCTN7I/y5CNllpq1wqE" |
|
114 "YmPciIzwwdi7BKevreK7Gp5dfbYoFoozJrquo+v6rMViWbQCV4QQzGTsQJY3kzIhvFpgfYte" |
|
115 "7jhCMp9kk7uep+ueWcWj6f8Xqioq8ck0xcIS6XT6vpRy3gqMqKpqRBfKLLNF1ZRV6YBiPDrw" |
|
116 "vduefwTL6hl6b74FgFVR0T4rJTU3jcvlymcymal8Ph+z9vf3p7u6uv5y/vz5bw994ld2fmUH" |
|
117 "7nYFRVG4Gb3Guv8FpmmQzCcIJ+5w8c5HRFL3UYRC+ZKX633j6LpObW3tDcMwrsODq4Jbt27V" |
|
118 "HT58+N7o6KgCYHfY2f2lXfi+6CJbnsAwjUeyXzFFKLgdHqb+mmL8xh22bduWmJycfHN2dvbX" |
|
119 "uVwuoQC0tbXlKisrYytBi/lFZsKzOErtTyQWCOxWO36ljvl/FLk+dJOSkhJTUZR35+fn+3K5" |
|
120 "XAIeXNcASz6fbxzwrxDYVQdqpARvs498IYchDUxpogiBVVFxqE7U/5Zx4c8fEo/FKS0tlR0d" |
|
121 "HZ8ODg6+l06nr6zwrAp4PJ6Qpmlf2L9/fywYDFaOXB0RI1dHaGpuoq29Fa1Uxe62YeZMInei" |
|
122 "jAY/IRqNAtDZ2blUV1fXPzg4+F5VVdU/H6p0eYjqsWPHvnz37t0XwuHw7d27d4eTyeTvLl26" |
|
123 "FJiamnpim6qrq9mzZ094fHz875FI5J3p6ekr631WBARgaWlpCezYsePeuXPnzFAo5Dp58uS+" |
|
124 "dDp91GKxNBYKBW82m3Vomqa7XK7pbDYbnJmZuR2LxYL5fP79WCyWeeys1h/D9e97enqsp06d" |
|
125 "8mWzWU+xWPTkcjmXaZpxwzDCsVhsbqNggP8BMJOU3UUUf+0AAAAASUVORK5CYII=") |
|
126 |
|
127 #---------------------------------------------------------------------- |
|
128 starticon = PyEmbeddedImage( |
|
129 "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABbpJ" |
|
130 "REFUSIl9lltsFNcdxn9nZnbHs15fd23j9TXYC0UCKzEhMQ+oIS2g1kQ1pbFStX0opFWsovSh" |
|
131 "rUqp2pS2ioTUolaKFOGHqGkiJcKRuDhOaZRiZCsCXyBgCBBfMfbu+oa9s17wzuzl9MH24mDD" |
|
132 "XzoPc/6fft+c72jOGSGlZEVlAU8D9cB20zQ9HR0duRcvXszq7e01EomEUlFREa+srLR8Pl+g" |
|
133 "sbHx3zk5ORcAFfACA8Bt4CFUSomUUkgpS6SUB6SUH5umOXLgwIEHqqrKJfGao7S0VB49ejRo" |
|
134 "2/YnUsrT+/fvb66pqSldYiKlRCytoBB4Gfjx6dOnq5qamjwTExOKqqqU+QrYUJFN7QY32Qbc" |
|
135 "vSeYCGtcux1i5M5dAPx+P1VVVQvnzp0ziouLfx8MBt9cXoAGZABbgZ1HjhwpO378eEEymaSi" |
|
136 "tIBjPy9lU5nKoyWExF2yjy+mN3HsH+/Q3d3NwMCAsZTI9pVaDXgK2Hr27Nn85ubmEpdh8IMX" |
|
137 "ffxirwshVrGXHBQSC/dIRvoZGuz/WkvTtHIhhCGlXABQgI2Tk5P5hw8f3uZwOGj8VjGHXnoC" |
|
138 "HJCpJFbkLtr8FXbX+XC79HRPVVW/qqre9LtIKX/S0NDwy76+vq1lhTr/fM2NAmTk+fHv/dea" |
|
139 "BlZkDHP0PHODH2NHg1gykw8/X7Dfb7vjTNgJqqurT3R1db0GoF2/fl0fGhqqdWca/K7RhZLO" |
|
140 "WSBU55oGGXlVZORVkeV7nsFPDqKL+9TWJCI3n9rojX2mYhjGj4QQv5FSziunTp0qdjqd4hvl" |
|
141 "Lnz5j49lrPMNhv7zM6b63knPuQpryMj3A9A2L++nvDaZXheqqrrXrVu3D0C5detWudPpxO/T" |
|
142 "Hk8HYnOD3J+8yr3bH6XnZNImHg3xfsgenfHo5QAyJwFAdnb2HiGEppmmWa3rOhtKrCcalNT9" |
|
143 "llTSwvBsXISn4nRdbJ5/czRsWvlGhQAEYtFg0kl2dnYZUKgB5U6nk5L82BMNXIU1X3uOWFH5" |
|
144 "eWIuy/YYWcjU4qQAxQ22bWMYhgfIU1RV/UrXdWaiDyOyUiLROktoJfDtC8fZfWQbb//v75ix" |
|
145 "MDlGnvjVC3+gflNDWiMQKPMalmVh2/a8w+HQFKAHIBR2ABCOS+uN6cTMoFstXmlwZbSba7tv" |
|
146 "8hfzT7z+7k+ZnZ0BoK5yR1qjCBV7MoVt29i2PaWqqq0BvUIIQqYORHlrKj6R9BoVj0b04oY9" |
|
147 "nEt+yvz3Y5yR/+Xap3XsDb/EtvV1aY1DdTA7HsW2bCKRyLiUclYBelRVldNWAfPSm4oV5ZQJ" |
|
148 "Vn/G9Zv2oWt6Ous7e4K81XiC1wNNBO6OIWKgB7Mwp000TYuFw+GxWCw2qbS2tk7k5uae/eDD" |
|
149 "Fn594p6SFyxRCjKLUBWF8fBoegTNMVLLm/kwdMyGGON/nePLklv0dl/Cii3gdrtvAzdg8aig" |
|
150 "vb296uDBgwMjIyMCwFvoZXv9NvRnIKqHSckUyQdJrtfexPqm5LGVAuNdVaofcCVywfpexLYD" |
|
151 "CsDOnTvnioqKzGXdzNQMV9tvkJEyUITyeOAjpYyAc9gxYc/GWyK2HYDF4xog6fV6h1i8FwCo" |
|
152 "LK/EncwhkWGxEH9AXLMXM2H1CpQBifI3yeapZ+70d43+cSo4+95yL23g8XiGFUWp3bVrV/Ty" |
|
153 "5ctZnR2ddHZ08uxzz1K9eT1GRhJls1gFlsfieK+WpJ5e/3z7pcuXzmia1rJSs3xlOg8dOvTD" |
|
154 "8fHx7wQCgb4tW7bMm6b55/Pnz+eGw+FFGJDT5iT1XRWlfxHMZ06+/Vz9dCAQeG9kZKR1x44d" |
|
155 "nSdPnkyuZSAArbq6eqOiKAP9/f3xlpaWgra2tlei0eiryWSyKGKa2TcaL+muwcxU5aDf9Gi+" |
|
156 "L0Oh0BehUOiaZVlnAoHAzFr7Ih75bVnVb2pqcvf09Phi0ei6+/rUC6lw1k0p5bSUctThcIwP" |
|
157 "Dw/HnwT4P6CDl+TMvD0JAAAAAElFTkSuQmCC") |
|
158 |
|
159 #---------------------------------------------------------------------- |
|
160 stopicon = PyEmbeddedImage( |
|
161 "iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAABPRJ" |
|
162 "REFUSImdlllsVGUUx3/f/e4sd5iZLjNt6XSFdtgkjWFRePABDaCBGgjamIg81CU0aoxbRHww" |
|
163 "+EDkhWjEB5rYGEMUxQTCJg8EoQ2BbgrFCNJWltplgC63naEzd+bO50NLLVAq4STfwz3nfP/f" |
|
164 "PSf3O98VSikmmQ94HFgDLDdNM1BfX5955swZX0tLi5FKpbSSkpJkaWlpIhQKdVdVVX2XkZFx" |
|
165 "EpBAEGgHLgH/iSqlUEoJpVSBUqpaKXXYNM0r1dXVt6WUajx5ylVYWKi2bdvWY1nWUaXUgQ0b" |
|
166 "NtRWVFQUjmuilEKMV5ALvAhsPHDgQFlNTU2gr69Pk1JSFMphTomfRXO8+A243i/oG9I5f6mX" |
|
167 "K1evAxAOhykrKxs9duyYkZ+f/0lPT8/2OwXogBtYDKzYunVr0c6dO3Ns26akMIcdbxQyv0hy" |
|
168 "rwmh8Bas5/eb89nxRR1NTU20t7cb4x1ZPjlXB2YBiw8ePJhdW1tb4DEMXng6xJtrPQhxn/Y4" |
|
169 "QSM12o89fJnOjst3hXRdLxZCGEqpUQANmBuJRLK3bNmy1OFwUPVMPm9VTiMOqLRNYvg6+shv" |
|
170 "rFoWwutxTcSklGEpZXDiXZRSr6xbt+6dtra2xUW5Lr7c7EUD3Flhwmu/nRKQGO7CvHaCwY7D" |
|
171 "WNEeEmoGe0+PWnuOXHWmrBTl5eW7GxsbNwPoFy5ccHV2di7yzjD4uMqDNtFngZDOKQHurDLc" |
|
172 "WWX4Qk/ScfRVXCLGoorU8J+z5gbjxyWGYbwshPhQKTWi7d+/P9/pdIp5xR5C2Q9uS1fDp3T+" |
|
173 "8jo32uomfJ7cCtzZYQCOjKhYOmgxI+hBSumdOXPmegDt4sWLxU6nk3BIf7A6EB/sIBY5R/+l" |
|
174 "nyd8yrZIRnvZ02tduxVwFQOojBQAfr9/tRBC103TLHe5XMwpSEwLKFj2EWk7gRGYOyaeTtJ4" |
|
175 "pnZk+7UhM5FtlAhAIMYAESd+v78IyNWBYqfTSUF2fFqAJ7firufhRFSdTg36rIDhQ6XHnAI0" |
|
176 "L1iWhWEYASBLl1L+JaWcfSuqk+u3AUikRer4ADffg/w7gt80fs35r34k3BYh2xNAarooAJ4d" |
|
177 "vsHgaP8EWMR17GiaVo8r0+Fw6DrQDDzXO+RgQSjBUFIlPh+wB0vLZD6TrLWrkWRXB29fGAK6" |
|
178 "pql1rNXVmrCklJYGtAgh6DXHDsuuG8k+O9M5895tq+atpSwwZ9o2TjZlWTGl1IAGNEsp1c1E" |
|
179 "DiMqmI7nZRQJ7j/G6xZWMS/vsYcGkEzG4vF4RDt06FBfZmbmwR/27uOD3f1aVk+BljMjD6lp" |
|
180 "/DN07a4VTYw8tL4rrQZgbNixadOm90+dOvX82cZmcbaxmWBukOVrlvJudw1R1xDp8a+kuPM6" |
|
181 "Gx8S4LXtCIwNO1asWDGYl5dn3gneunGLc7/+gTttoAntQRrTmgMmpimAHQwGOycnlBaX4rUz" |
|
182 "8LszMRweXLr7kWB35oMdCAT+1jRt0cqVK6Otra2+hvoGGuobWPLEEsoXzkbPkLhvR4CBRwJY" |
|
183 "Xq/3SGVlZbq7u7utsrJyxDTNz06cOJHZ0tRCS1MLAKuRwNQT9v8AyV27dn1fXl7eqmlae11d" |
|
184 "XXLfvn0/+Xy+l6LR6Gu2befFYjFfzrk2FzeHp7mK7jdxz2/LffGamhpvc3NzyLKsbFd3z1PG" |
|
185 "aHyBTKdjum0POGzbFAp7qo0xVOtJZdf/C/wRDnL5FYGSAAAAAElFTkSuQmCC") |
|
186 |
|
187 class ParamsEntryDialog(wx.TextEntryDialog): |
|
188 if wx.VERSION < (2, 6, 0): |
|
189 def Bind(self, event, function, id = None): |
|
190 if id is not None: |
|
191 event(self, id, function) |
|
192 else: |
|
193 event(self, function) |
|
194 |
|
195 |
|
196 def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", |
|
197 style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): |
|
198 wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) |
|
199 |
|
200 self.Tests = [] |
|
201 if wx.VERSION >= (2, 8, 0): |
|
202 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId()) |
|
203 elif wx.VERSION >= (2, 6, 0): |
|
204 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) |
|
205 else: |
|
206 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) |
|
207 |
|
208 def OnOK(self, event): |
|
209 value = self.GetValue() |
|
210 texts = {"value" : value} |
|
211 for function, message in self.Tests: |
|
212 if not function(value): |
|
213 message = wx.MessageDialog(self, message%texts, "Error", wx.OK|wx.ICON_ERROR) |
|
214 message.ShowModal() |
|
215 message.Destroy() |
|
216 return |
|
217 self.EndModal(wx.ID_OK) |
|
218 |
|
219 def GetValue(self): |
|
220 return self.GetSizer().GetItem(1).GetWindow().GetValue() |
|
221 |
|
222 def SetTests(self, tests): |
|
223 self.Tests = tests |
|
224 |
|
225 class DemoTaskBarIcon(wx.TaskBarIcon): |
|
226 TBMENU_CHANGE_NAME = wx.NewId() |
|
227 TBMENU_CHANGE_PORT = wx.NewId() |
|
228 TBMENU_CHANGE_INTERFACE = wx.NewId() |
|
229 TBMENU_CHANGE_WD = wx.NewId() |
|
230 TBMENU_QUIT = wx.NewId() |
|
231 |
|
232 def __init__(self, pyroserver): |
|
233 wx.TaskBarIcon.__init__(self) |
|
234 # Set the image |
|
235 self.UpdateIcon(None) |
|
236 |
|
237 # bind some events |
|
238 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeName, id=self.TBMENU_CHANGE_NAME) |
|
239 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeInterface, id=self.TBMENU_CHANGE_INTERFACE) |
|
240 self.Bind(wx.EVT_MENU, self.OnTaskBarChangePort, id=self.TBMENU_CHANGE_PORT) |
|
241 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeWorkingDir, id=self.TBMENU_CHANGE_WD) |
|
242 self.Bind(wx.EVT_MENU, self.OnTaskBarQuit, id=self.TBMENU_QUIT) |
|
243 |
|
244 def CreatePopupMenu(self): |
|
245 """ |
|
246 This method is called by the base class when it needs to popup |
|
247 the menu for the default EVT_RIGHT_DOWN event. Just create |
|
248 the menu how you want it and return it from this function, |
|
249 the base class takes care of the rest. |
|
250 """ |
|
251 menu = wx.Menu() |
|
252 menu.Append(self.TBMENU_CHANGE_NAME, "Change Name") |
|
253 menu.Append(self.TBMENU_CHANGE_INTERFACE, "Change IP of interface to bind") |
|
254 menu.Append(self.TBMENU_CHANGE_PORT, "Change Port Number") |
|
255 menu.AppendSeparator() |
|
256 menu.Append(self.TBMENU_CHANGE_WD, "Change working directory") |
|
257 menu.Append(self.TBMENU_QUIT, "Quit") |
|
258 return menu |
|
259 |
|
260 def MakeIcon(self, img): |
|
261 """ |
|
262 The various platforms have different requirements for the |
|
263 icon size... |
|
264 """ |
|
265 if "wxMSW" in wx.PlatformInfo: |
|
266 img = img.Scale(16, 16) |
|
267 elif "wxGTK" in wx.PlatformInfo: |
|
268 img = img.Scale(22, 22) |
|
269 # wxMac can be any size upto 128x128, so leave the source img alone.... |
|
270 icon = wx.IconFromBitmap(img.ConvertToBitmap() ) |
|
271 return icon |
|
272 |
|
273 def OnTaskBarChangeInterface(self,evt): |
|
274 dlg = ParamsEntryDialog(None, "Enter the ip of the interface to bind", defaultValue=pyroserver.ip) |
|
275 dlg.SetTests([(re.compile('\d{1,3}(?:\.\d{1,3}){3}$').match, "Ip is not valid!"), |
|
276 ( lambda ip :len([x for x in ip.split(".") if 0 <= int(x) <= 255]) == 4, "Ip is not valid!") |
|
277 ]) |
|
278 if dlg.ShowModal() == wx.ID_OK: |
|
279 pyroserver.ip = dlg.GetValue() |
|
280 pyroserver.Stop() |
|
281 |
|
282 def OnTaskBarChangePort(self,evt): |
|
283 dlg = ParamsEntryDialog(None, "Enter a port number ", defaultValue=str(pyroserver.port)) |
|
284 dlg.SetTests([(UnicodeType.isdigit, "Port number must be an integer!"), (lambda port : 0 <= int(port) <= 65535 , "Port number must be 0 <= port <= 65535!")]) |
|
285 if dlg.ShowModal() == wx.ID_OK: |
|
286 pyroserver.port = int(dlg.GetValue()) |
|
287 pyroserver.Stop() |
|
288 |
|
289 |
|
290 def OnTaskBarChangeWorkingDir(self,evt): |
|
291 dlg = wx.DirDialog(None, "Choose a working directory ", pyroserver.workdir, wx.DD_NEW_DIR_BUTTON) |
|
292 if dlg.ShowModal() == wx.ID_OK: |
|
293 pyroserver.workdir = dlg.GetPath() |
|
294 pyroserver.Stop() |
|
295 |
|
296 def OnTaskBarChangeName(self,evt): |
|
297 dlg = ParamsEntryDialog(None, "Enter a name ", defaultValue=pyroserver.name) |
|
298 dlg.SetTests([(lambda name : len(name) is not 0 , "Name must not be null!")]) |
|
299 if dlg.ShowModal() == wx.ID_OK: |
|
300 pyroserver.name = dlg.GetValue() |
|
301 pyroserver.Restart() |
|
302 |
|
303 def OnTaskBarQuit(self,evt): |
|
304 pyroserver.Quit() |
|
305 self.RemoveIcon() |
|
306 wx.GetApp().ExitMainLoop() |
|
307 |
|
308 def UpdateIcon(self, plcstatus): |
|
309 if plcstatus is "Started" : |
|
310 currenticon = self.MakeIcon(starticon.GetImage()) |
|
311 elif plcstatus is "Stopped": |
|
312 currenticon = self.MakeIcon(stopicon.GetImage()) |
|
313 else: |
|
314 currenticon = self.MakeIcon(defaulticon.GetImage()) |
|
315 self.SetIcon(currenticon, "Beremiz Service") |
|
316 |
181 from runtime import PLCObject, ServicePublisher |
317 from runtime import PLCObject, ServicePublisher |
182 import Pyro.core as pyro |
318 import Pyro.core as pyro |
183 |
319 |
184 if not os.path.isdir(WorkingDir): |
320 if not os.path.isdir(WorkingDir): |
185 os.mkdir(WorkingDir) |
321 os.mkdir(WorkingDir) |
186 |
|
187 |
|
188 |
322 |
189 class Server(): |
323 class Server(): |
190 def __init__(self, name, ip, port, workdir, args): |
324 def __init__(self, name, ip, port, workdir, args): |
191 self.continueloop = True |
325 self.continueloop = True |
192 self.daemon = None |
326 self.daemon = None |
235 def Stop(self): |
369 def Stop(self): |
236 if self.servicepublisher is not None: |
370 if self.servicepublisher is not None: |
237 self.servicepublisher.UnRegisterService() |
371 self.servicepublisher.UnRegisterService() |
238 del self.servicepublisher |
372 del self.servicepublisher |
239 self.daemon.shutdown(True) |
373 self.daemon.shutdown(True) |
240 |
|
241 class ParamsEntryDialog(wx.TextEntryDialog): |
|
242 if wx.VERSION < (2, 6, 0): |
|
243 def Bind(self, event, function, id = None): |
|
244 if id is not None: |
|
245 event(self, id, function) |
|
246 else: |
|
247 event(self, function) |
|
248 |
|
249 |
|
250 def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", |
|
251 style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition): |
|
252 wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos) |
|
253 |
|
254 self.Tests = [] |
|
255 if wx.VERSION >= (2, 8, 0): |
|
256 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetAffirmativeId()) |
|
257 elif wx.VERSION >= (2, 6, 0): |
|
258 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId()) |
|
259 else: |
|
260 self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetChildren()[0].GetSizer().GetChildren()[0].GetWindow().GetId()) |
|
261 |
|
262 def OnOK(self, event): |
|
263 value = self.GetValue() |
|
264 texts = {"value" : value} |
|
265 for function, message in self.Tests: |
|
266 if not function(value): |
|
267 message = wx.MessageDialog(self, message%texts, "Error", wx.OK|wx.ICON_ERROR) |
|
268 message.ShowModal() |
|
269 message.Destroy() |
|
270 return |
|
271 self.EndModal(wx.ID_OK) |
|
272 |
|
273 def GetValue(self): |
|
274 return self.GetSizer().GetItem(1).GetWindow().GetValue() |
|
275 |
|
276 def SetTests(self, tests): |
|
277 self.Tests = tests |
|
278 |
|
279 class DemoTaskBarIcon(wx.TaskBarIcon): |
|
280 TBMENU_CHANGE_NAME = wx.NewId() |
|
281 TBMENU_CHANGE_PORT = wx.NewId() |
|
282 TBMENU_CHANGE_INTERFACE = wx.NewId() |
|
283 TBMENU_CHANGE_WD = wx.NewId() |
|
284 TBMENU_QUIT = wx.NewId() |
|
285 |
|
286 def __init__(self, pyroserver): |
|
287 wx.TaskBarIcon.__init__(self) |
|
288 # Set the image |
|
289 self.UpdateIcon(None) |
|
290 |
|
291 # bind some events |
|
292 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeName, id=self.TBMENU_CHANGE_NAME) |
|
293 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeInterface, id=self.TBMENU_CHANGE_INTERFACE) |
|
294 self.Bind(wx.EVT_MENU, self.OnTaskBarChangePort, id=self.TBMENU_CHANGE_PORT) |
|
295 self.Bind(wx.EVT_MENU, self.OnTaskBarChangeWorkingDir, id=self.TBMENU_CHANGE_WD) |
|
296 self.Bind(wx.EVT_MENU, self.OnTaskBarQuit, id=self.TBMENU_QUIT) |
|
297 |
|
298 def CreatePopupMenu(self): |
|
299 """ |
|
300 This method is called by the base class when it needs to popup |
|
301 the menu for the default EVT_RIGHT_DOWN event. Just create |
|
302 the menu how you want it and return it from this function, |
|
303 the base class takes care of the rest. |
|
304 """ |
|
305 menu = wx.Menu() |
|
306 menu.Append(self.TBMENU_CHANGE_NAME, "Change Name") |
|
307 menu.Append(self.TBMENU_CHANGE_INTERFACE, "Change IP of interface to bind") |
|
308 menu.Append(self.TBMENU_CHANGE_PORT, "Change Port Number") |
|
309 menu.AppendSeparator() |
|
310 menu.Append(self.TBMENU_CHANGE_WD, "Change working directory") |
|
311 menu.Append(self.TBMENU_QUIT, "Quit") |
|
312 return menu |
|
313 |
|
314 def MakeIcon(self, img): |
|
315 """ |
|
316 The various platforms have different requirements for the |
|
317 icon size... |
|
318 """ |
|
319 if "wxMSW" in wx.PlatformInfo: |
|
320 img = img.Scale(16, 16) |
|
321 elif "wxGTK" in wx.PlatformInfo: |
|
322 img = img.Scale(22, 22) |
|
323 # wxMac can be any size upto 128x128, so leave the source img alone.... |
|
324 icon = wx.IconFromBitmap(img.ConvertToBitmap() ) |
|
325 return icon |
|
326 |
|
327 def OnTaskBarChangeInterface(self,evt): |
|
328 dlg = ParamsEntryDialog(None, "Enter the ip of the interface to bind", defaultValue=pyroserver.ip) |
|
329 dlg.SetTests([(re.compile('\d{1,3}(?:\.\d{1,3}){3}$').match, "Ip is not valid!"), |
|
330 ( lambda ip :len([x for x in ip.split(".") if 0 <= int(x) <= 255]) == 4, "Ip is not valid!") |
|
331 ]) |
|
332 if dlg.ShowModal() == wx.ID_OK: |
|
333 pyroserver.ip = dlg.GetValue() |
|
334 pyroserver.Stop() |
|
335 |
|
336 def OnTaskBarChangePort(self,evt): |
|
337 dlg = ParamsEntryDialog(None, "Enter a port number ", defaultValue=str(pyroserver.port)) |
|
338 dlg.SetTests([(UnicodeType.isdigit, "Port number must be an integer!"), (lambda port : 0 <= int(port) <= 65535 , "Port number must be 0 <= port <= 65535!")]) |
|
339 if dlg.ShowModal() == wx.ID_OK: |
|
340 pyroserver.port = int(dlg.GetValue()) |
|
341 pyroserver.Stop() |
|
342 |
|
343 |
|
344 def OnTaskBarChangeWorkingDir(self,evt): |
|
345 dlg = wx.DirDialog(None, "Choose a working directory ", pyroserver.workdir, wx.DD_NEW_DIR_BUTTON) |
|
346 if dlg.ShowModal() == wx.ID_OK: |
|
347 pyroserver.workdir = dlg.GetPath() |
|
348 pyroserver.Stop() |
|
349 |
|
350 def OnTaskBarChangeName(self,evt): |
|
351 dlg = ParamsEntryDialog(None, "Enter a name ", defaultValue=pyroserver.name) |
|
352 dlg.SetTests([(lambda name : len(name) is not 0 , "Name must not be null!")]) |
|
353 if dlg.ShowModal() == wx.ID_OK: |
|
354 pyroserver.name = dlg.GetValue() |
|
355 pyroserver.Restart() |
|
356 |
|
357 def OnTaskBarQuit(self,evt): |
|
358 pyroserver.Quit() |
|
359 self.RemoveIcon() |
|
360 wx.GetApp().ExitMainLoop() |
|
361 |
|
362 def UpdateIcon(self, plcstatus): |
|
363 if plcstatus is "Started" : |
|
364 currenticon = self.MakeIcon(starticon.GetImage()) |
|
365 elif plcstatus is "Stopped": |
|
366 currenticon = self.MakeIcon(stopicon.GetImage()) |
|
367 else: |
|
368 currenticon = self.MakeIcon(defaulticon.GetImage()) |
|
369 self.SetIcon(currenticon, "Beremiz Service") |
|
370 |
374 |
371 pyroserver = Server(name, ip, port, WorkingDir, args) |
375 pyroserver = Server(name, ip, port, WorkingDir, args) |
372 |
376 |
373 if havewx: |
377 if havewx: |
374 app=wx.App(redirect=False) |
378 app=wx.App(redirect=False) |