Hi all,
I’m trying to run a python script in HA, I created the folder in my repository and insert the code in cofiguration.yaml (python_script:).
If I run the script with “thonny, Python IDE” it run with no problems.
In HA I found the service “python_script.campanello2” but if I click “call service” nothing happens…
This is the LOG:
Error executing script: __import__ not found
Traceback (most recent call last):
File "/srv/homeassistant/lib/python3.8/site-packages/homeassistant/components/python_script/__init__.py", line 217, in execute
exec(compiled.code, restricted_globals)
File "campanello2.py", line 1, in <module>
ImportError: __import__ not found
Basically it’s a script that take a picture from the ip camera and sends it to email:
import requests
import shutil
import os
import smtplib
import RPi.GPIO as GPIO
import time
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
# This is the image url.
image_url = 'http://192.168.0.19/tmpfs/auto.jpg/'
username = ''
password = '!!'
#Email Variables
SMTP_SERVER = 'smtp.gmail.com' #Email Server (don't change!)
SMTP_PORT = 587 #Server Port (don't change!)
GMAIL_USERNAME = '[email protected]' #change this to match your gmail account
GMAIL_PASSWORD = 'c' #change this to match your gmail password
#Set GPIO pins to use BCM pin numbers
GPIO.setmode(GPIO.BCM)
#Set digital pin 17(BCM) to an input
GPIO.setup(17, GPIO.IN)
#Set digital pin 17(BCM) to an input and enable the pullup
GPIO.setup(17, GPIO.IN)#, pull_up_down=GPIO.PUD_UP)
#Event to detect button press
GPIO.add_event_detect(17, GPIO.FALLING)
class Emailer:
def sendmail(self, recipient, subject, content, image):
#Create Headers
emailData = MIMEMultipart()
emailData['Subject'] = subject
emailData['To'] = recipient
emailData['From'] = GMAIL_USERNAME
#Attach our text data
emailData.attach(MIMEText(content))
#Create our Image Data from the defined image
imageData = MIMEImage(open(image, 'rb').read(), 'jpg')
imageData.add_header('Content-Disposition', 'attachment; filename="image.jpg"')
emailData.attach(imageData)
#Connect to Gmail Server
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo()
#Login to Gmail
session.login(GMAIL_USERNAME, GMAIL_PASSWORD)
#Send Email & Exit
session.sendmail(GMAIL_USERNAME, recipient, emailData.as_string())
session.quit
sender = Emailer()
time.sleep(1.5)
# Open the url image, set stream to True, this will return the stream content.
resp = requests.get(image_url, auth=(username, password), stream=True)
# Open a local file with wb ( write binary ) permission.
local_file = open('/home/pi/Desktop/LOGcampanello/cam.jpg', 'wb')
# Set decode_content value to True, otherwise the downloaded image file's size will be zero.
resp.raw.decode_content = True
# Copy the response stream raw data to local image file.
shutil.copyfileobj(resp.raw, local_file)
# Remove the image url response object.
del resp
#creo il file con l'orario come nome
new_filename='/home/pi/Desktop/LOGcampanello/'+ time.strftime("%d%m%Y-%H:%M:%S.jpg")
#rinomino il file scaricato dalla telecamera
os.rename("/home/pi/Desktop/LOGcampanello/cam.jpg", new_filename)
#invio mail
emailSubject = "Campanello"
emailContent = "Hanno suonato alle: " + time.ctime()
sender.sendmail('[email protected]', emailSubject, emailContent, new_filename)
print("Email1 Sent")
sender.sendmail('[email protected]', emailSubject, emailContent, new_filename)
print("Email2 Sent")
time.sleep(6)
Yep - @ludeeus is spot on. While Python scripts are very powerful to use, they are limited - i.e., no imports. You have what you have. For those situations I use AppDaemon.
Thanks to all, I installed pyscript by HACS…
In HA logs I see this error: Exception in </home/homeassistant/.homeassistant/pyscript/campanello2.py> line 50: local_file = open("/home/pi/Desktop/LOGcampanello/cam.jpg", 'wb') ^ NameError: name 'open' is not defined
But if I run the script with Thonny python IDE I don’ have errors…
pyscript, out of the box, does not allow any blocking calls (like open) as they would block all of Home Assistant. Reading a file in has to be done in a slightly different way.
Here’s a quick chunk of untested code that should get you started (only works with “master” version of pyscript since pyscript_compile is fairly new):
@pyscript_compile
def blocking_read_file(filename):
f = open(filename, "r")
data = f.read()
f.close()
return data
def read_file(filename):
x = task.executor(blocking_read_file, filename)
return x
def somefunction():
file_contents = read_file("/home/pi/Desktop/LOGcampanello/cam.jpg")
thanks for your help… Honestly I think to discard the idea to runs the script by an automation of HA. Now the script runs as service and it executes when a GPIO event occours…
But honestly I have trouble programming in Python…
I created the code joining various script found on the net, and it works (but i don’t understand it completely)
resp = requests.get(image_url, auth=(username, password), stream=True)
# Open a local file with wb ( write binary ) permission.
local_file = open('/home/pi/Desktop/LOGcampanello/cam.jpg', 'wb')
# Set decode_content value to True, otherwise the downloaded image file's size will be zero.
resp.raw.decode_content = True
# Copy the response stream raw data to local image file.
shutil.copyfileobj(resp.raw, local_file)
# Remove the image url response object.
del resp
#creo il file con l'orario come nome
new_filename='/home/pi/Desktop/LOGcampanello/'+ time.strftime("%d%m%Y-%H:%M:%S.jpg")
#rinomino il file scaricato dalla telecamera
os.rename("/home/pi/Desktop/LOGcampanello/cam.jpg", new_filename)
#invio mail
emailSubject = "Campanello"
emailContent = "Hanno suonato alle: " + time.ctime()
sender.sendmail('[email protected]', emailSubject, emailContent, new_filename)
print("Email1 Sent")
Maybe the code could easily “repaired” but I don’t able to do this…