Update script being used as presence detection. Previously would take arguments for -s and -b (switch and bluetooth) and only check 1 device. Required multiple cron entries, 1 for each device. This could lead to polling issues if more devices are added. This new script “Should” only poll once for all devices. There’s a pause when it’s searching for the first device but consecutive devices fly through so I think it’s working.
Python Script saved in /home/domoticz/domoticz/bluetooth/bluescan.py
#!/usr/bin/python
import bluetooth
import time
import argparse
import urllib
import urllib2
import json
parser = argparse.ArgumentParser(description='SwitchID BluetoothID')
parser.add_argument('-l', '--link', action='append', help='BluetoothMac-SwitchID', required=True)
parser.add_argument('-d', '--debug', help='Debug Output', required=False, action='store_true')
parser.add_argument('-u', '--updatefound', help='Always update Found Devices', required=False, action='store_true')
args = parser.parse_args()
def update_switch(args, switchid, status):
URL="http://127.0.0.1/json.htm?username=YWRtaW4=&password=ZG9tb3RpY3o=&type=command&param=switchlight&idx={0}&switchcmd={1}".format( switchid, status )
if args.debug:
print URL
request = urllib2.Request(URL)
response = urllib2.urlopen(request)
return response.read()
if args.debug:
print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
for value in args.link:
s = value.split("-")
blueid, switchid = s[0], s[1]
if args.debug:
print ("Switch ID: %s" %switchid )
print ("Bluetooth ID: %s" %blueid )
#Get the current status
URL="http://127.0.0.1/json.htm?username=YWRtaW4=&password=ZG9tb3RpY3o=&type=devices&rid={0}".format( switchid )
if args.debug:
print URL
response = urllib2.urlopen(URL)
json_data = json.load(response)
current_status = json_data['result'][0]['Status']
if args.debug:
print ("Current Status: %s" %current_status )
result = bluetooth.lookup_name(blueid, timeout=10)
if (result != None):
if args.debug:
print "Found"
# status = 1
status = "On"
else:
if args.debug:
print "NOT Found"
# status = 0
status = "Off"
if current_status == status:
if args.debug:
print "Status UnChanged"
if status=="On" and args.updatefound:
update = update_switch( args, switchid, status )
if args.debug:
print update
else:
update = update_switch( args, switchid, status )
if args.debug:
print update
Had to us – as separator. : in mac address would be confusing, tried ; but conflicts with bash, was going to use a space but would need to account for that in the argument parser and – was just easier.
Yesterday I received my Barcode scanner, after a little playing scanning everything in sight I got to work on programming a Raspberry PI in Python to use the barcode scanner to update orders in WooCommerce.
I’m not going to go into full details in this post on how. but I will write it up soon.
A BIG problem I hit though was updating orders using the WooCommerce API. I kept getting error code 400 ‘No order data specified to edit order’. I’d followed the example but changed it to fit my code i.e dont print the output but return it for error checking.
Searching google for that exact phrase gave just 1 result, and it’s someone commenting they are getting the error with no response (and it’s 4 months old on a 2 year old post).
After looking through the API code and trying to follow along (I’m not the best programmer but I can generally follow what it’s trying). I found it looking for ‘order’
So after looking at how the bulk update is done and with a bit of playing I found that instead of
data = {'status': 'completed'}
you need
data = {"order":{"status":"completed"}}
Hey Presto it works. My specific code is now
def WooCommerceUpdateOrder(order, data):
global wcapi
putstring = "orders/%s" % order
result = wcapi.put(putstring, data)
return result
Hope this helps someone. I’ll post the full python program for the barcode reader later in the week. Basically it uses a PI, PI LCD Screen with 4 buttons, Barcode Reader, Speakers. 🙂
I’ve been using wview with my WH1080 weather station for some time (actually 2 of them). My main setup has been using my server, and every now and again the WH1080 would seem to lock up and nothing could get data out of it. The solution was to drop it’s power, on reboot it would all start working again.
However wview also seemed to introduce lockups of it’s own and the only solution there was to reboot the server (not ideal). So when it came to setting up a second weather station (in a remote location) I needed something a bit more stable and started looking at alternatives. I was doing this on a Raspberry PI and found wview. After installing it sometime last year it seemed pretty stable (although the WH1080 still manages to lockup).
Back to my house and I’ve finally had enough of missing weather data. One thing I really liked with wview was the ability to pull the archive data if the weather station had been running when the machine hadn’t (providing the USB hadn’t locked up), I really recommend looking at wview if your starting out.
I’ve already covered setting up weewx on a Raspberry PI and I’m not going to post about my exact configuration here. Instead I’m going to share my Python code for displaying the various graphs and gauges straight to the TV. At the moment I have my weather PI connected to the TV via HDMI. This may change later and then I’ll have to adjust the code to pull the images to another pi before displaying them (I have a similar project for displaying webcams already).
So a few things before the code.
It’s my first real attempt at using classes, so my code will be more than a little scattered.
You need to have python, pygame, wview, (and for this exact code Bootstrap for wview but you could just change the file paths to the Standard guages and graphs), mysql and wview configured for mysql.
I have this started using an init script (added below).
This runs the python program as root, I need to find a way to run this as a normal user (but that will affect point 5&6).
This program checks mysql is able to be connected to and restarts mysql of not.
It also checks the freshness of the index.html file (not the best way but a quick way) to make sure wview is running keeping the files upto date. If not it reboot the PI, this causes the weather station to reboot so if the USB locks up the whole system resets fixing it.
So now onto the python code
#!/usr/bin/python
import os
import time
import pygame
import MySQLdb as mdb
import signal
import sys
imglocation = "/var/www/weewx/Bootstrap"
class pyscreen :
screen = None;
def __init__(self):
"Initializes a new pygame screen using the framebuffer"
disp_no = os.getenv("DISPLAY")
if disp_no:
print "I'm running under X display = {0}".format(disp_no)
# Check which framebuffer drivers are available.
drivers = ['fbcon', 'directfb', 'svgalib']
found = False
for driver in drivers:
# Make sure that SDL_VIDEODRIVER is set
if not os.getenv('SDL_VIDEODRIVER'):
os.putenv('SDL_VIDEODRIVER', driver)
try:
pygame.display.init()
except pygame.error:
print 'Driver: {0} failed.'.format(driver)
continue
found = True
break
if not found:
raise Exception('No suitable video driver found!')
size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
print "Framebuffer size: %d x %d" % (size[0], size[1])
self.screen = pygame.display.set_mode(size, pygame.FULLSCREEN)
pygame.mouse.set_visible(False)
# Clear the screen to start
self.screen.fill((0, 0, 0))
# Initialise font support
pygame.font.init()
# Render the screen
pygame.display.update()
def __del__(self):
"Destructor to make sure pygame shuts down, etc."
def size(self):
size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
return size
def fill(self, colour):
if self.screen.get_at((0,0)) != colour:
self.screen.fill((0, 0, 0))
self.screen.fill(colour)
pygame.display.update()
def image(self, img, locX, locY, sizX, sizY):
try:
if (( "week" not in img) and (os.stat(img).st_mtime > time.time() - 600)):
# 600 = 10 mins.
image = pygame.image.load(img)
image = pygame.transform.scale(image, (sizX, sizY))
self.screen.blit(image, (locX, locY))
elif(( "week" in img) and (os.stat(img).st_mtime > time.time() - 7200)):
# 7200 = 2 hours.
image = pygame.image.load(img)
image = pygame.transform.scale(image, (sizX, sizY))
self.screen.blit(image, (locX, locY))
else:
pygame.draw.rect(self.screen, (255, 0, 0), (locX, locY, sizX, sizY), 0)
except pygame.error, message:
pygame.draw.rect(self.screen, (255, 0, 0), (locX, locY, sizX, sizY), 0)
pygame.display.update()
def text_object(self, msg, font):
black = (0, 0, 0)
textSurface = font.render(msg, True, black)
return textSurface, textSurface.get_rect()
def error(self, msg):
largeText = pygame.font.Font('freesansbold.ttf', 115)
TextSurf, TextRect = screeny.text_object(msg, largeText)
size = screeny.size
TextRect.center = ((pygame.display.Info().current_w/2),(pygame.display.Info().current_h/2))
self.screen.blit(TextSurf, TextRect)
pygame.display.update()
class fileman:
global imglocation
def __init__(self):
"Init for fileman. Nothing to do atm."
def __del__(self):
"Destructor for fileman. Nothing to do again."
def total_files(self):
count=0
for file in os.listdir(imglocation):
if file.endswith(".png"):
count=count+1
return count
class sqly:
def __init__(self):
"do nothing"
def test(self):
try:
con = mdb.connect('localhost', 'weewx', 'weewx', 'weather')
cur = con.cursor()
cur.execute("SELECT VERSION()")
ver = cur.fetchone()
return 0
except mdb.Error, e:
return 1
finally:
"do nothing"
def restart(self):
#wait 30 secs and try the connection again.
time.sleep(30)
if not mysql_con.test():
try:
os.system("service mysql start")
except:
"do nothing"
def sigterm_handler(_signo, _stack_frame):
"When sysvinit send the TERM signal, cleanup before exiting"
print("[" + get_now() + "] received signal {}, exiting...".format(_signo))
sys.exit(0)
signal.signal(signal.SIGTERM, sigterm_handler)
def reboot():
"check if we've been reboot in the last 30 mins"
uptimef = open("/proc/uptime", "r")
uptimestr = uptimef.read()
uptimelst = uptimestr.split()
uptimef.close()
if float(uptimelst[0]) < 1800:
"We've reboot in the last 30 mins, ignoring"
else:
try:
os.system("reboot")
except:
"do nothing"
if __name__ == "__main__":
try:
screeny = pyscreen()
filey = fileman()
screeny.fill((0, 0, 255))
size = screeny.size()
border = 7
sizewquarter = ((size[0]-(border*5))/4)
sizehthird = ((size[1]-(border*4))/3)
print("Total files : %d" % (filey.total_files()))
while 1:
mysql_con = sqly()
if mysql_con.test():
screeny.fill((250, 0, 0))
screeny.error("Database Offline. Restarting!")
mysql_con.restart()
elif (os.stat("/var/www/weewx/Bootstrap/index.html").st_mtime < time.time() - 600):
screeny.fill((254, 0, 0))
screeny.error("NOT Updating. Reboot Imminent!")
reboot()
else:
screeny.fill((0, 0, 255))
screeny.image("/var/www/weewx/Bootstrap/barometerGauge.png", (border*1), (border*1), sizewquarter, sizehthird)
screeny.image("/var/www/weewx/Bootstrap/outTempGauge.png", ((border*2)+(sizewquarter*1)), (border*1), sizewquarter, sizehthird)
screeny.image("/var/www/weewx/Bootstrap/windDirGauge.png", ((border*3)+(sizewquarter*2)), (border*1), sizewquarter, sizehthird)
screeny.image("/var/www/weewx/Bootstrap/windSpeedGauge.png", ((border*4)+(sizewquarter*3)), (border*1), sizewquarter, sizehthird)
screeny.image("/var/www/weewx/Bootstrap/big_images/weekbarometer-Bootstrap.png", (border*1), ((border*2)+(sizehthird*1)), ((sizewquarter*2)+(border*1)), sizehthird)
screeny.image("/var/www/weewx/Bootstrap/big_images/weektempchill-Bootstrap.png", (border*1), ((border*3)+(sizehthird*2)), ((sizewquarter*2)+(border*1)), sizehthird)
screeny.image("/var/www/weewx/Bootstrap/big_images/weekwinddir-Bootstrap.png", ((border*3)+(sizewquarter*2)), ((border*2)+(sizehthird*1)), ((sizewquarter*2)+(border*1)), sizehthird)
screeny.image("/var/www/weewx/Bootstrap/big_images/weekwind-Bootstrap.png", ((border*3)+(sizewquarter*2)), ((border*3)+(sizehthird*2)), ((sizewquarter*2)+(border*1)), sizehthird)
time.sleep(1)
except KeyboardInterrupt:
"We've got an interupt"
and now the init.d code
#!/bin/sh
#
# init script for displayweewx
#
### BEGIN INIT INFO
# Provides: displayweewx
# Required-Start: $syslog $network
# Required-Stop: $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: init script to display weewx charts via HDMI output
# Description: The python script queries mysql and file ages, so does not rely on mysql as a backup way to kick it.
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NAME=displayweewx
DAEMON=/root/displayweewx/main.py
DAEMONARGS=""
PIDFILE=/var/run/$NAME.pid
LOGFILE=/var/log/$NAME.log
. /lib/lsb/init-functions
test -f $DAEMON || exit 0
case "$1" in
start)
start-stop-daemon --start --background \
--pidfile $PIDFILE --make-pidfile --startas /bin/bash \
-- -c "exec stdbuf -oL -eL $DAEMON $DAEMONARGS > $LOGFILE 2>&1"
log_end_msg $?
;;
stop)
start-stop-daemon --stop --pidfile $PIDFILE
log_end_msg $?
rm -f $PIDFILE
;;
restart)
$0 stop
$0 start
;;
status)
start-stop-daemon --status --pidfile $PIDFILE
log_end_msg $?
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 2
;;
esac
exit 0
Just a very quick post. I’m working on a small project I’ve had in mind for a few months, basically pull and image and display it on the tv (there’s more to it, or I’d just settle for RasBMC).
So I’ve been coding it all up using python with pygame to display the image, all fine.
Then I introduced loops to refresh the images, and update the display. I had issues around other code and couldn’t keep looking at the tv while the code was running so I introduced a few mp3’s to play as the images were being refreshed and as the display was updating. All worked well, it sounded like I was on the Enterprise.
Further into coding up different functions, and some more headaches I’d cleared up alot of the minor error’s I had been getting, and was now ready to push the system to speed up the refreshes.
I’d managed to put a few images to refresh every second, and it appeared to be going well. Then it stopped making a sound, checked and python had crashed with error: glibc detected *** /usr/bin/python: double free or corruption (fasttop)
So I changed the code I’d been working on (clearly that’s the problem, didn’t have this earlier), but nope didn’t solve it. Onto google, but this brought up alot of big reports about other things. checked a few, made a few changes. but I’m still getting the problem. Troubling though, if this is going to come down to the fact I’m refreshing alot and it’s getting intensive, it’s going to be a show stopper for this project.
Now I dont have the same problem (playing wav’s) but this drew me to the fact I’m playing mp3’s and these have increased in how much I’m playing them and they now overlap alot more than earlier.
So I decided to drop them out. Eureka it’s been running about 15 minutes and not died (previously a few minutes), sad thing is I’m now kinda missing my beeps. I had hoped to be able to play an alert sound, if certain events happened so I may have to rethink how I can do so without causing crashes.
Anyways there it is in case it’s of help to someone else. I’ll be posting about the project at a later date, once I’ve done a little more with the code and tested it a bit more. It’s my first serious attempt in python, I can make programmers cry at the best of times so I’m expecting people to be able to rip this apart (but I’m actually very interested in getting it stable, so will welcome the criticism/ideas.
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish.Accept
Privacy & Cookies Policy
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.