I'm trying to make a script in python which fetches several pieces of information (such as CPU name, network adapters) about machines in my network.
The script is currently working on my machine by using wmi.WMI() (or wmi.WMI('localhost')) to connect.
But now I want to see if it works for other machines as well. For this purpose, I've installed VMWare and set up a Virtual Machine (running Windows XP). I'd like to know how to connect to it.
I've read that you can simply use wmi.WMI([machine name or IP]) but putting in the IP ipconfig gives me does not seem to work. I get the error The RPC server is unavailable.
Could anybody help me please?
Thank you in advance.
One thing you can do that I found to be helpful was use a try...except statement inside a while True loop. That will repeatedly force WMI to connect to the machine and only break once the connection has been established. For example, in the case of the RPC server is unavailable error:
while True:
try:
comm = wmi.WMI([servername] user=[username] password=[password])
except wmi.x_wmi:
continue
else:
break
That should help out a little.
Related
Part of the code I'm using is based on the messagebus example at https://github.com/irmen/Pyro4/tree/master/examples/messagebus. I've set up a Pyro4 nameserver on one machine. The server & publisher are also running on this machine.
The subscriber works if I run it on this machine but I get an error if I try and run it on a different one. I need this to work on several different machines.
The Error I get is: "error: [Errno 99] Cannot assign requested address"
The line where my code is failing is:
d = Pyro4.Daemon(host = NS_HOST, port = 6193)
where NS_HOST is the name of the host where the nameserver etc are running, and 6193 is the port that the ns is using. For some reason it doesn't seem to work anywhere except the localhost. Do I need to do anything different?
I know that I can connect to the ns of this host because I don't get an error with:
Pyro4.locateNS(host = NS_HOST, port = 6193)
The above line isn't currently in my code ( I just used it to check that I wasn't having issues with wrong hostname, firewalls etc.) but I was wondering if there is a way I could combine this with Pyro4.Daemon() to get the code to work - any ideas?
I'm using python 2.7.
Thanks for your help!
(It often helps to include the actual stack trace and not only the final error message. And, "Error 99" is also a bit undescriptive.)
However, that error message is part of an OSError that's not caused by Pyro itself. It's an error condition from your OS's socket library because you're trying to bind a Pyro daemon on the wrong network interface address: you're supplying the address of the name server which is running on another node.
The 'host' and 'port' parameters for the Daemon are not the same as the ones you provide to the locateNS function. See https://pyro4.readthedocs.io/en/stable/servercode.html#creating-a-daemon Normally you don't have to specify them at all and just let Pyro figure out the suitable defaults.
I have a python script running on a revPi which uses Azure IOT SDK. The script basically accepts a bunch of modbus registers from a .json file, adds a few properties and sends it to Azure IOT hub for analysis.
The script is currently too dependent on network connection and due to infrastructure limitations, the connectivity is unreliable and often causes the script to die/abort often. How can I make the script to function on this poor internet connection? The main libraries being used are pymodbus and iothub_client.
As per Checking network connection I'd suggest something like this;
import urllib2
if(internet_on())
CallFunction()
else
internet_on()
def internet_on():
try:
urllib2.urlopen('http://216.58.192.142', timeout=1)
return True
except urllib2.URLError as err:
return False
"216.58.192.142" is a google address but you could use anything reliable such as Azure as this is where you are sending your data.
It may be more sensible to use a while loop or add a thread sleep to stop it checking so often.
Hope this helps.
I have a dot-matrix printer LX-300 connected to my computer through the network. How do I send a raw string with ESCP characters directly to my printer in Python?
The computer is connected to the printer through another computer. I need to send a raw string because LX-300 image printing result is blurry.
The Problem
To send data down this route:
Client computer ---> Server (Windows machine) ---> printer (dot-matrix)
...and to not let Windows mess with the data; instead to send the raw data, including printer control codes, straight from the client computer.
My Solution
Here's how I solved a near-identical problem for a small in-house database application:
Step 1) Make the printer network-accessible without Windows getting its fingers in the data routed to it. I accomplished this by installing the printer using the "Generic/Text Only" driver, then installing
RawPrintServer on the Windows machine connected to the printer.
Step 2) Send raw data over the network to the TCP/IP port specified when you set up RawPrintServer (default is 9100). There are various ways to do that, here's what I did:
data = b"\x1B#A String To Print\x1B#" # be sure to use the right codes for your printer
ip_addr = 123.123.123.123 # address of the machine with the printer
port = 9100 # or whatever you set it to
s = socket.socket()
try:
s.connect((ip_addr, port))
s.send(data)
except:
# deal with the error
finally:
s.close()
Background
I thought about the problem in two parts:
Client machine: spitting out the data I need from Python with the correct formatting/control codes for my printer, and sending it across the network
Print server machine: transmitting the data to the locally connected printer
Number 1 is the easy part. There are actually some libraries in PyPI that may help with all the printer codes, but I found most of them are aimed at the little point-of-sale label printers, and were of limited use to me. So I just hard-coded what I needed into my Python program.
Of course, the way you choose to solve number 2 will effect how you send the data from Python. I chose the TCP/IP route to avoid dealing with Samba and Windows print issues.
As you probably discovered, Windows normally tries very hard to convert whatever you want to print to a bitmap and run the printer in graphics mode. We can use the generic driver and dump the data straight into the (local) printer port in order to prevent this.
The missing link, then, is getting from the network to the local printer port on the machine connected to the printer. Again, there are various ways to solve this. You could attempt to access the Windows printer share in some way. If you go the TCP/IP route like I did, you could write your own print server in Python. In my case, the RawPrintServer program "just worked" so I didn't investigate any further. Apparently all it does is grab incoming data from TCP port 9100 and shove it into the local printer port. Obviously you'll have to be sure the firewall isn't blocking the incoming connections on the print server machine. This method does not require the printer to be "shared" as far as Windows is concerned.
Depending on your situation (if you use DHCP), you might need to do some extra work to get the server's IP address in Python. In my case, I got the IP for free because of the peculiarity of my application.
This solution seems to be working out very well for me. I've got an old Panasonic printer running in Epson ESC/P compatibility mode connected to a Windows 7 machine, which I can print to from any other computer on the local network. Incidentally, this general idea should work regardless of what OS the client computer is running.
Ultimately, you will need and want to write your own wrapper/script to do this. And since you are using a distribution of Linux, this is relatively easy.
On a Linux OS, the simplest way to issue a print job is to open a subprocess to the lpr. Generally, using lpr lets you access the printer without the need to be logged in as root (being a superuser), which is desirable considering the amount of damage that can be done while logged in as a "superuser".
Code like the following:
import subprocess
lpr = subprocess.Popen("/usr/bin/lpr", stdin=subprocess.PIPE)
lpr.stdin.write(data_to_send_to_printer)
Should be a good jumping off point for you. Essentially, this code should allow you to accomplish what you need.
Be careful though; depending on your privilege levels, a call to open a subprocess might need root level/Superuser permissions.
Subprocesses generally inherit the User IDs and access rights by the user that is running the command. For example, if the subprocess is created by a root user, then you will need root user/Superuser rights to access that subprocess.
For more information, check out the hyperlinks I've included in the post.
Good luck!
I have just tried to connect to usb mobile to send sms through it using AT commands. But when i use pyserial to connect to it in a windows os, i get error could not open port, the file specified cannot be found.
>>> import serial
>>> ser = serial.Serial(0) # open first serial port
>>> print ser.name # check which port was really used
>>> ser.write("hello") # write a string
>>> ser.close()
even if i replace the 0 with any other value, like 0 -10 or 'com0','com1' etc, i still get error file specified not found, port cannot be open.
There is a command listed in pyserial documentation which lists ports or allows you to open a port
python -m serial.tools.miniterm
This command is supposed to list all serial ports. But it shows none.
I have 3 usb ports on my system. What is causing this issue.
Pyserial is not guaranteed to detect all ports. This depends on how the device and the OS communicate and if pyserial is designed to pick up on this. For Example, pyserial could not detect a LabJack U3-LV or a EPSOM-POS receipt printer I plugged in in a Win8 session (both could be detected using a linux session).
Try serial.tools.list_ports.comports() and see what it gives you.
You could also look at the pyusb module for usb connections.
Also: I recommend being careful when using numbers for ports, as the mapping may not be "common-sense" logical (i.e. 0 may not map to COM0). Use explicit string names instead.
I found the solution myself. Its pretty simple and uses the same code in the question.. I was getting blocked error because there was no modem(nokia phone) in my device manager. although i had plugged in my phone into the usb, there was no nokia pc suite installed. Once you install nokia pc suite and connect your nokia phone, in device manager -> modems your phone will appear. Just check its properties->modem and you will find the com5 or whichever number. Then use that id to connect. If you dont know this, just iterate till you find the right one.
Thanks everyone who tried to help
I have a device with a built-in USB/Serial adapter (shows up as a Prolific PL2303). The device documentation provides full details on how to communicate with it, and provides a sample Windows app. However, I need to use it on Linux - ideally with Python but I'm not too precious about that.
The device docs state the device runs at 9600, 8N1 with half duplex. The Windows app works fine - device works fine (so I know it's not a device problem). However, I can't communicate with it using Python on Linux. I'm using pySerial, and I've tried a similar (full duplex, also PL2303) device which works fine.
I've tried several combinations of setting xonxoff, rtscts etc. I've also tried RTS toggling using setRTS(True) and checking for CTS and DSR etc - gets all return False. I can successfully open the device using pySerial (I can see activity light flashing - simple but effective test) and pySerial complains if you unplug it during reads/writes.
Doesn't seem to matter what flags/lines I set or what data I send, always get the same result.
>>> s=serial.Serial()
>>> s.port('/dev/ttyUSB1')
>>> s.open()
>>> s
Serial<id=0x7fe94b533b50, open=True>(port='/dev/ttyUSB1', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=3, xonxoff=0, rtscts=0, dsrdtr=0)
>>> s.write('\2CMD2292\r')
>>> s.inWaiting()
0
>>> s.setRTS(True)
>>> s.getCTS()
False
(several iterations of above with different flags).
Ignore the data in the write command - that's just a status check command. Doesn't matter what goes there, the device should either respond with an answer or an error.
I've even resorted to closing and re-opening the device in between setting various ctsrts flags etc., and unplugging / replugging it to force resets. As above it continues to work fine using the Windows test app. I can't use Portmon etc. to sniff the Windows port traffic as it's a 64bit Win7 install and I don't currently have time to build an XP machine.
Any thoughts?
UPDATE: I've also tried all of the above using Python on the same Windows box that the demo app works on. It definitely opens the port and communicates, but again no info back regardless of what's written.
UPDATE2: It looks like it might be device-driver related. Some additional background research suggests that some PL2303 chips have functionality to support half-duplex, but this isn't supported by the Linux drivers. The Windows demo app comes with a dedicated device driver and the app doesn't work on a clean test machine using default Windows drivers. This makes me think that while I can connect to it successfully through Python, I can't control the duplex comms (e.g. even in an STX/ETX way) and therefore this might be a hopeless case. sigh.
UPDATE3: Thanks for the comments below. However, I couldn't find any way round this. I tried a USB protocol analyser, and I tried disassembling the driver but it just became rather time-consuming, so in the end I took the device apart and after some tinkering I managed to replace the existing usb-serial adapter with a proper PL2303 part - on the device side, it was just a basic 2-wire serial interface so it didn't care what was talking to it. I can't seem to close this question so I'll leave it as-is.
Try
s.flush()
just after your s.write call