def connect(self): if not self.libLoaded: #from artisanlib.s7client import S7Client from snap7.common import load_library as load_snap7_library # first load shared lib if needed platf = str(platform.system()) if platf in ['Windows', 'Linux'] and artisanlib.util.appFrozen(): libpath = os.path.dirname(sys.executable) if platf == 'Linux': snap7dll = os.path.join(libpath, "libsnap7.so") else: # Windows: snap7dll = os.path.join(libpath, "snap7.dll") load_snap7_library( snap7dll) # will ensure to load it only once self.libLoaded = True if self.libLoaded and self.plc is None: # create a client instance from artisanlib.s7client import S7Client self.plc = S7Client() # next reset client instance if not yet connected to ensure a fresh start if self.plc is not None and not self.isConnected(): try: self.plc.disconnect() except: pass with suppress_stdout_stderr(): time.sleep(0.4) try: self.plc.connect(self.host, self.rack, self.slot, self.port) time.sleep(0.4) except Exception: pass if self.isConnected(): self.sendmessage( QApplication.translate("Message", "S7 Connected", None)) time.sleep(0.4) else: time.sleep(0.6) try: self.plc.disconnect() except: pass # we try a second time with suppress_stdout_stderr(): time.sleep(0.4) self.plc.connect(self.host, self.rack, self.slot, self.port) time.sleep(0.4) if self.isConnected(): self.sendmessage( QApplication.translate("Message", "S7 Connected", None) + " (2)") time.sleep(0.4) self.updateActiveRegisters()
def writeBool(self, area, dbnumber, start, index, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if self.isConnected(): with suppress_stdout_stderr(): ba = self.plc.read_area(self.areas[area], dbnumber, start, 1) self.set_bool(ba, 0, int(index), bool(value)) self.plc.write_area(self.areas[area], dbnumber, start, ba) else: self.aw.qmc.adderror( (QApplication.translate("Error Message", "S7 Error:", None) + " connecting to PLC failed")) except Exception as e: if self.aw.qmc.flagon: _, _, exc_tb = sys.exc_info() self.aw.qmc.adderror( QApplication.translate("Error Message", "S7 Communication Error", None) + " writeBool: " + str(e), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) if self.aw.seriallogflag: self.aw.addserial("S7 writeBool({},{},{},{},{})".format( area, dbnumber, start, index, value))
def writeInt(self, area, dbnumber, start, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if self.plc is not None and self.plc.get_connected(): with suppress_stdout_stderr(): ba = self.plc.read_area(self.areas[area], dbnumber, start, 2) self.set_int(ba, 0, int(value)) self.plc.write_area(self.areas[area], dbnumber, start, ba) else: self.adderror( (QApplication.translate("Error Message", "S7 Error:", None) + " connecting to PLC failed")) except Exception as e: self.adderror( QApplication.translate("Error Message", "S7 Communication Error", None) + " writeInt: " + str(e)) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) self.addserial("S7 writeInt(" + str(area) + "," + str(dbnumber) + "," + str(start) + "," + str(value) + ")")
def maskWriteInt(self, area, dbnumber, start, and_mask, or_mask, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if self.isConnected(): with suppress_stdout_stderr(): ba = self.plc.read_area(self.areas[area], dbnumber, start, 2) new_val = (int(round(value)) & and_mask) | (or_mask & (and_mask ^ 0xFFFF)) self.set_int(ba, 0, int(new_val)) self.plc.write_area(self.areas[area], dbnumber, start, ba) else: self.aw.qmc.adderror( (QApplication.translate("Error Message", "S7 Error:", None) + " connecting to PLC failed")) except Exception as e: if self.aw.qmc.flagon: self.aw.qmc.adderror( QApplication.translate("Error Message", "S7 Communication Error", None) + " maskWriteInt: " + str(e)) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) if self.aw.seriallogflag: self.aw.addserial("S7 writeInt({},{},{},{})".format( area, dbnumber, start, value))
def writeFloat(self, area, dbnumber, start, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if self.isConnected(): with suppress_stdout_stderr(): ba = self.plc.read_area(self.areas[area], dbnumber, start, 4) self.set_real(ba, 0, float(value)) self.waitToEnsureMinTimeBetweenRequests() self.plc.write_area(self.areas[area], dbnumber, start, ba) else: self.commError = True self.aw.qmc.adderror( QApplication.translate( "Error Message", "S7 Error: connecting to PLC failed", None)) except Exception as e: if self.aw.qmc.flagon: _, _, exc_tb = sys.exc_info() self.aw.qmc.adderror( QApplication.translate("Error Message", "S7 Communication Error", None) + " writeFloat: " + str(e), exc_tb.tb_lineno) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) if self.aw.seriallogflag: self.aw.addserial("S7 writeFloat({},{},{},{})".format( area, dbnumber, start, value))
def readBool(self, area, dbnumber, start, index, force=False): if area == 0: return try: #### lock shared resources ##### self.COMsemaphore.acquire(1) if not force and area in self.readingsCache and dbnumber in self.readingsCache[ area] and start in self.readingsCache[area][dbnumber]: # cache hit res = bytearray([self.readingsCache[area][dbnumber][start]]) return self.get_bool(res, 0, index) else: self.connect() if self.isConnected(): retry = self.readRetries res = None while True: try: with suppress_stdout_stderr(): res = self.plc.read_area( self.areas[area], dbnumber, start, 1) except Exception: res = None if res is None: if retry > 0: retry = retry - 1 else: raise Exception("Communication error") else: break if res is None: return else: if self.commError: # we clear the previous error and send a message self.commError = False self.aw.qmc.adderror( QApplication.translate( "Error Message", "S7 Communication Resumed", None)) return self.get_bool(res, 0, index) else: self.commError = True self.aw.qmc.adderror((QApplication.translate( "Error Message", "S7 Error:", None) + " connecting to PLC failed")) except Exception as e: if self.aw.qmc.flagon: self.aw.qmc.adderror( QApplication.translate("Error Message", "S7 Communication Error", None) + " readBool: " + str(e)) self.commError = True finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) if self.aw.seriallogflag: self.aw.addserial("S7 readBool({},{},{},{})".format( area, dbnumber, start, index))
def readInt(self, area, dbnumber, start): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if self.isConnected(): retry = self.readRetries res = None while True: try: with suppress_stdout_stderr(): res = self.plc.read_area(self.areas[area], dbnumber, start, 2) except Exception: res = None if res is None: if retry > 0: retry = retry - 1 else: raise Exception("Communication error") else: break if res is None: return -1 else: if self.commError: # we clear the previous error and send a message self.commError = False self.aw.qmc.adderror( QApplication.translate("Error Message", "S7 Communication Resumed", None)) return self.get_int(res, 0) else: self.commError = True self.aw.qmc.adderror( (QApplication.translate("Error Message", "S7 Error:", None) + " connecting to PLC failed")) return -1 except Exception as e: if self.aw.qmc.flagon: self.aw.qmc.adderror( QApplication.translate("Error Message", "S7 Communication Error", None) + " readInt: " + str(e)) self.commError = True return -1 finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) if self.aw.seriallogflag: self.aw.addserial("S7 readInt({},{},{})".format( area, dbnumber, start))
def connect(self): from artisanlib.s7client import S7Client from snap7.common import load_library as load_snap7_library # first load shared lib if needed platf = str(platform.system()) if platf in ['Windows', 'Linux'] and artisanlib.util.appFrozen(): libpath = os.path.dirname(sys.executable) if platf == 'Linux': snap7dll = os.path.join(libpath, "libsnap7.so") else: # Windows: snap7dll = os.path.join(libpath, "snap7.dll") load_snap7_library(snap7dll) # will ensure to load it only once # next reset client instance if not yet connected to ensure a fresh start if self.plc and not self.plc.get_connected(): self.plc = None # connect if not yet connected if self.plc is None: self.plc = S7Client() with suppress_stdout_stderr(): time.sleep(0.4) self.plc.connect(self.host, self.rack, self.slot, self.port) time.sleep(0.4) if self.plc.get_connected(): self.sendmessage( QApplication.translate("Message", "S7 Connected", None)) time.sleep(0.7) else: time.sleep(0.6) self.plc = S7Client() # we try a second time with suppress_stdout_stderr(): time.sleep(0.4) self.plc.connect(self.host, self.rack, self.slot, self.port) time.sleep(0.4) if self.plc.get_connected(): self.sendmessage( QApplication.translate("Message", "S7 Connected", None) + " (2)") time.sleep(0.7)
def peekInt(self, area, dbnumber, start): if area == 0: return try: self.connect() if self.isConnected(): with suppress_stdout_stderr(): res = self.plc.read_area(self.areas[area], dbnumber, start, 2) return self.get_int(res, 0) else: return except: return
def readFloat(self, area, dbnumber, start): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if self.plc is not None and self.plc.get_connected(): retry = self.readRetries res = None while True: try: with suppress_stdout_stderr(): res = self.plc.read_area(self.areas[area], dbnumber, start, 4) except: res = None if res is None: if retry > 0: retry = retry - 1 else: raise Exception("Communication error") else: break if res is None: return -1 else: if self.commError: # we clear the previous error and send a message self.commError = False self.adderror( QApplication.translate("Error Message", "S7 Communication Resumed", None)) from snap7.util import get_real return get_real(res, 0) else: self.commError = True self.adderror( (QApplication.translate("Error Message", "S7 Error:", None) + " connecting to PLC failed")) return -1 except Exception: self.adderror( QApplication.translate("Error Message", "S7 Communication Error", None)) self.commError = True return -1 finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) self.addserial("S7 readFloat")
def peakFloat(self, area, dbnumber, start): if area == 0: return try: self.connect() if self.isConnected(): self.waitToEnsureMinTimeBetweenRequests() with suppress_stdout_stderr(): res = self.plc.read_area(self.areas[area], dbnumber, start, 4) return self.get_real(res, 0) else: return except: return
def peakFloat(self, area, dbnumber, start): try: self.connect() if self.isConnected(): try: with suppress_stdout_stderr(): res = self.plc.read_area(self.areas[area], dbnumber, start, 4) return self.get_real(res, 0) except: return None return None else: return None except Exception: return None
def writeFloat(self, area, dbnumber, start, value): try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() if self.plc is not None and self.plc.get_connected(): with suppress_stdout_stderr(): ba = self.plc.read_area(self.areas[area], dbnumber, start, 4) from snap7.util import set_real set_real(ba, 0, float(value)) self.plc.write_area(self.areas[area], dbnumber, start, ba) else: self.adderror( (QApplication.translate("Error Message", "S7 Error:", None) + " connecting to PLC failed")) except Exception as ex: self.adderror( QApplication.translate("Error Message", "S7 Communication Error", None)) finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1)
def readInt(self, area, dbnumber, start, force=False): if area == 0: return try: #### lock shared resources ##### self.COMsemaphore.acquire(1) if not force and area in self.readingsCache and dbnumber in self.readingsCache[area] and start in self.readingsCache[area][dbnumber] \ and start+1 in self.readingsCache[area][dbnumber]: # cache hit res = bytearray([ self.readingsCache[area][dbnumber][start], self.readingsCache[area][dbnumber][start + 1] ]) r = self.get_int(res, 0) if self.aw.seriallogflag: self.aw.addserial( "S7 readInt_cached({},{},{},{}) => {}".format( area, dbnumber, start, force, r)) return r else: self.connect() if self.isConnected(): retry = self.readRetries res = None while True: try: with suppress_stdout_stderr(): res = self.plc.read_area( self.areas[area], dbnumber, start, 2) except Exception: res = None if dbnumber == 2 and start == 48: raise Exception("result None") if res is None: if retry > 0: retry = retry - 1 else: raise Exception("result None") else: break if res is None: return else: if self.commError: # we clear the previous error and send a message self.commError = False self.aw.qmc.adderror( QApplication.translate( "Error Message", "S7 Communication Resumed", None)) r = self.get_int(res, 0) if self.aw.seriallogflag and not self.commError: self.aw.addserial( "S7 readInt({},{},{},{}) => {}".format( area, dbnumber, start, force, r)) return r else: self.commError = True self.aw.qmc.adderror((QApplication.translate( "Error Message", "S7 Error:", None) + " connecting to PLC failed")) except Exception as e: if self.aw.qmc.flagon: _, _, exc_tb = sys.exc_info() self.aw.qmc.adderror( QApplication.translate("Error Message", "S7 Communication Error", None) + " readInt({},{},{},{}): {}".format(area, dbnumber, start, force, str(e)), exc_tb.tb_lineno) if self.aw.seriallogflag: self.aw.addserial( "S7 readInt({},{},{},{}) => S7 Communication Error: {}" .format(area, dbnumber, start, force, str(e))) self.commError = True finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1)