Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
need pointers for creating a GUI (for arming/disarming motion alarm on my set of Foscam cameras)
-
I've written a script in Pythonista that allows me to arm/disarm the motion sensors on my 6 security cameras, as well as adjust sensitivity for detecting motion. It's pretty basic...it loops through my list of cameras and issues the command one at a time and then displays a result message. My cameras are located at my cabin in WV and are accessed through WildBlue satellite internet, so there is a bit of a lag when sending commands and receiving a response (~8-10 seconds for each camera). (For those unfamiliar with the nuances of satellite internet service, here's how it goes: Send command over internet, goes to Colorado where transmission station sends it 22,000 miles into space to satellite and then 22,000 miles back down to earth to the satellite dish at my cabin, hits my cabin network, executes action on camera, then repeats the trip back 22,000 miles up and back down to Colorado, and back onto the internet where it finally gets me the response. That's 88,000 miles of space travel and probably 3,500 miles on the internet.)
I'd like to create a GUI that lists each camera and then a column with a checkbox to arm/disarm each camera, and then another column with a slider bar to adjust sensitivity for that camera.
Once I get the basics done, then I'll make it a little more sophisticated with settings for Home, Away, and presence awareness (i.e. if I'm at the cabin, then turn off inside cameras), and automatically re-arm motion sensors x hours after I disable them.
In the meantime, what's the best way to construct this GUI? In Pythonista, HTML or something else?
-
Yeah your best bet is html, manually constructing a gui however would be harder but more rewarding
-
I've built a GUI framework for Pythonista that does some of the hard work for you.
Framework : https://gist.github.com/BashedCrab/5924965
Demo GUI : https://gist.github.com/BashedCrab/5953776
It already has sliders and checkboxes (iOS style switches) implemented for you. If you need a hand getting started I can very quicky code up a GUI skeleton for your app for you to experiment with.
I'll also be releasing an update soon that has much improved rendering performance.
-
Awesome. I'll check out the framework and GUI tonight.
(And thanks for the offer to create a GUI skeleton. I'm sure I'll take you up on it at some point, but let me play with the code you've provided so far. This is a bit fun for me to get into.)
-
bashedcrab,
Is the offer still available for you to create the GUI skeleton? If so, here's a draft of how it would look
Camera Name Arm/Disarm Sensitivity
Cam 1 [switch component] [slider component]
Cam 2 [switch component] [slider component]
Cam 3 [switch component] [slider component]
Cam 4 [switch component] [slider component]
Cam 5 [switch component] [slider component]
Cam 6 [switch component] [slider component]I'll have to do some things like query the cameras on first running the program to get current settings, and freeze a component until the setting is made and confirmed. But getting this layout will be a big help. (I'm better at the workflow logic than on the GUI)
-
Grab the latest version of Hydrogen & HydrogenLayouts, then have a play with HCameraApp
Hydrogen - https://gist.github.com/BashedCrab/5924965
HydrogenLayouts - https://gist.github.com/BashedCrab/6103019
HCameraApp - https://gist.github.com/anonymous/6110768
I probably could have made it shorter/simpler, but I wanted it to look nice. It was very quick to code as it's mainly cut & pasted from the demo.
-
Is there a way to "collect" several commands and submit once, rather than wait for each command to execute? With the satellite internet latency of 8-10 seconds round trip, it could take a long time to make configuration changes to several cameras one at a time.
My UI would construct the commands as follows:
http://camera1.com:8080/set_alarm.cgi?motion_armed=0?motion_sensitivity=5
http://camera2.com:8080/set_alarm.cgi?motion_armed=1?motion_sensitivity=6
http://camera3.com:8080/set_alarm.cgi?motion_armed=0?motion_sensitivity=2and then to check/verify settings:
http://camera1.com:8080/get_params.cgi?http://camera2.com:8080/get_params.cgi?http://camera3.com:8080/get_params.cgi? -
When you are looking for "separate threads of execution", the threading module becomes your friend...
<pre>from threading import Thread
from datetime import datetime
from collections import namedtuple
from time import sleepCameraConfig = namedtuple('CameraConfig', 'id armed sensitivity')
theCameras = (CameraConfig(1, 0, 5),
CameraConfig(2, 1, 6),
CameraConfig(3, 0, 2))class CameraConfigThread(Thread):
def init(self, inCameraConfig):
#Thread.init(self)
super(self.class, self).init() # only works with single inheritance
self.cameraConfig = inCameraConfigdef run(self): theName = self.getName() theURL = 'http://camera{id}.com:8080/set_alarm.cgi?motion_armed={armed}?motion_sensitivity={sensitivity}'.format(**self.cameraConfig._asdict()) fmt = '{} doing {} at {}\n Using URL: {}\n' print(fmt.format(theName, self.cameraConfig, datetime.now(), theURL)) for i in xrange(5): sleep(1) print('{}: i = {}'.format(theName, i))
theThreads = [] # empty list
for theCamera in theCameras:
theThread = CameraConfigThread(theCamera)
theThread.start()
theThreads.append(theThread)
#theThread.join() # calling join() at this point would causes the app to pause until this thread completes before launching the next one. This is NOT what we want.now that all threads are running pause the app until they all complete
for theThread in theThreads:
if theThread.is_alive():
theThread.join() # pause the main app thread until the thread completes
else:
print('{} is no longer alive at join time.'.format(theThread.getName()))
print('\nAll threads have completed.\n')fmt = 'Check results using: http://camera{id}.com:8080/get_params.cgi?'
for theCamera in theCameras:
print(fmt.format(**theCamera._asdict()))print('=' * 60)</pre>