我有一个XBMC盒子连接到我的电视。另外,我有2台Foscam IP摄像机,我用它来监控我的两个小女孩。
前段时间我觉得编写几个脚本很酷,所以当其中一个Foscam的警报触发时,我会收到有关XBMC的通知以及来自相关Foscam的实时图像相机。有了这个,我可以看电视,同时密切关注孩子们。
因此,在XBMC盒子上我运行了一个shell脚本,每秒检查一次Foscam警报状态。如果触发了警报,它会向XBMC发送命令以触发XBMC脚本,暂停其检查30秒,然后继续检查警报状态。 XBMC脚本显示一个30秒的通知,其中包含我的一个女儿的名字(取决于触发的相机)和它们的可爱图片,以及来自相关Foscam的实时快照,每半秒更新一次。
这一切都运行得非常好,并且非常棒:)但是,上周我升级了Foscam的固件。新固件(固件说明中提到)中的唯一更改是将相机的HTTP
授权方法从basic
更改为digest
。从那时起,我的XBMC脚本出现了问题。
首先,这是脚本的当前版本:
# Import the XBMC/XBMCGUI modules.
from requests.auth import HTTPDigestAuth
import xbmc, xbmcgui, xbmcvfs, xbmcaddon
import sys, os, requests, time
# Class to manage the notification image
class CamView(xbmcgui.WindowDialog):
urlpath = "/snapshot.cgi?resolution=16"
imagename = "snapshot.jpg"
def __init__(self, camname,camport,idx,username,password):
# Construct correct URL
self.baseurl = 'http://' + camname + 'cam:' + camport
# Cams use digest authentication
self.auth = HTTPDigestAuth(username, password)
# Set
path = xbmc.translatePath('special://profile/addon_data/%s' % xbmcaddon.Addon().getAddonInfo('id'))
if not xbmcvfs.exists(path):
xbmcvfs.mkdir(path)
self.imagefile = os.path.join(path, self.imagename)
# Message
self.msg = {
"1": camname.capitalize() + ' moved',
"3": camname.capitalize() + ' made a sound',
}.get(idx, camname.capitalize() + 'cam fired alarm')
# set the initial image before the window is shown
self.image = xbmcgui.ControlImage(870, 383, 380, 253, "")
self.addControl(self.image)
def update_image(self):
f = requests.get(self.baseurl+self.urlpath, auth=self.auth)
with open(self.imagefile, "wb") as local_file:
local_file.write(f.content)
self.image.setImage("")
self.image.setImage(self.imagefile)
def __enter__(self):
return self
def __exit__(self,type,value,traceback):
os.remove(self.imagefile)
def main():
for i in range(1,len(sys.argv)):
str,dummy,val = sys.argv[i].partition("=")
if str == "alarm_id": idx = val
if str == "cam_id" : camname = val
if str == "cam_port": camport = val
if str == "username": username = val
if str == "password": password = val
with CamView(camname,camport,idx,username,password) as viewer:
viewer.show()
start_time = time.time()
firstimage = True
while(time.time() - start_time <= 30):
viewer.update_image()
curr_time = round(time.time()-start_time, 0)
if firstimage:
firstimage = False
nowtime = time.strftime("%I:%M %p")
viewer.image.setAnimations([('conditional', 'effect=fade start=0 end=100 time=750 delay=125 condition=true'),
('conditional', 'effect=slide start=400,0 end=0,0 time=750 condition=true')])
xoptions = ("Notification(\"" + viewer.msg + "\", " + nowtime + ", 29500, special://masterprofile/addon_data/" +
xbmcaddon.Addon().getAddonInfo('id') + "/" + camname + ".png)")
xbmc.executebuiltin(xoptions)
elif curr_time == 30:
viewer.image.setAnimations([('conditional', 'effect=fade start=100 end=0 time=750 condition=true'),
('conditional', 'effect=slide start=0,0 end=400,0 time=750 condition=true')])
else:
viewer.image.setAnimations([('conditional', 'effect=fade start=100 end=100 time=0 condition=true')])
xbmc.sleep(500)
if __name__ == "__main__":
if xbmc.getInfoLabel("Window(10000).Property(foscamScriptRunning)") == "True":
xbmc.log('Script already running', level=xbmc.LOGERROR)
else:
xbmc.log('Foscam alarm triggered', level=xbmc.LOGNOTICE)
xbmcgui.Window(10000).setProperty("foscamScriptRunning", "True")
main()
xbmcgui.Window(10000).setProperty("foscamScriptRunning", "False")
原始脚本使用urllib
,我发现它不支持任何方便的digest
身份验证。所以我改为urllib2
。这不起作用,因为我的XBMC弹出窗口中的图像在第一张图像之后没有更新。有时甚至根本没有图像。
所以我做了一些挖掘,我很快发现使用urllib2
Digest
身份验证获取快照的时间超过7秒! (使用旧固件,这需要不到0.1秒)。认为这可能是图像未更新的原因,我将所有内容都更改为requests
模块。分析显示从相机获取单个快照现在大约需要0.25秒;仍然相当慢恕我直言,但也许可以接受。但是,使用此方法,通知图像也不会更新。
我通过远程SSH触发脚本,因此我可以检查XBMC日志等。我还检查了snapshot.jpg
文件创建时的时间戳,他们似乎同意脚本触发时间和requests
的0.25秒延迟。在XBMC脚本中,我更改了清除映像的顺序,并将其设置为新快照,以达到您可以想到的每个可能的顺序,但没有成功。如果我在清除和重新设置图像之间放置一个延迟,我会看到一个闪烁的图像,表明它一切正常。但是,它始终重新设置为完全相同的快照。
所以,我真的很卡住了。我在这里俯瞰什么?
答案 0 :(得分:0)
为了它的价值:
我终于&#34;修复&#34;通过将每个单独的快照保存在唯一名称(基于时间和微秒生成的名称)之后,以及之后删除所有这些单个文件来解决问题。
这暗示了xbmcgui.ControlImage.setImage()
的某些缓存问题的方向,但我一直无法找到任何提及缓存的文档...
我使用此方法遇到的一个问题是,如果您在显示通知时按Esc
(因为在这种情况下所有XBMC控件都丢失了),那么图像并不总是如此清理得当。相对较小的问题,但它清楚地表明这是一个臭的解决方案:)