GPIO random input, Difference between scripts? - python

So I am currently working on a Raspberry Pi Project.
My Raspi is connected to my letterbox, so everytime someone opens it, a button is pushed. When the button is pushed, a script should detect this and send me an EMail, and write the current Time and Date in a .txt file.
My script that I made a little bit by my self and with the help of the internet, works, but it randomly detects a GPIO input every 10-20 Minutes (the Wires that are connected to the button are very long and my Raspi is connected in a room that is full with cabels, this might be the Problem). But, I tried to do it with a script that I just found on the internet. Just copy it (well, at least the GPIO part). So this script works, but mine detects a random input.
Another Problem (you'll see it in the script) that I had with an old script was, that I used a while loop, and it used 97% of my CPU. So I did another script that would work differently. It doesnt use 97% of my CPU, but it detects random Inputs. In the script that I copied from the internet also uses a while loop, but it doesnt take that much CPU. But why? I dont understand that either.
This is my Script, that detects random Inputs:
import RPi.GPIO as GPIO
import smtplib
import pytz
from pytz import timezone
import datetime
from time import sleep
GPIO.setmode(GPIO.BCM)
GPIO.setup(7,GPIO.IN,)
def writeanemail():
smtpUser = ''
smtpPass = ''
toAdd = ''
fromAdd = smtpUser
subject = 'Du hast etwas in deinem Postfach'
header = 'To: ' + toAdd + '\n' + 'From: ' + fromAdd + '\n' + 'Subject: ' + subject
print ("\n" + header)
s = smtplib.SMTP('smtp.gmail.com',587)
s.ehlo()
s.starttls()
s.ehlo()
s.login(smtpUser, smtpPass)
s.sendmail(fromAdd, toAdd, header)
s.quit()
def timelog():
now = datetime.datetime.now(timezone('Europe/Berlin'))
file = open("/home/pi/ps/gpio.log","a")
file.write("\n" + now.strftime("%Y-%m-%d--%a %H:%M:%S"))
file.close()
print ("\n" + now.strftime("%Y-%m-%d--%a %H:%M") + "\n" + "\n" + "Log wurde geschrieben")
def main():
GPIO.wait_for_edge(7, GPIO.FALLING, bouncetime = 150)
print ("Knopf wurde gedrueckt, E-Mail wird geschickt.")
sleep(1)
writeanemail()
timelog()
sleep(10)
main()
main()
And this is the copied one, that works fine:
import RPi.GPIO as GPIO
from pytz import timezone
import datetime
# SET GPIO Button-Pin
gpio = 7
def writeanemail():
smtpUser = ''
smtpPass = ''
toAdd = ''
fromAdd = smtpUser
subject = 'Du hast etwas in deinem Postfach'
header = 'To: ' + toAdd + '\n' + 'From: ' + fromAdd + '\n' + 'Subject: ' + subject
print ("\n" + header)
s = smtplib.SMTP('smtp.gmail.com',587)
s.ehlo()
s.starttls()
s.ehlo()
s.login(smtpUser, smtpPass)
s.sendmail(fromAdd, toAdd, header)
s.quit()
# Main Function
def main():
value = 0
while True:
if not GPIO.input(gpio):
value += 0.01
if value > 0:
if GPIO.input(gpio):
print "gedrueckt"
now = datetime.datetime.now(timezone('Europe/Berlin'))
file = open("/home/pi/ps/gpio.log","a")
file.write("\n" + now.strftime("%Y-%m-%d--%a %H:%M:%S"))
file.close()
writeanemail()
main()
time.sleep(0.03)
return 0
if __name__ == '__main__':
GPIO.setmode(GPIO.BCM)
GPIO.setup(gpio, GPIO.IN)
main()
Here I copied only the main function, the Email part is the same.
I am thankful for any help and advice.

Related

Python - using smtplib to send to multiple recipients

I'm finding it very difficult to modify this code to send to send to multiple recipients, I have tried many variations of the examples already out there. I'm very new to python so any help would be much appreciated.
It is as part of safety system I am designing to alert parents and carers of potential elopement risk for children and adults with ASD.
'''
import time
import serial
import smtplib
TO = 'email#mail.org'
GMAIL_USER = 'email#gmail.com'
GMAIL_PASS = 'passowrd'
SUBJECT = 'Security Alert'
TEXT = 'Movement detected!'
ser = serial.Serial('COM6', 9600)
def send_email():
print("Sending Email")
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
smtpserver.login(GMAIL_USER, GMAIL_PASS)
header = 'To:' + TO + '\n' + 'From: ' + GMAIL_USER
header = header + '\n' + 'Subject:' + SUBJECT + '\n'
print header
msg = header + '\n' + TEXT + ' \n\n'
smtpserver.sendmail(GMAIL_USER, TO, msg)
smtpserver.close()
while True:
message = ser.readline()
print(message)
if message[0] == 'M' :
send_email()
time.sleep(0.5)
'''
Send the alert to multiple people.
Have you had a look at this yet? How to send email to multiple recipients using python smtplib?
It looks like you might be dropping some of the pieces of your header too by overwriting them:
header = 'From: ' + GMAIL_USER
Instead of:
header = header + 'From: ' + GMAIL_USER
You might also want to consider using format instead, but I'm already out of my depth on Python :-)

Python Syntax Error, can't find a solution to indentions

Been having issues with one of my scripts. When I run the script, I get the following message under line 23:
SyntaxError: inconsistent use of tabs and spaces in indentation
I have tried using Anaconda to replace any tabs with 4/8 spaces but no success.
Any ideas where I'm going wrong here?
Cheers.
import RPi.GPIO as GPIO
import time
sensor = 4
GPIO.setmode(GPIO.BCM)
GPIO.setup(sensor, GPIO.IN, GPIO.PUD_DOWN)
previous_state = False
current_state = False
try:
while True:
time.sleep(0.1)
previous_state = current_state
current_state = GPIO.input(sensor)
if current_state != previous_state:
new_state = "HIGH" if current_state else "LOW"
print("GPIO pin %s is %s" % (sensor, new_state))
import smtplib
smtpUser = 'rpigroupproject#gmail.com'
smtpPass = '<password>'
toAdd = 'rpigroupproject#gmail.com'
fromAdd = smtpUser
subject = 'ALERT!'
header = 'To: ' + toAdd + '\n' + 'From: ' + \
fromAdd + '\n' + 'Subject:' + subject
body = 'Motion was detected...'
print header + '\n' + body
s = smtplib.SMTP('smtp.gmail.com', 587)
s.ehlo()
s.starttls()
s.ehlo()
s.login(smtpUser, smtpPass)
s.sendmail(fromAdd, toAdd, header + '\n' + body)
s.quit()
except:
GPIO.cleanup()
Here it is with the indentation fixed. You should configure your editor so you don't get this error again.
import RPi.GPIO as GPIO
import time
sensor = 4
GPIO.setmode(GPIO.BCM)
GPIO.setup(sensor, GPIO.IN, GPIO.PUD_DOWN)
previous_state = False
current_state = False
try:
while True:
time.sleep(0.1)
previous_state = current_state
current_state = GPIO.input(sensor)
if current_state != previous_state:
new_state = "HIGH" if current_state else "LOW"
print("GPIO pin %s is %s" % (sensor, new_state))
import smtplib
smtpUser = 'rpigroupproject#gmail.com'
smtpPass = 'W1r3l355'
toAdd = 'rpigroupproject#gmail.com'
fromAdd = smtpUser
subject = 'ALERT!'
header = 'To: ' + toAdd + '\n' + 'From: ' + fromAdd + '\n' + 'Subject:' + subject
body = 'Motion was detected...'
print header + '\n' + body
s = smtplib.SMTP('smtp.gmail.com',587)
s.ehlo()
s.starttls()
s.ehlo()
s.login(smtpUser, smtpPass)
s.sendmail(fromAdd, toAdd, header + '\n' + body)
s.quit()
except:
GPIO.cleanup()
I'm not sure if you using a custom identation, but just for the sake of testing I would advice to reset any customization and use tabs.
For example, this is a sample of your code below. You can see that identation between try-while, and what follows while is not consistent
try:
while True:
time.sleep(0.1)
previous_state = current_state
current_state = GPIO.input(sensor)
This is how it looks with consistent identation:
try:
while True:
time.sleep(0.1)
previous_state = current_state
current_state = GPIO.input(sensor)

os not letting me save email attachment using pywin32

import win32com.client
import pythoncom
import time
import os
class Handler_Class(object):
def OnNewMailEx(self, receivedItemsIDs):
# RecrivedItemIDs is a collection of mail IDs separated by a ",".
# You know, sometimes more than 1 mail is received at the same moment.
for ID in receivedItemsIDs.split(","):
print('Running scan...')
mail = outlook.Session.GetItemFromID(ID)
email_date = mail.SentOn.strftime("%m-%d-%y" + " at " + "%I:%M:%S %p")
email_date_stamp = mail.SentOn.strftime('%m-%d-%y_%I:%M:%S-%p')
email_message = mail.Body
email_subject = mail.Subject
email_sender = mail.SenderEmailAddress
email_attachments = mail.Attachments
try:
if check_correct_subject(email_subject) == True:
print('From: ' + email_sender)
print('Subject: ' + email_subject)
print('Date: ' + email_date)
if email_attachments.Count > 0:
print(str(email_attachments.Count) + ' attachments found.')
for i in range(email_attachments.Count):
email_attachment = email_attachments.Item(i + 1)
report_name = email_date_stamp + '_' + email_attachment.FileName
print(report_name)
email_attachment.SaveASFile(os.getcwd() + '\\Reports\\Broker_Risk_LDW\\' + report_name)
print('Pushing attachment - ' + report_name + ' - to check_correct_email() function.')
if check_correct_attachment(email_attachment) == True:
save_incoming_report(email_attachment, report_name, get_report_directory(email_subject))
else:
print('Not the attachment we are looking for.')
# add error logging here
break
else: # ***********add error logging here**************
print('No attachment found.')
except:
pass
I am calling the class like this.
if __name__ == '__main__':
outlook = win32com.client.DispatchWithEvents("Outlook.Application", Handler_Class)
#and then an infinit loop that waits from events.
pythoncom.PumpMessages()
The problem here is this line: email_attachment.SaveASFile(os.getcwd() + '\\Reports\\Broker_Risk_LDW\\' + report_name)
That folder is already created and it was working before I switched this to a class, in order to work with an Outlook event listener. I am not getting an error message, however the attachment is not saving.
Any tips?

How to end a server socket listen

So what i'm trying to do is to make a multi-threaded server that creates threads for each client that connects to it, and replies back the string sent from the client.
It sort of works, but my server doesn't actually end properly. My KerboardInterrupt catch doesn't seem to work in windows command prompt, only thing that lets me exit the process would be ctrl + pause/break. Can anyone help me think of a way to get the server to end gracefully?
Server Code:
import socket
import threading
import time
import datetime
import sys
def getTime():
ts = time.time()
timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m- %d_%H:%M:%S')
return timeStamp
def ThreadFunction(clientsocket, clientaddr):
global ReceivedData
global SentData
while True:
#Receive data from client
data = clientsocket.recv(bufferSize)
#Get client IP and port
clientIP, clientSocket = clientsocket.getpeername()
#Add to total amount of data transfered
ReceiveDataSize = len(data)
ReceivedData += ReceiveDataSize
#LOg the received data
text_file.write(str(getTime()) + "__ Size of data received (" + clientIP + ":" + str(clientSocket) + ") = " + str(ReceiveDataSize) + '\n')
#Send data
clientsocket.send(data)
SentDataSize = len(data)
SentData += SentDataSize
#Log the sent data
text_file.write(str(getTime()) + "__ Size of data sent (" + clientIP + ":" + str(clientSocket) + ") = " + str(SentDataSize) + '\n')
def Close(counter, ReceivedData, SentData):
print ("Shutting down Server...")
serversocket.close()
text_file.write("\n\nTotal # of connections: " + str(counter))
text_file.write("\nTotal data received: " + str(ReceivedData))
text_file.write("\nTotal data sent: " + str(SentData))
text_file.close()
sys.exit()
if __name__ == '__main__':
serverIP = raw_input('Enter your server IP \n')
port = int(raw_input('What port would you like to use?\n'))
# Maintain how many connections
connections = []
counter = 0
# Maintain amount of data sent to and from server
ReceivedData = 0
SentData = 0
bufferSize = 1024
# Create and initialize the text file with the date in the filename in the logfiles directory
text_file = open("MultiThreadedServerLog.txt", "w")
address = (serverIP, port)
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind server to port
serversocket.bind(address)
# The listen backlog queue size
serversocket.listen(50)
print ("Server is listening for connections\n")
try:
while 1:
# Accept client connections, increment number of connections
clientsocket, clientaddr = serversocket.accept()
counter += 1
# Log client information
print (str(clientaddr) + " : " + " Just Connected. \n Currently connected clients: " + str(counter) + "\n")
text_file.write(str(getTime()) + " - " + str(clientaddr) + " : " + " Just Connected. \n Currently connected clients: " + str(counter) + "\n")
clientThread = threading.Thread(target=ThreadFunction, args=(clientsocket, clientaddr))
clientThread.start()
except KeyboardInterrupt:
print ("Keyboard interrupt occurred.")
Close(counter, ReceivedData, SentData)
Client Code:
from socket import *
import threading
import time
import random
import sys
import datetime
serverIP = ""
port = 8005
message = ""
msgMultiple = 1
def getTime():
ts = time.time()
timeStamp = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d_%H:%M:%S')
return timeStamp
def run(clientNumber):
buffer = 1024
global totalTime
s = socket(AF_INET, SOCK_STREAM)
s.connect((serverIP, port))
threadRTT = 0
while 1:
for _ in range(msgMultiple):
cData = message + " From: Client " + str(clientNumber)
# Start timer and send data
start = time.time()
s.send(cData.encode('utf-8'))
print "Sent: " + cData
# Stop timer when data is received
sData = s.recv(buffer)
end = time.time()
# Keep track of RTT and update total time
response_time = end - start
threadRTT += end - start
totalTime += response_time
print "Received: " + cData + '\n'
t = random.randint(0, 9)
time.sleep(t)
# Log information of Client
text_file.write(
"\nClient " + str(clientNumber) + " RTT time taken for " + str(msgMultiple) + " messages was: " + str(
threadRTT) + " seconds.")
threadRTT = 0
break
if __name__ == '__main__':
serverIP = raw_input('Enter the server IP: ')
port = int(input('Enter the port: '))
clients = int(input('Enter number of clients: '))
message = raw_input('Enter a message to send: ')
msgMultiple = int(input('Enter the number of times you would like to send the message: '))
# Initialize Log file
text_file = open("ClientLog.txt", "w")
# Used to maintain list of all running threads
threads = []
totalTime = 0
# Create a seperate thread for each client
for x in range(clients):
thread = threading.Thread(target=run, args=[x])
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
# Calculations for log data
bytes = sys.getsizeof(message)
totalRequests = clients * msgMultiple
totalBytes = totalRequests * bytes
averageRTT = totalTime / totalRequests
# Output data
print("Bytes sent in message was : " + str(bytes))
print("Total Data sent was : " + str(totalBytes) + " Bytes.")
print("Average RTT was : " + str(averageRTT) + " seconds.")
print("Requests was : " + str(totalRequests))
# Write data to log file
text_file.write("\n\n Bytes sent in message was : " + str(bytes))
text_file.write("\nTotal Data sent was : " + str(totalBytes) + " Bytes.")
text_file.write("\nAverage RTT was : " + str(averageRTT) + " seconds.")
text_file.write("\nRequests was : " + str(totalRequests))
Also if anyone else has any general improvements they would add to this code, let me know. I'm still pretty new at python, and still rough at it.
Here is the normal intended input i'm getting from my server.
But when it gets to the last client that connects, it starts to drag on for some reason.
The last picture, the inputs go on for the majority of the text file, for a very long time. Seems like something isn't ending properly.
Solved by adding an if statement that checks for a byte < 0 , if it is, end the socket.

Python Twitch IRC bot disconnecting after a period of time

So I have written a little bot that connects to twitch and is suppose to stay active till I close the script, but it seems after a elongated period of time the bot stops being connected to twitch and stops receiving anything. I think it is disconnecting, but I have no proof. Just the fact that it doesn't do anything after a while.
irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
irc.connect((server, port))
irc.send("PASS " + password + "\n")
irc.send("NICK " + name + "\n")
irc.send("JOIN " + channel + "\n")
def main():
while True:
data = irc.recv(1204)
data = data.strip('\r\n')
sendUsr = data.split(" ")
sendUsr = sendUsr[0]
sendUsr = sendUsr.split("!")
sendUsr = sendUsr[0]
sendUsr = sendUsr.strip(":")
print (data)
if data.find('PING') != -1 :
irc.send("PONG")
if data.find('PING') != -1 :
irc.send("PONG")
Needs to be changed to:
if data.find('PING')
irc.send("PONG :tmi.twitch.tv")
Try doing that & it should work.

Categories