Hello, here it is (the application makes a connection to a siemens plc and reads some data
thanks for your help
--main code ---
import sys, time
from PyQt5.QtWidgets import QApplication
from utils import config
from ui import appWindow
from threading import Thread
def main():
app=QApplication(sys.argv)
app.aboutToQuit.connect(myExit)
cfg = config()
cfg.log('application starts')
if not cfg.configFile():
myExit()
window = appWindow()
window.setupFonts()
window.show()
t = Thread(target=window.work, args=(cfg.plcIp,))
t.start()
sys.exit(app.exec_())
def myExit():
print ('closing ...')
try:
appWindow.stopComms = True
except:
pass
time.sleep (3)
if __name__ == "__main__":
main()
-- file ui.py --- I suspect the problem is here.
from PyQt5.QtWidgets import QWidget
from design import Ui_Form
from PyQt5.QtGui import QFont
from PyQt5 import QtCore
from S7talk import *
import time, os, sys
class appWindow(QWidget, Ui_Form):
stopComms = False
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle('Monitor')
def setupFonts(self):
try:
self.setStyleSheet('background-color:black') # window background color
font1=QFont('Arial', 20, QFont.Light)
font2=QFont('Arial', 50, QFont.Light)
font3=QFont('Arial', 70, QFont.Light)
font4=QFont('Arial', 80, QFont.Light)
self.lblTagOk.setFont(font3)
self.lblTagNok.setFont(font3)
self.lblTagTempoMedio.setFont(font3)
self.lblTagOk.setStyleSheet('color:white')
self.lblTagNok.setStyleSheet('color:white')
self.lblTagTempoMedio.setStyleSheet('color:white')
self.lblOk.setFont(font4)
self.lblNok.setFont(font4)
self.lblTempoMedio.setFont(font4)
self.lblInfo.setFont(font1)
self.lblOk.setStyleSheet('color:green')
self.lblNok.setStyleSheet('color:red')
self.lblTempoMedio.setStyleSheet('color:blue')
self.lblInfo.setStyleSheet('color:white')
self.lblTagTempoMedio.setText("T.Med:")
self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowTitleHint | QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowCloseButtonHint)
except:
print ('error:' + sys.exc_info()[0])
def work(self, ip):
statusOK = 255
statusShutdown = 1
statusRestart = 2
statusReconnect = 0
plc = S7ToPy()
self.ip = ip
try:
if plc.connectToS7(self.ip):
doWork = True
else:
doWork = False
except:
doWork = False
plc.status = statusOK
while not appWindow.stopComms:
try:
self.lblInfo.setText('')
time.sleep(0.3)
if not doWork: # or plc.status == statusReconnect:
try:
if plc.connectToS7(self.ip):
doWork = True
else:
if plc.s7IsConnected(): plc.pcClient.disconnect()
self.errorComms('PLC Connection FAILED')
print('PLC Connection FAILED')
doWork = False
except:
if plc.s7IsConnected(): plc.pcClient.disconnect()
self.errorComms('PLC Connection FAILED')
print('PLC Connection FAILED')
doWork = False
# caso esteja tudo bem
if doWork:
if plc.readFromS7():
if plc.status == statusShutdown:
os.system('sudo halt')
print('halt')
break
if plc.status == statusRestart:
os.system('sudo reboot')
print('reboot')
break
# atualiza os resultados
self.lblOk.setText(str(plc.valueOk))
self.lblNok.setText(str(plc.valueNok))
self.lblTempoMedio.setText(str(plc.valueTempoMedio))
bits = int(plc._semafores)
self.setWindowTitle(str(bits) + ' --- ' + str(plc.valueOk))
if bits == 1:
self.lblSemaforeVerde.setVisible(True)
self.lblSemaforeAmarelo.setVisible(False)
self.lblSemaforeVermelho.setVisible(False)
elif bits == 2:
self.lblSemaforeVerde.setVisible(False)
self.lblSemaforeAmarelo.setVisible(True)
self.lblSemaforeVermelho.setVisible(False)
elif bits == 4:
self.lblSemaforeVerde.setVisible(False)
self.lblSemaforeAmarelo.setVisible(False)
self.lblSemaforeVermelho.setVisible(True)
else:
self.lblSemaforeVerde.setVisible(False)
self.lblSemaforeAmarelo.setVisible(False)
self.lblSemaforeVermelho.setVisible(False)
self.lblInfo.setText('PLC Connection OK')
self.lblInfo.setStyleSheet("color:green")
else:
if plc.s7IsConnected(): plc.pcClient.disconnect()
self.errorComms('Error reading PLC')
print('Error reading PLC')
if plc.s7IsConnected(): plc.pcClient.disconnect()
doWork = False
else:
time.sleep(0.3)
time.sleep(0.3)
except:
print ('error:' + sys.exc_info()[0])
def errorComms(self, msg):
self.lblInfo.setText(msg)
self.lblInfo.setStyleSheet('color:red')
time.sleep(1)
-- utils.py
import sys, os
from pathlib import Path
import datetime
class config:
def __init__(self):
self._plcIpAddress = ''
""" properties """
@property
def plcIp(self):
return self._plcIpAddress
@plcIp.setter
def plcIp(self, value):
self._plcIpAddress = value
""" writes in the log file """
def log (self, text):
pathname = os.path.dirname(sys.argv[0])
my_file = Path(pathname + "/log.txt")
now = datetime.datetime.now()
strText = now.strftime("%Y-%m-%d %H:%M:%S") + " -> " + text + "\n"
try:
if my_file.exists():
size = my_file.stat().st_size
if size > 32000:
my_file.open('w').write(strText)
else:
my_file.open('a').write(strText)
else:
my_file.write_text(strText)
except:
ex = str(sys.exc_info()[0])
""" application quits """
def bye(self):
self.log ('quiting')
""" read configuration file """
def configFile(self):
pathname = os.path.dirname(sys.argv[0])
my_file = Path(pathname + "/config.txt")
try:
if not my_file.exists():
return False
txt = my_file.read_text()
lines = txt.splitlines()
self.plcIp = lines[0]
if len(self.plcIp.split('.')) != 4:
self.log ("error -> wrong ip address" + '\n')
return False
return True
except:
ex = str(sys.exc_info()[0])
return False
-- S7talk.py
"""comms with plc
/*
* int16 - OK -> bytes 0 e 1
* int16 - NOK -> bytes 2 e 3
* int16 - Semafores -> bytes 4 e 5
* int32 - Tempo medio -> bytes 6, 7, 8 e 9
* byte - status -> byte 10
* 255 - tudo ok
* 0 - shutdown me
*/
"""
from snap7 import client
from struct import unpack
class S7ToPy:
def __init__(self):
self._ok = 0
self._nok = 0
self._tempo = 0
self._st = 0
self._semafores = 0
self._bytesToRead = 11
self.pcClient = client.Client()
""" properties """
@property
def valueOk(self):
return self._ok
@valueOk.setter
def valueOk(self, value):
self._ok = value
@property
def valueNok(self):
return self._nok
@valueNok.setter
def valueNok(self, value):
self._nok = value
@property
def valueTempoMedio(self):
return self._tempo
@valueTempoMedio.setter
def valueTempoMedio(self, value):
self._tempo = value
@property
def valueSemafores(self):
return self._semafores
@valueSemafores.setter
def valueSemafores(self, value):
self._semafores = value
@property
def status(self):
return self._st
@status.setter
def status(self, value):
self._st = value
def s7IsConnected(self):
return self.pcClient.get_connected()
def connectToS7 (self, ip):
try:
self.pcClient.connect(ip,0,1)
if self.pcClient.get_connected():
return True
else:
return False
except: return False
def readFromS7(self):
buf = []
try:
buf = self.pcClient.db_read(100,0,self._bytesToRead)
self.valueOk = buf[0] * 256
self.valueOk += buf[1]
#print (buf)
self.valueNok = buf [2] * 256
self.valueNok += buf[3]
self.valueSemafores = buf[4] * 256
self.valueSemafores += buf[5]
hexbytes = buf[6:10]
floatValue = (unpack(">f", hexbytes))[0] # big endian
floatValue = round(floatValue,1)
self.valueTempoMedio = str(floatValue)
self.valueTempoMedio = self.valueTempoMedio.replace('.', ',') + ' (s)'
self.status = buf[10]
return True
except:
return False
--design.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'design.ui'
#
# Created by: PyQt5 UI code generator 5.5.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(909, 571)
self.verticalLayout_4 = QtWidgets.QVBoxLayout(Form)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.lblTagOk = QtWidgets.QLabel(Form)
self.lblTagOk.setObjectName("lblTagOk")
self.horizontalLayout.addWidget(self.lblTagOk)
self.lblOk = QtWidgets.QLabel(Form)
self.lblOk.setAlignment(QtCore.Qt.AlignCenter)
self.lblOk.setObjectName("lblOk")
self.horizontalLayout.addWidget(self.lblOk)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.lblTagNok = QtWidgets.QLabel(Form)
self.lblTagNok.setObjectName("lblTagNok")
self.horizontalLayout_2.addWidget(self.lblTagNok)
self.lblNok = QtWidgets.QLabel(Form)
self.lblNok.setAlignment(QtCore.Qt.AlignCenter)
self.lblNok.setObjectName("lblNok")
self.horizontalLayout_2.addWidget(self.lblNok)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.lblTagTempoMedio = QtWidgets.QLabel(Form)
self.lblTagTempoMedio.setObjectName("lblTagTempoMedio")
self.horizontalLayout_3.addWidget(self.lblTagTempoMedio)
self.lblTempoMedio = QtWidgets.QLabel(Form)
self.lblTempoMedio.setAlignment(QtCore.Qt.AlignCenter)
self.lblTempoMedio.setObjectName("lblTempoMedio")
self.horizontalLayout_3.addWidget(self.lblTempoMedio)
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
self.horizontalLayout_4.addLayout(self.verticalLayout_2)
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.lblSemaforeVermelho = QtWidgets.QLabel(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lblSemaforeVermelho.sizePolicy().hasHeightForWidth())
self.lblSemaforeVermelho.setSizePolicy(sizePolicy)
self.lblSemaforeVermelho.setStyleSheet("border-color: rgb(0, 0, 0);\n"
"border-width: 3px; \n"
"border-style: solid;\n"
"border-radius: 40px;\n"
"margin:20px;\n"
"padding:30px;\n"
"background-color: red;\n"
"")
self.lblSemaforeVermelho.setObjectName("lblSemaforeVermelho")
self.verticalLayout_3.addWidget(self.lblSemaforeVermelho)
self.lblSemaforeAmarelo = QtWidgets.QLabel(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lblSemaforeAmarelo.sizePolicy().hasHeightForWidth())
self.lblSemaforeAmarelo.setSizePolicy(sizePolicy)
self.lblSemaforeAmarelo.setStyleSheet("border-color: rgb(0, 0, 0);\n"
"border-width: 3px; \n"
"border-style: solid;\n"
"border-radius: 40px;\n"
"margin:20px;\n"
"padding:30px;\n"
"background-color: yellow;\n"
"")
self.lblSemaforeAmarelo.setObjectName("lblSemaforeAmarelo")
self.verticalLayout_3.addWidget(self.lblSemaforeAmarelo)
self.lblSemaforeVerde = QtWidgets.QLabel(Form)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lblSemaforeVerde.sizePolicy().hasHeightForWidth())
self.lblSemaforeVerde.setSizePolicy(sizePolicy)
self.lblSemaforeVerde.setStyleSheet("border-color: rgb(0, 0, 0);\n"
"border-width: 3px; \n"
"border-style: solid;\n"
"border-radius: 40px;\n"
"margin:20px;\n"
"padding:30px;"
"background-color: green;")
self.lblSemaforeVerde.setObjectName("lblSemaforeVerde")
self.verticalLayout_3.addWidget(self.lblSemaforeVerde)
self.horizontalLayout_4.addLayout(self.verticalLayout_3)
self.verticalLayout_4.addLayout(self.horizontalLayout_4)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_4.addItem(spacerItem)
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.lblInfo = QtWidgets.QLabel(Form)
self.lblInfo.setStyleSheet("")
self.lblInfo.setText("")
self.lblInfo.setObjectName("lblInfo")
self.horizontalLayout_5.addWidget(self.lblInfo)
self.verticalLayout_4.addLayout(self.horizontalLayout_5)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.lblTagOk.setText(_translate("Form", "OK:"))
self.lblOk.setText(_translate("Form", "000"))
self.lblTagNok.setText(_translate("Form", "NOT:"))
self.lblNok.setText(_translate("Form", "000"))
self.lblTagTempoMedio.setText(_translate("Form", "T. MED:"))
self.lblTempoMedio.setText(_translate("Form", "000"))
self.lblSemaforeVermelho.setText(_translate("Form", "Sinalizador"))
self.lblSemaforeAmarelo.setText(_translate("Form", "Sinalizador"))
self.lblSemaforeVerde.setText(_translate("Form", "Sinalizador"))
--