2014-06-16 36 views
2

我有一個XBMC盒子連接到我的電視。另外,我有2臺Foscam IP攝像機,我用它來監控我的兩個小女孩。XBMC通知圖像(來自IP攝像頭)未更新

回想起來,我認爲編寫幾個腳本會很酷,這樣當Foscam的某個警報觸發時,我會在XBMC上發出通知以及來自相關Foscam相機的實時圖像。有了這個,我可以看電視,同時密切關注這個kiddos。

因此,在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彈出窗口中的圖像沒有在第一張圖像後更新。有時甚至根本沒有圖像。

所以我做了一些挖掘工作,並且很快發現使用urllib2Digest身份驗證獲取快照需要7秒多一點時間! (使用舊的固件,這需要0.1秒以下)。考慮到這可能是未更新圖像的原因,我將所有內容都更改爲requests模塊。分析顯示,從相機獲取單個快照現在需要大約0.25秒的時間;恕我直言,但仍然相當慢,但也許可以接受。但是,對於這種方法,通知圖像也不會更新。

我通過遠程SSH觸發腳本,因此我可以檢查XBMC日誌等。我還檢查了snapshot.jpg文件創建時的時間戳,它們似乎與腳本觸發時間和由requests延遲0.25秒。在XBMC腳本中,我改變了清除圖像的順序,並將其設置爲新的快照,以達到您可以想到的所有可能的順序,但沒有成功。如果我在清除和重新設置圖像之間放置了一段時間,我會看到一張閃爍的圖像,暗示它一切正常。但是,它總是被重新設置爲完全相同的快照。

所以,我真的很卡住。我在這裏忽略了什麼?

+0

有沒有機會回滾到以前的固件?除非我們有相同的硬件,否則任何人都很難幫助.. :(( – mlwn

+0

@mlwn不是真的,相機甚至沒有「保存當前固件」選項.....我希望這是一個與Python代碼問題,或者有人遇到與使用模塊相結合的摘要認證類似的問題... –

+0

我對這個主題感興趣..並希望提供我的幫助,但我從未使用過這種硬件。 ..你認爲可能有一個在線模擬器???我準備以任何方便的方式幫助... – mlwn

回答

0

對於它的價值:

我終於「固定」的下一個唯一的名稱保存每個單獨的快照問題(名產生基於時間與微秒),事後刪除所有這些單獨的文件。

這暗示了一些緩存問題的方向與xbmcgui.ControlImage.setImage(),但我一直無法找到任何文件提及緩存...

我使用這種方法遇到的一個問題是,如果在顯示通知時按下Esc(因爲所有XBMC控件在這種情況下都會丟失),那麼圖像並不總是被正確清理。相對較小的問題,但它清楚地表明這是一個臭解決方案:)

相關問題