Exemplo n.º 1
0
    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()
Exemplo n.º 2
0
 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))
Exemplo n.º 3
0
 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) + ")")
Exemplo n.º 4
0
 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))
Exemplo n.º 5
0
 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))
Exemplo n.º 6
0
    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))
Exemplo n.º 7
0
    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))
Exemplo n.º 8
0
 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)
Exemplo n.º 9
0
 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
Exemplo n.º 10
0
 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")
Exemplo n.º 11
0
 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
Exemplo n.º 12
0
 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
Exemplo n.º 13
0
 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)
Exemplo n.º 14
0
 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)