I'm sure this is a simple problem, but I'm an amateur so here i am.
Trying to use the obd python library to communicate with my vehicle. I have a bluetooth OBDII adapter and on it's own i can send single commands as outlined in the basic usage section of the readme and get responses.
My problem is that i have a list of commands that i want to send. I'm trying to use a for loop to go through each command and print the responses on screen.
import os
import time
import obd
def clear_Screen():
os.system('cls' if os.name == 'nt' else 'clear')
connection = obd.OBD("COM7")
pids = [ 'RPM' , 'ENGINE_LOAD' , 'COOLANT_TEMP' , 'RUN_TIME' ]
try:
while True:
time.sleep(1)
clear_Screen()
for i in pids:
cmd = "obd.commands." + i
response = connection.query(cmd)
print i , ": " , (response.value)
except KeyboardInterrupt:
exit()
there's a problem with how I'm building the cmd variable because the response i get from each query is that the command isn't supported but i know they are.
if i print cmd instead of trying to use the command.query(cmd) it prints exactly like it would be if i specified it i.e. obd.commands.RPM so I don't understand why this doesn't work.
In your question you stated:
there's a problem with how I'm building the cmd variable
Indeed, in your way, cmd is only a string. So instead if you want the actual evaluated attitude, you should use getattr instead:
cmd = getattr(obd.commands,i)
eval() and exec() are both unsafe so you should never use those.
Try wrapping what you're assigning to cmd in eval():
cmd = eval("obd.commands." + i)
Related
Using Python, is there a way using psutil or something else to return the output of "ipconfig /displaydns" or something similar?
Spawning a cmd process and running the command is not an option.
To execute a command, you can use the os library. Executing the command you've shown above is as simple as:
import os
os.system('ipconfig /displaydns')
If you want to store the output of a command in a variable, you can use:
x = os.popen('ipconfig /displaydns')
You can try using dnspython's resolver class, which has a nameservers list attached to it.
import dns.resolver
resolver = dns.resolver.Resolver()
resolver.nameservers
# Returns ['8.8.8.8', '8.8.4.4', '8.8.8.8'] on my pc
This python script I made creates a directory in widows user profile and copies windows dns information into a log.txt,So if directory does not exist it will create it. Hope it works for you.
#!/usr/bin/env python3
import time
import os
def dns():
path = os.system("ipconfig /displaydns >> %USERPROFILE%\DNS\logdns.txt")
if path == False:
os.system("ipconfig /displaydns >> %USERPROFILE%\DNS\logdns.txt")
print("Please wait copying information........")
time.sleep(5 )
os.system("cls")
print("Information copy complete.")
time.sleep(3)
else:
print("Making directory please wait a second....")
time.sleep(5)
os.system("cls")
os.system("mkdir %USERPROFILE%\DNS")
time.sleep(1)
dns()
dns()
OS:- Mac OSX
Python
I'm new to Multiprocessing with python. For my application, I want to open a new process from main and run it without locking the main process. for eg. I'm running process A and now i need to open a new application from A, lets call it process B. I want to open B in such a way that it does not blocks process A and still from Process i should be able to stop the process whenever i wish to.
Till now whatever code i have tried are basic and they lock the process A. and hence i'm unable to achieve it. Is there any workaround to do this ?
I read about fork and spawn but couldn't understand how can i use it to open an application. And i have tried threading also. But with no success. Can anyone tell me how can i do that ?
Currently I'm using subprocess.call() to open Mac Applications through Python.
It would be really helpful.
EDIT :-
I tried the accepted answer of this link
but to no avail. Because it would block the terminal and once we close the app manually it exits with output 0.
Also I have tried this solution. It would do the same. I want to make the the calling process not to be blocked by the called process.
while doing the same task in windows with os.system() gives me exactly what i want. But i don't know how can i do this in Mac.
EDIT 2: CODE
module 1:
import subprocess
def openCmd(name):
subprocess.call(["/usr/bin/open", "-W", "-n", "-a", "/Applications/"+name+".app"])
def closeCmd(name):
subprocess.call(['osascript', '-e', 'tell "'+name+'" to quit'])
main module:
import speech_recognition as sr
import pyttsx
import opCl
speech_engine = pyttsx.init('nsss')
speech_engine.setProperty('rate', 150)
OPEN_COGNATES=['open']
CLOSE_COGNATES=['close']
def speak(text):
speech_engine.say(text)
speech_engine.runAndWait()
re = sr.Recognizer()
def listen():
with sr.Microphone() as source:
re.adjust_for_ambient_noise(source)
while True:
speak("Say something!")
print ">>",
audio = re.listen(source)
try:
speak("now to recognise it,")
value=re.recognize_google(audio)
print (value)
speak("I heard you say {}".format(value))
value=value.strip().split()
name=" ".join(value[1:])
if value[0] in OPEN_COGNATES:
speak("opening "+name)
opCl.openCmd(name)
pass
elif value[0] in CLOSE_COGNATES:
speak("opening "+name)
opCl.closeCmd(name)
pass
else:
pass
except sr.UnknownValueError as e:
speak("Could not understand audio")
print ('Could not understand audio')
except sr.RequestError as e:
speak("can't recognise what you said.")
print ("can't recognise what you said")
if __name__=='__main__':
listen()
Comment: it gave a traceback. FileNotFoundError: [Errno 2] No such file or directory: 'leafpad'
As i wrote, I can't us "/usr/bin/open" and osascript, so my example uses 'leafpad'.
Have you tried replacing Popen([name]) with your
Popen(["/usr/bin/open", "-W", "-n", "-a", "/Applications/"+name+".app"])?
You must pass the same command args as you start it from the command line.
Read this: launch-an-app-on-os-x-with-command-line
Reread From Python » 3.6.1 Documentation subprocess.Popen
Note
shlex.split() can be useful when determining the correct tokenization for args, especially in complex cases:
Python » 3.6.1 Documentation:
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)
Run the command described by args. Wait for command to complete, then return the returncode attribute
Your given "/usr/bin/open" and osascript didn't work for me.
From Python » 3.6.1 Documentation subprocess.Popen
NOWAIT example, for instance:
import subprocess
def openCmd(name):
subprocess.Popen([name])
def closeCmd(name):
subprocess.Popen(['killall', name])
if __name__ == '__main__':
while True:
key = input('input 1=open, 0=cloes, q=quit:')
if key == '1':
openCmd(('leafpad'))
if key == '0':
closeCmd('leafpad')
if key == 'q':
break
Note: Killing a process can lead to data loos and or other problems.
Tested with Python:3.4.2
I'm
I have pexpect working, but I am having problems printing the output back from it. In my test script below, it creates the ssh connection, and then sends a sudo su -, then my password, and then sends a line that would require sudo access to do (I have also added p.interact() a few times to make sure it is at root). The problem I am having, is with returning the output of the commands I run. In the end I am wanting to run some top commands, and some du -h, and other(much more complex) space commands. But currently when it tries to print p.before, I get:
Traceback (most recent call last):
File "./ssh.py", line 37, in <module>
print p.before()
TypeError: 'str' object is not callable
Here is the script I am working from(edited to remove my pass and such)
#!/usr/bin/env python
import pexpect
import struct, fcntl, os, sys, signal
def sigwinch_passthrough (sig, data):
# Check for buggy platforms (see pexpect.setwinsize()).
if 'TIOCGWINSZ' in dir(termios):
TIOCGWINSZ = termios.TIOCGWINSZ
else:
TIOCGWINSZ = 1074295912 # assume
s = struct.pack ("HHHH", 0, 0, 0, 0)
a = struct.unpack ('HHHH', fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ , s))
global global_pexpect_instance
global_pexpect_instance.setwinsize(a[0],a[1])
ssh_newkey = 'Are you sure you want to continue connecting'
p=pexpect.spawn('ssh user#localhost')
i=p.expect([ssh_newkey,'password:',pexpect.EOF,pexpect.TIMEOUT],1)
if i==0:
print "I say yes"
p.sendline('yes')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==1:
print "I give password",
p.sendline("mypassword")
elif i==2:
print "I either got key or connection timeout"
pass
elif i==3: #timeout
pass
global global_pexpect_instance
global_pexpect_instance = p
p.sendline("sudo su -")
p.sendline("mypasswd")
p.sendline("mkdir /home/user/test")
print p.before
I am working off of this link: http://linux.byexamples.com/archives/346/python-how-to-access-ssh-with-pexpect/
Any help is much appreciated.
EDIT: As Armin Rigo pointed out below. I was calling to p.before as a function like p.before(). Stupid mistake on my part, as this explains why I was getting this error today, and not yesterday when I was trying this. After making that change to my script, and modifying the command being sent, print p.before, and no output is returned. Any other ways to return output from a sendline() command?
Use logfile, that logfile is store all output in terminal.use that example code:-
child = pexpect.spawn("ssh user#localhost")
child.logfile = open("/tmp/mylog", "w")
child.expect(".*assword:")
child.send("guest\r")
child.expect(".*\$ ")
child.sendline("python -V\r")
open the log file and see everything in terminals event
To fetch the complete output after sendline use child.read()
e.g.
cmd_resp = pexpect.spawnu(cmd) # for execution of the command
str_to_search = 'Please Enter The Password'
cmd_resp.sendline('yes') # for sending the input 'yes'
resp = cmd_resp.expect([str_to_search, 'password:', EOF], timeout=30) # fetch the output status
if resp == 1:
cmd_resp.sendline(password)
resp = cmd_resp.expect([str_to_search, 'outputString:', EOF], timeout=30)
print(cmd_resp.read()) # to fetch the complete output log
p.before is a string - not a function. To see the output you have to write
print p.before.
Hope this might help you
I was asked to simulate CLI with Python.
This is what I did
def somefunction(a,b):
//codes here
//consider some other functions too
print "--- StackOverFlow Shell ---"
while True:
user_input = raw_input("#> ")
splitit = user_input.split(" ")
if splitit[0] == "add":
firstNum = splitit[1]
sNum = splitit[2]
result = somefunction(firstNum, sNum)
print result
//consider some other elif blocks with "sub", "div", etc
else:
print "Invalid Command"
I do also check the length of the list, here "splitit" I will allow only 3 argumets, first will be the operation, and second and third are the arguments with which some functions are to be performed, in case the argument is more than 3, for that i do put a check.
Though Somehow I manage to make it work, but is there a better way to achieve the same?
Use python CMD Module:
Check few examples given on the below pages
http://docs.python.org/library/cmd.html # Support for line-oriented command interpreters
http://www.doughellmann.com/PyMOTW/cmd - # Create line-oriented command processors
prompt can be set to a string to be printed each time the user is asked for a new command.
intro is the “welcome” message printed at the start of the program.
eg:
import cmd
class HelloWorld(cmd.Cmd):
"""Simple command processor example."""
prompt = 'prompt: '
intro = "Simple command processor example."
You should check out the VTE lib:
http://earobinson.wordpress.com/2007/09/10/python-vteterminal-example/
It works really well and you can very easily customize its look. This is how easy it is:
# make terminal
terminal = vte.Terminal()
terminal.connect ("child-exited", lambda term: gtk.main_quit())
terminal.fork_command()
# put the terminal in a scrollable window
terminal_window = gtk.ScrolledWindow()
terminal_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
terminal_window.add(terminal)
Based on Chapter 12 of the OTP in Action book and Cesarini's book I wrote this Erlang code:
Erlang:
p(Param) ->
?DBG("Starting~n", []),
Cmd = "python test.py",
Port = open_port({spawn,Cmd}, [stream,{line, 1024}, exit_status]),
?DBG("Opened the port: ~w~n", [Port]),
Payload = term_to_binary(list_to_binary(integer_to_list(Param))),
erlang:port_command(Port, Payload),
?DBG("Sent command to port: ~w~n", [Payload]),
?DBG("Ready to receive results for command: ~w~n", [Payload]),
receive
{Port, {data, Data}} ->
?DBG("Received data: ~w~n", [Data]),
{result, Text} = binary_to_term(Data),
Blah = binary_to_list(Text),
io:format("~p~n", [Blah]);
Other ->
io:format("Unexpected data: ~p~n", [Other])
end.
Python:
import sys
def main():
while True:
line = sys.stdin.readline().strip()
if line == "stop-good":
return 0
elif line == "stop-bad":
return 1
sys.stdout.write("Python got ")
sys.stdout.write(line)
sys.stdout.write("\n")
sys.stdout.flush()
if __name__ == "__main__":
sys.exit(main())
The Erlang code suspends at the recieve clause - it never gets any message.
I have also checked Python from a regular Linux shell - it prints out every user input (1 - "Python got 1").
Where is the mistake here? Why doesn't my Erlang code get anything back?
There are two points:
make sure that Python does not buffer your output, try running python -u in open_port
using term_to_binary/1 and binary_to_term/1 won't work, since they assume that Python is able to encode/decode Erlang External Term Format, which does not seem to be the case. If you want to go this route, check out ErlPort
Does your Param contain the command limiter for Python? (in this case I assume newline, "\n"). Also, list_to_binary/1 and then a term_to_binary/1 feels kinda wrong. term_to_binary/1 directly (including the newline) should be sufficient.