Page 2 of 3

Re: Once again down that hole

PostPosted: Tue Jun 12, 2018 7:34 pm
by Different Computers
So very very close, AND I've greatly simplified the mess.

But (and there's always a but) I have a problem with what I think is effectively simultaneous execution. The first part of my script takes time, because it involves network activities:
Code: Select all
from PIL import Image
import subprocess
import time
pic_destination = "/Library/Application Support/Perceptive Automation/Indigo 7/IndigoWebServer/public/whatever.PNG"
subprocess.Popen("wget --user name --password value --no-check-certificate 192.168.999.999/cgi-bin/currentpic.cgi -O /Library/Application\ Support/Perceptive\ Automation/Indigo\ 7/IndigoWebServer/whatever.PNG", shell=True)


But as I think I read somewhere, Python executes everything as fast as it can, rather than in order. So any time I've run this after the first, this part acts on the previous image before the new image is saved:
Code: Select all
time.sleep(5). <--------even with this ridiculous value
pic = Image.open(pic_destination)
pic.save("/Library/Application Support/Perceptive Automation/Indigo 7/IndigoWebServer/public/whatever.PNG", optimize=True, quality=80, format='PNG')


To be clear, I'm grabbing an image from the camera, and then want to reduce its quality and size. Right now, the action group is reducing the PREVIOUS image, which is then overwritten immediately by the new image. I know this because I'm watching that Finder directory, and when I run this, the old image drops in size by 70 % or so, and then is overwritten.

But now I'm doubly confused because I just read this suggesting Python executes from top to bottom.

Re: Once again down that hole

PostPosted: Tue Jun 12, 2018 8:35 pm
by berkinet
Try something like this...
foo = subprocess.Popen(“command.....
foo.wait

Re: Once again down that hole

PostPosted: Thu Jun 14, 2018 8:33 am
by Different Computers
foo.wait seems to have gotten me to the point where I could troubleshoot my other issues.

I still see some weird timing stuff happening, but between adding .wait and sleep commands, it is now working!

Many thanks to everyone who commented.

Oh, and for those wondering, this code integrates, at a very basic level for now, the Wyze V2 camera and the Wyze Cam Pan with the Xiomi/Dafang hacked firmware. With the hack, these cameras are an extraordinary value/feature combination that I highly recommend. Excellent images, full-featured. In fact, most of this Python was needed because the images were too high quality straight from the cameras, and needed to be stepped down for IWS to serve them over the reflector!

Re: Once again down that hole

PostPosted: Tue Jun 25, 2019 10:13 am
by Different Computers
Weirdly, I have to resurrect this thread.

I had to totally reset one of the cameras, and since then the wget script to grab the image from the camera has stopped working.

Here's what I know:

IP address of the reset camera, and the user name/pwd are the same as they were.
The wget command works at the command line.
The second half of the script, which converts the large image from the camera into a smaller image that IndigoWebServer can serve, still works.
I can reach the camera from the Indigo box, and have re-authorized the camera's self signed certificate.

What's not working is the wget. BUT the script does NOT return any errors. It just isn't working to grab a new image. the second half works to convert any existing image.

Here's the script:
Code: Select all
from PIL import Image
import math
import subprocess
import time

pic_destination = "/Library/Application Support/Perceptive Automation/Indigo 7.3/IndigoWebServer/public/FOO/FYBig.jpg"
get_image = subprocess.Popen("wget --user NAME --password BOGUS --no-check-certificate 192.168.0.66/cgi-bin/currentpic.cgi -O /Library/Application Support/Perceptive Automation/Indigo 7.3/IndigoWebServer/public/FOO/FYBig.jpg", shell=True)
get_image.wait

Image.open(pic_destination)
time.sleep(2)
saved_pic = Image.open(pic_destination)
#width, height = saved_pic.size
#width = width*.59
#height = height*.59
#saved_pic.resize((int(math.floor(width)), int(math.floor(height))), Image.ANTIALIAS)
saved_pic.save("/Library/Application Support/Perceptive Automation/Indigo 7.3/IndigoWebServer/public/FOO/FY.jpg", optimize=True)


I have 2 other versions of this script running without problems on nearly identical cameras. When I run
Code: Select all
wget --user NAME --password BOGUS --no-check-certificate 192.168.0.66/cgi-bin/currentpic.cgi
at the command line, I get current pic.cgi in my documents root folder.

So is there some sort of python environment issue where it for some reason is still not trusting the connection, even though the bash does? Here's what the command line returns:
Code: Select all
Indigo:~ name$ wget --user NAME --password PWD --no-check-certificate 192.168.0.66/cgi-bin/currentpic.cgi
--2019-06-25 11:12:27--  http://192.168.0.66/cgi-bin/currentpic.cgi
Connecting to 192.168.0.66:80... connected.
HTTP request sent, awaiting response... 401 Unauthorized
Authentication selected: Basic realm="all", charset="UTF-8"
Reusing existing connection to 192.168.0.66:80.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://192.168.0.66/cgi-bin/currentpic.cgi [following]
--2019-06-25 11:12:27--  https://192.168.0.66/cgi-bin/currentpic.cgi
Connecting to 192.168.0.66:443... connected.
WARNING: cannot verify 192.168.0.66's certificate, issued by ‘emailAddress=...,CN=...,OU=...,O=...,L=Munich,ST=Bavaria,C=DE’:
  Self-signed certificate encountered.
    WARNING: certificate common name ‘...’ doesn't match requested host name ‘192.168.0.66’.
HTTP request sent, awaiting response... 200 OK
Length: 117879 (115K) [image/jpeg]
Saving to: ‘currentpic.cgi.1’

currentpic.cgi.1    100%[===================>] 115.12K   163KB/s    in 0.7s   

2019-06-25 11:12:28 (163 KB/s) - ‘currentpic.cgi.1’ saved [117879/117879]


I'm going to try deleting the stored certificate. In the mean time, thanks for any help.

Re: Once again down that hole

PostPosted: Wed Jun 26, 2019 9:00 am
by jay (support)
Remind me again why you're using wget rather than just getting the image directly in Python using the requests lib?

Re: Once again down that hole

PostPosted: Wed Jun 26, 2019 11:07 am
by Different Computers
I really don't recall. Probably because:

1. I knew more or less how wget works
2. I didn't know how requests works or couldn't figure out the syntax for getting it to do all the options that wget does and are required.

I've tried deleting the certificates in the Keychain, and nothing changed.

Re: Once again down that hole

PostPosted: Thu Jun 27, 2019 9:27 am
by jay (support)
I think this should get you on your way using requests:

Code: Select all
import requests
from PIL import Image
from io import BytesIO

reply = requests.get('https://192.168.0.66/cgi-bin/currentpic.cgi', auth=('user', 'pass'), verify=False)
saved_pic = Image.open(BytesIO(reply.content))


Not tested, so it's likely I have something wrong, but it should be pretty close (this example is almost directly from the requests documentation). Hopefully you'll get better response error feedback to help figure out what's going wrong.

Re: Once again down that hole

PostPosted: Thu Jun 27, 2019 11:02 am
by Different Computers
Thanks! I'll give it a try.

Re: Once again down that hole

PostPosted: Thu Jun 27, 2019 11:23 am
by Different Computers
OK, got past the first hurdle, which was remembering what to do with 'user' and 'password'. Looks like it's addressing the camera correctly and then fails to properly place or pick back up the data.

I *think* I don't understand some of the flow of this script, and have a mismatch of variable names. I get a error result of "'JpegImageFile' object has no attribute 'read'".

edit:

worked through the mess that was my code and figured out how your suggested code needed to fit in. Looks like this for anyone who might need this:
Code: Select all
from PIL import Image
import math
import subprocess
import time
import requests
from io import BytesIO

pic_destination = "/Library/Application Support/Perceptive Automation/Indigo 7.3/IndigoWebServer/public/FOO/GROOMpython.jpg"
reply = requests.get('https://192.168.0.66/cgi-bin/currentpic.cgi', auth=('user', 'pass'), verify=False)
saved_pic = Image.open(BytesIO(reply.content))
time.sleep(2) # maybe not needed depending on your camera/network speed
saved_pic.save("/Library/Application Support/Perceptive Automation/Indigo 7.3/IndigoWebServer/public/FOO/GRpython.jpg", optimize=True)


Thanks very much!

Re: Once again down that hole

PostPosted: Thu Jun 27, 2019 12:46 pm
by jay (support)
So, is it working?

Re: Once again down that hole

PostPosted: Thu Jun 27, 2019 4:12 pm
by howartp
Jay, what’s the $indigo_path py command that DC can use instead of hard coding /library/........indigo 7.3/...


Sent from my iPhone using Tapatalk Pro

Re: Once again down that hole

PostPosted: Thu Jun 27, 2019 4:14 pm
by howartp
Also DC, you’ve defined pic_destination but then hardcoded the path instead of using the pic_destination variable you defined.


Sent from my iPhone using Tapatalk Pro

Re: Once again down that hole

PostPosted: Thu Jun 27, 2019 5:07 pm
by jay (support)
getInstallFolderPath

So, something like:

Code: Select all
pic_destination = "{}/IndigoWebServer/public/FOO/GROOMpython.jpg".format(indigo.server.getInstallFolderPath())

Re: Once again down that hole

PostPosted: Fri Jun 28, 2019 12:20 am
by howartp
Cheers.

I knew you’d get there quicker and easier than me on phone.

I can never remember the command, or find it in the docs because I can’t remember the name to search it!


Sent from my iPhone using Tapatalk Pro

Re: Once again down that hole

PostPosted: Fri Jun 28, 2019 8:04 am
by Different Computers
You're right I did.

So it should be
Code: Select all
saved_pic.save(pic_destination, optimize=True)
right? Or is it supposed to be
Code: Select all
saved_pic.save("pic_destination", optimize=True)


And yes, thank you Jay, it's working. And it seems faster than using wget. I was able to reduce the wait states, and even went ahead and changed all the other cameras over to use this new code.