def test_db_write_real(self): byte_data = self.client.db_read(11, 22, 4) data = get_real(byte_data, 0) print(data) set_real(byte_data, 0, 33) self.client.db_write(11, 22, byte_data) byte_data = self.client.db_read(11, 22, 4) data = get_real(byte_data, 0) print(data)
def create_data_for_fb(self, _bytearray): """ Create data for firebase :param _bytearray :return tuple (path, dict) :raises TypeError OverflowError ValueError """ if not isinstance(_bytearray, bytearray): raise TypeError("A parameter must be bytearray") if self.__size != len(_bytearray): raise OverflowError("Bytearray is not correct") holder = {} for index, foo in enumerate(self.__template): data_type = foo['Data_type'] offset = float(foo['Offset']) row = None old = None if data_type == 'Bool': byte, bit = str(offset).split('.') byte, bit = int(byte), int(bit) old = get_bool(self.__datablock, byte, bit) row = get_bool(_bytearray, byte, bit) elif data_type == 'String': offset = int(offset) old = get_string(self.__datablock, offset, 256) row = get_string(_bytearray, offset, 256) elif data_type == 'Int': offset = int(offset) old = get_int(self.__datablock, offset) row = get_int(_bytearray, offset) elif data_type == 'Real': offset = int(offset) old = get_real(self.__datablock, offset) row = get_real(_bytearray, offset) else: raise ValueError("data_type error") if old == row: continue holder[index] = row self.__datablock = _bytearray return 'current/datablocks/DB{_num}/data'.format( _num=self.__datablock_number), holder
def test_read_real(self): data = self.client.db_read(0, 60, 4 * 9) self.assertAlmostEqual(get_real(data, 0), -3.402823e38, delta=-3.402823e38 * -0.0000001) self.assertAlmostEqual(get_real(data, 4), -3.402823e12, delta=-3.402823e12 * -0.0000001) self.assertAlmostEqual(get_real(data, 8), -175494351e-38, delta=-175494351e-38 * -0.0000001) self.assertAlmostEqual(get_real(data, 12), -1.175494351e-12, delta=-1.175494351e-12 * -0.0000001) self.assertAlmostEqual(get_real(data, 16), 0.0) self.assertAlmostEqual(get_real(data, 20), 1.175494351e-38, delta=1.175494351e-38 * 0.0000001) self.assertAlmostEqual(get_real(data, 24), 1.175494351e-12, delta=1.175494351e-12 * 0.0000001) self.assertAlmostEqual(get_real(data, 28), 3.402823466e12, delta=3.402823466e12 * 0.0000001) self.assertAlmostEqual(get_real(data, 32), 3.402823466e38, delta=3.402823466e38 * 0.0000001)
def unpack(array_read, array_order, variables): buffer = [] j = 0 for loop in range(len(array_order)): a = array_order[loop][0] print(a) start_index = int(math.modf(variables[a]['address'])[1]) i = 0 while i < len(array_order[loop]): order = array_order[loop][i] byte_index = int(math.modf(variables[order]['address'])[1]) type = variables[order]['data_type'] if type == 7: bool_index = round(math.modf(variables[order]['address'])[0] * 10) buffer.append([get_bool(array_read[loop], byte_index - start_index, bool_index)]) if type == 6: buffer.append([get_byte(array_read[loop], byte_index - start_index)]) if type == 4: buffer.append([get_word(array_read[loop], byte_index - start_index)]) if type == 5: buffer.append([get_dword(array_read[loop], byte_index - start_index)]) if type == 2: buffer.append([get_int(array_read[loop], byte_index - start_index)]) if type == 3: buffer.append([get_dint(array_read[loop], byte_index - start_index)]) if type == 1: buffer.append([get_real(array_read[loop], byte_index - start_index)]) buffer[j].append(order) j = j + 1 i = i + 2 order1(buffer) # 按最后一列顺序排序 return buffer
def read_value(data_type, result, byte_index=0, bool_index=0): # 'FLOAT' if data_type == 1: return get_real(result, byte_index) # 'INT' elif data_type == 2: return get_int(result, byte_index) # 'DINT' elif data_type == 3: return get_dint(result, byte_index) # 'WORD' elif data_type == 4: return get_word(result, byte_index) # 'DWORD' elif data_type == 5: return get_dword(result, byte_index) # 'BYTE' elif data_type == 6: return get_byte(result, byte_index) # 'BOOL' elif data_type == 7: return get_bool(result, byte_index, bool_index) else: assert ValueError, 'data_type is not useful'
def car_position_1(): p_old = 0 b = 0 while True: time.sleep(5) mysql_1 = DatabaseManagement() for i in range(16): start = 2 + 36 * i # 向plc读取过跨车位置 position_1 = plc_r(100, start, 4) position_1 = get_real(position_1, 0) a = position_1 - p_old p_old = position_1 if a != 0: truck_num = i % 8 + 1 news = car_Position(truck_num, i + 1, position_1) mysql_1.add_obj(news) else: b += 1 if b % 4 == 0: truck_num = i % 8 + 1 news = car_Position(truck_num, i + 1, position_1) mysql_1.add_obj(news)
def plcRead_weight1(i): plc = snap7.client.Client() plc.connect('192.168.6.101', 0, 1) try: weight = get_real(plc.read_area(0x84, 68, 68 + i * 4, 4), 0) return round(weight, 2) except: journal() print('read weight error')
def plcRead_weightPlan(): plc = snap7.client.Client() plc.connect('192.168.6.101', 0, 1) try: weight_plan = get_real(plc.read_area(0x84, 68, 0, 4), 0) return weight_plan except: journal() print('read weight---plan error')
def read_Real(self): """ Read Real type Data from snap7-server """ data = self.client.db_read(self.db, self.real_start, self.real_size) real_list = [] for index in range(self.real_start, self.real_size - 1, 4): real_data = util.get_real(data, index) real_list.append(real_data) print("real_list<{}> = {}\n".format(len(real_list), real_list))
def read(self,datatype,*args): self.plc2pc_data=self.plc.db_read(self.db_number,self.db_read_start,self.db_read_size) if datatype=='bool': return util.get_bool(self.plc2pc_data,args[0],args[1]) elif datatype=='int': return util.get_int(self.plc2pc_data,args[0]) elif datatype==('dint' or 'dword'): return util.get_dword(self.plc2pc_data,args[0]) elif datatype=='real': return util.get_real(self.plc2pc_data,args[0]) elif datatype=='string': return util.get_string(self.plc2pc_data,args[0],args[1])
def readValue(area, db, datatype, offset, size=0): if area == 'S7AreaDB' and db != 0: (buf, start) = readDataBlock(db, datatype, offset, size) elif area == 'S7AreaMK': (buf, start) = readMarker(datatype, offset, size) else: (buf, start) = (b'', 0) if buf: if datatype == 'INTEGER': value = s7util.get_int(buf, start) elif datatype == 'REAL': value = s7util.get_real(buf, start) elif datatype == 'STRING': value = s7util.get_string(buf, start, size) elif datatype == 'DATE_TIME': value = buf[:8] elif datatype == 'ARRAY OF REAL': value = [] if len(buf) >= start + (4 * size): for i in range(0, size): value.append(s7util.get_real(buf, start + (4 * i))) else: # print('setting default value') if datatype == 'INTEGER': value = 0 elif datatype == 'REAL': value = 0.0 elif datatype == 'STRING': value = '' elif datatype == 'DATE_TIME': value = b'' elif datatype == 'ARRAY OF REAL': value = [] for i in range(0, size): value.append(0.0) return value
def set_value(self, byte): self.valor_anterior = self.valor if self.type_var == "R": self.valor = round(util.get_real(byte, self.address),2) elif self.type_var == "I" or self.type_var == "W": self.valor = round(util.get_int(byte, self.address),2) elif self.type_var == "DW" or self.type_var == "DI": self.valor = round(util.get_dword(byte, self.address),2) elif self.type_var == "B": self.valor = util.get_bool(byte, self.address, self.bit) if self.valor_anterior != self.valor: self.write = True else: self.write = False
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 set_value(self, byte): self.valor_anterior = self.valor if self.type_var == "R": self.valor = util.get_real(byte, self.address) if self.type_var == "I" or self.type_var == "W": self.valor = util.get_int(byte, self.address) if self.type_var == "DW" or self.type_var == "DI": self.valor = int(util.get_dword(byte, self.address)) # print str(self.db )+"."+str(self.address )+" DI: "+ str(self.valor) if self.type_var == "B": #print self.address value_t = util.get_bool(byte, int(self.address), int(self.bit)) if value_t: self.valor = 1 else: self.valor = 0
def plcRead_position(i): try: plc = snap7.client.Client() plc.connect('192.168.6.101', 0, 1) area = 0x84 try: start = 2 + 36 * i news = plc.read_area(0x84, 100, start, 4) news = get_real(news, 0) return news except: journal() print('read position error') except: journal() print('can not connect plc--position')
def get_real(self): """get Real type data :returns: real_list: list """ real_list = [] for point in self.real_points: try: data = self.client.db_read(db_number=self.db_number, start=point, size=self.real_data_size) except Exception as err: log.warn(err) else: for index in range(0, self.real_data_size-1, 4): real_data = util.get_real(_bytearray=data, byte_index=index) real_list.append(real_data) return real_list
def read_siemens(ipSiemens, db): global temp if not plc.get_connected() : try: startTemp = time.time() print "Conectando ao PLC Siemens..." plc.connect(ipSiemens, 0, 1) # connect to PLC msg1 = "Conectado ao PLC Siemens, tempo:" + str(time.time() - startTemp) +" IP:"+str(ipSiemens)+" db:"+str(db) print msg1 LogInflux.influx_log(msg1) except: msg1 = "Sem conexao com PLC Siemens IP:"+ str(ipSiemens) print msg1 LogInflux.influx_log(msg1) LogInflux.influx_plc(1) # 1 para status de erro plc.disconnect() temp = ["ERRO"] if plc.get_connected() : try: area = 0x84 # area for DB memory start = 0 # location we are going to start the read length = 288 # tamanho em bytes da leitura, com uma casa a mais do ultimo dado desejado no PLC # bit = 0 # which bit in the db memory byte we are reading startTemp = time.time() byte = plc.read_area(area,db,start,length) temp = [] i = 0 # Cria Array com dados do PLC while i <= length-4: temp.append(round(util.get_real(byte,i),3)) i=i+4 LogInflux.influx_plc(0) # 0 para status OK except : msg1 = "PLC Siemens falha na leitura ip:"+ str(ipSiemens) print msg1 LogInflux.influx_log(msg1) LogInflux.influx_plc(1) plc.disconnect() temp = ["ERRO"]
def read_value(data_type, result, byte_index=0, bool_index=0): if data_type == 'FLOAT': return get_real(result, byte_index) elif data_type == 'INT': return get_int(result, byte_index) elif data_type == 'DINT': return get_dint(result, byte_index) elif data_type == 'WORD': return get_word(result, byte_index) elif data_type == 'BYTE': return get_byte(result, byte_index) elif data_type == 'BOOL': return get_bool(result, byte_index, bool_index) elif data_type == 'DWORD': return get_dword(result, byte_index) else: assert ValueError, 'data_type is not useful'
def s7_multi_read(plc, tag_type, tag_address,data_type,tag_name): ''' 从s7_read_excel处理完的变量表中批量读取变量 ''' # print('s7multiread函数') # print(tag_type, tag_address) taglens = len(tag_type) # print(taglens) # l = taglens # 变量表长度,如果大于20 必须分批读取 snp7 # x = (l // 20) +1 # 取整加1 组数 # y = l % 20 # 取余数 # dataitemsgroup=[] # for i in range(x): # dataitemsgroup.append("data_items"+str(i)) # for i in dataitemsgroup: # if i < x: # dataitemsgroup = (S7DataItem * pass)() # data_items[i].Area = areas[tag_type[i]] # 数据类型 # data_items[i].WordLen = ctypes.c_int32(S7WLByte) # data_items[i].Result = ctypes.c_int32(0) # data_items[i].DBNumber = ctypes.c_int32(0) # DB块 非DB写0 # data_items[i].Start = ctypes.c_int32(int(tag_address[i].split('.')[0])) # byte地址 # data_items[i].Amount = ctypes.c_int32(8) # 读取8位 # val = val + plc.read_multi_vars(data_items[20 * a:20 * (a + 1)]) # a += 1 # n += 1 # if n == x and y != 0: # val = val + plc.read_multi_vars(data_items[20 * a:20 * a + y]) # # a = 0 # 每一组变量的上标 # val = [] # 初始化列表 每一组变量值 # for n in range(x): # if n < x: # val = val + plc.read_multi_vars(data_items[20 * a:20 * (a + 1)]) # a += 1 # n += 1 # if n == x and y != 0: # val = val + plc.read_multi_vars(data_items[20 * a:20 * a + y]) # val2 = val # return val2 data_items = (S7DataItem * taglens)() # 括号 数组 # print(type(data_items)) # fixme 如果只有一个变量的情况 可能会有bug # 生成 data_items 待读取的变量结构体 for i in range(taglens): # print(i) data_items[i].Area = areas[tag_type[i]] # 数据类型 data_items[i].WordLen = ctypes.c_int32(S7WLByte) data_items[i].Result = ctypes.c_int32(0) data_items[i].DBNumber = ctypes.c_int32(0) # DB块 非DB写0 data_items[i].Start = ctypes.c_int32(int(tag_address[i].split('.')[0])) # byte地址 data_items[i].Amount = ctypes.c_int32(8) # 读取8位 # data_items[i].Bit = tag_address[i].split('.')[1] # 偏移量 # print(type(data_items)) # print(type(data_items[2])) # print(type(data_items[0:20])) # create buffers to receive the data # use the Amount attribute on each item to size the buffer for di in data_items: # create the buffer buffer = ctypes.create_string_buffer(di.Amount) # cast the pointer to the buffer to the required type pBuffer = ctypes.cast(ctypes.pointer(buffer), ctypes.POINTER(ctypes.c_uint8)) di.pData = pBuffer # di.Bit = di.Bit # fixme 分批读取 snap7单次20个以上报错 def readten(data_items): """ :type data_items: object """ # print(type(data_items)) # print(type(data_items[10:20])) # a=plc.read_multi_vars(data_items[10:20]) # print(a) l = len(data_items) # 变量表长度,如果大于20 必须分批读取 snp7 x = l // 20 # 取整 y = l % 20 # 取余数 a = 0 # 每一组变量的上标 val = [] # 初始化列表 每一组变量值 for n in range(x): if n < x: val = val + plc.read_multi_vars(data_items) a += 1 n += 1 if n == x and y != 0: val = val + plc.read_multi_vars(data_items) val2 = val return val2 result, data_items = plc.read_multi_vars(data_items) # print('读取的原始数据',data_items) ttt = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # for di in data_items: # check_error(di.Result) result_values = [] # function to cast bytes to match data_types[] above # byte_to_value = [util.get_bool, util.get_real, util.get_int,util.get_dword,util.get_string] # unpack and test the result of each read # todo 做一个函数列表,合并循环。逻辑上需要先读取,后get_bool for i in range(0, len(data_items)): # btv = byte_to_value[i] ddd = data_items[i] # print(ddd) d_bit = int(tag_address[i].split('.')[1]) # value = btv(di.pData, 0) if data_type[i] == 'Bool': value = util.get_bool(ddd.pData, 0, d_bit) elif data_type[i] == 'Real': value = util.get_real(ddd.pData, d_bit) elif data_type[i] == 'Int': value = util.get_int(ddd.pData, d_bit) elif data_type[i] == 'Dword': value = util.get_dword(ddd.pData, d_bit) elif data_type[i] == 'String': value = util.get_string(ddd.pData, d_bit) # assert isinstance(value, object) result_values.append(value) # print(result_values) # todo # client.disconnect() # client.destroy() siemensdata = dict(zip(tag_name, result_values)) print(siemensdata) return siemensdata, ttt
def s7_multi_read(plc, tag_type, tag_address, data_type, tag_name): ''' 从s7_read_excel处理完的变量表中批量读取变量 ''' taglens = len(tag_type) data_items = (S7DataItem * taglens)() # 括号 数组 # fixme 如果只有一个变量的情况 可能会有bug # 生成 data_items 待读取的变量结构体 for i in range(taglens): # print(i) data_items[i].Area = areas[tag_type[i]] # 数据类型 data_items[i].WordLen = ctypes.c_int32(S7WLByte) data_items[i].Result = ctypes.c_int32(0) data_items[i].DBNumber = ctypes.c_int32(0) # DB块 非DB写0 data_items[i].Start = ctypes.c_int32( int(tag_address[i].split('.')[0])) # byte地址 data_items[i].Amount = ctypes.c_int32(8) # 读取8位 for di in data_items: # create the buffer buffer = ctypes.create_string_buffer(di.Amount) # cast the pointer to the buffer to the required type pBuffer = ctypes.cast(ctypes.pointer(buffer), ctypes.POINTER(ctypes.c_uint8)) di.pData = pBuffer # fixme 分批读取 snap7单次20个以上报错 数组切片报错 暂时未使用 def readten(data_items): """ :type data_items: object """ # print(type(data_items)) # print(type(data_items[10:20])) # a=plc.read_multi_vars(data_items[10:20]) # print(a) l = len(data_items) # 变量表长度,如果大于20 必须分批读取 snp7 x = l // 20 # 取整 y = l % 20 # 取余数 a = 0 # 每一组变量的上标 val = [] # 初始化列表 每一组变量值 for n in range(x): if n < x: val = val + plc.read_multi_vars(data_items) a += 1 n += 1 if n == x and y != 0: val = val + plc.read_multi_vars(data_items) val2 = val return val2 result, data_items = plc.read_multi_vars(data_items) # print('读取的原始数据',data_items) ttt = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) for di in data_items: check_error(di.Result) result_values = [] # function to cast bytes to match data_types[] above # byte_to_value = [util.get_bool, util.get_real, util.get_int,util.get_dword,util.get_string] # unpack and test the result of each read # todo 做一个函数列表,合并循环。逻辑上需要先读取,后get_bool for i in range(0, len(data_items)): ddd = data_items[i] d_bit = int(tag_address[i].split('.')[1]) if data_type[i] == 'Bool': value = util.get_bool(ddd.pData, 0, d_bit) elif data_type[i] == 'Real': value = util.get_real(ddd.pData, d_bit) elif data_type[i] == 'Int': value = util.get_int(ddd.pData, d_bit) elif data_type[i] == 'Dword': value = util.get_dword(ddd.pData, d_bit) elif data_type[i] == 'String': value = util.get_string(ddd.pData, d_bit) result_values.append(value) # fixme # client.disconnect() # client.destroy() siemensdata = dict(zip(tag_name, result_values)) # print(siemensdata) return siemensdata, ttt
data_items[i].DBNumber = ctypes.c_int32(int(numero)) data_items[i].Start = ctypes.c_int32( 8 * int(byte) + int(bit) ) # al estar en modo bit es 8 bits * 5 bytes ya que en el DB0.DBX5.0 data_items[i].Amount = ctypes.c_int32(getattr(snap7types, tipo)) for di in data_items: # create the buffer buffer = ctypes.create_string_buffer(di.Amount) # cast the pointer to the buffer to the required type pBuffer = ctypes.cast(ctypes.pointer(buffer), ctypes.POINTER(ctypes.c_uint8)) di.pData = pBuffer result, data_items = plc.read_multi_vars(data_items) for di in data_items: check_error(di.Result) result_values = [] for di in data_items: if di.WordLen == getattr(snap7types, 'S7WLBit'): value = util.get_bool(di.pData, 0, 0) elif di.WordLen == getattr(snap7types, 'S7WLByte'): value = util.get_int(di.pData, 0) elif di.WordLen == getattr(snap7types, 'S7WLDWord'): value = util.get_dword(di.pData, 0) elif di.WordLen == getattr(snap7types, 'S7WLReal'): value = util.get_real(di.pData, 0) result_values.append(value) print(result_values)