128 comments on “Doorbell + IPcam + XBMC

  1. This is awesome but I’ve been trying for hours without success, I cant get this to work. Im running this on xbmc 12 on a mac and i get the message that say’s “doorbell TIME” but no image this is what my log file says, i hope you can help me.

    16:07:00 T:4678410240 NOTICE: 13.0
    16:07:00 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:00 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg
    16:07:00 T:4678410240 NOTICE: catch
    16:07:00 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:00 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg
    16:07:12 T:4678410240 NOTICE: Thread XBPyThread start, auto delete: false
    16:07:12 T:4678410240 NOTICE: –>Python Interpreter Initialized<–
    16:07:12 T:140735084313792 ERROR: Texture manager unable to load file: special://masterprofile/media/bell1.png
    16:07:12 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:12 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg
    16:07:13 T:4678410240 NOTICE: 1.0
    16:07:13 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:13 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg
    16:07:13 T:4678410240 NOTICE: 1.0
    16:07:13 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:13 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg
    16:07:14 T:4678410240 NOTICE: 2.0
    16:07:14 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:14 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg
    16:07:14 T:4678410240 NOTICE: 2.0
    16:07:14 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:14 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg
    16:07:15 T:4678410240 NOTICE: 3.0
    16:07:15 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:15 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg
    16:07:15 T:4678410240 NOTICE: 3.0
    16:07:15 T:140735084313792 WARNING: JpegIO: Error 55: Not a JPEG file: starts with 0x%02x 0x%02x
    16:07:15 T:140735084313792 ERROR: Texture manager unable to load file: /Users/armando/Library/Application Support/XBMC/userdata/addon_data/script.doorbell/cam_2.jpg

    • I’m going to trust the logs and suggest whatever you’re getting is not a JPEG file. Have you tried hitting the URL manually, what does it present you with? I can help you test this if you want to open up your firewall to that cam temporarily.

  2. @a1a2a – Were you able to get this working? I have RaspXBMC running throughout our house and would love to have a live image display on screen when motion is detected. Blue iris can serve the stream and can run a script or batch file if needed. Anyone else know how to accomplish this?
    Awesome job on all this! I have been hoping for someone to figure out this type of integration.
    Any help would be greatly appreciated! RaspXBMC runs XBMC version 12.

  3. Hello, does it possible to use and modify your code to add it in my script for fibaro’s box??
    I only add the possibility to have more than one camera.
    Thanks

  4. Yes, you can, you can dupicate the code
    # Import the XBMC/XBMCGUI modules.
    import xbmc, xbmcgui, time, urllib, xbmcvfs, xbmcaddon, os
    __addon__ = xbmcaddon.Addon()
    __addonid__ = __addon__.getAddonInfo(‘id’)

    url=’http://canino2.dyndns-server.com:8081/snapshot.cgi’
    url1=’http://canino2.dyndns-server.comYCX:8082/snapshot.cgi’
    url2=’http://canino2.dyndns-server.com:8083/snapshot.cgi’
    url3=’http://canino2.dyndns-server.com:8080/snapshot.cgi’

    #path = xbmc.translatePath(‘/media/usb0/’)
    path = xbmc.translatePath(‘special://profile/addon_data/%s’ % __addonid__)

    if not xbmcvfs.exists(path):
    xbmcvfs.mkdir(path)

    imagefile = os.path.join(path, ‘cam1.png’)
    imagefile1 = os.path.join(path, ‘cam2.png’)
    imagefile2 = os.path.join(path, ‘cam3.png’)
    imagefile3 = os.path.join(path, ‘cam4.png’)

    #xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER).play(url+path)
    #xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER).play(‘/media/usb0/videos/Nissan/0_Nissan Mexico_0.flv’)
    # /media/usb0/videos/Nissan/0_Nissan Mexico_0.flv

    #========================================================================
    # Class – Set the initial image
    #========================================================================

    class CamView(xbmcgui.WindowDialog):
    #class CamView(xbmcgui.Window):

    def __init__(self):
    #
    #set the initial image before the window is shown
    #aspectRatio : [opt] integer – (values
    # 0 = stretch (default),
    # 1 = scale up (crops),
    # 2 = scale down (black bars)
    # colorDiffuse : hexString – (example, ’0xC0FF0000′ (red tint))

    urllib.urlretrieve(url, imagefile)
    self.image = xbmcgui.ControlImage(0, 0, 640, 360, imagefile, aspectRatio=2) # Arriba-Izquierda
    self.addControl(self.image)

    urllib.urlretrieve(url1, imagefile1)
    self.image1 = xbmcgui.ControlImage(640, 0, 640, 360, imagefile1, aspectRatio=2) # Arriba-Derecha
    self.addControl(self.image1)

    urllib.urlretrieve(url2, imagefile2)
    self.image2 = xbmcgui.ControlImage(0, 360, 640, 360, imagefile2, aspectRatio=2) # Abajo-Izquierda
    self.addControl(self.image2)

    urllib.urlretrieve(url3, imagefile3)
    self.image3 = xbmcgui.ControlImage(640, 360, 640, 360, imagefile3, aspectRatio=2) # Abajo-Derecha
    self.addControl(self.image3)
    #========================================================================
    # Programa
    #========================================================================
    viewer = CamView()
    viewer.show()

    start_time = time.time()
    firstimage = True

    while(time.time() – start_time <= 59): # Durante 1 minuto

    urllib.urlretrieve(url, imagefile)
    viewer.image.setImage("")
    viewer.image.setImage(imagefile)

    urllib.urlretrieve(url1, imagefile1)
    viewer.image1.setImage("")
    viewer.image1.setImage(imagefile1)

    urllib.urlretrieve(url2, imagefile2)
    viewer.image2.setImage("")
    viewer.image2.setImage(imagefile2)

    urllib.urlretrieve(url3, imagefile3)
    viewer.image3.setImage("")
    viewer.image3.setImage(imagefile3)

    # curr_time = round(time.time() – start_time, 0)
    # if firstimage:
    # nowtime=time.strftime("%I:%M %p")
    # xoptions="Notification(\"Doorbell\",%s, 13800, special://masterprofile/media/bell1.png)" % (nowtime)
    # xbmc.executebuiltin(xoptions)
    # viewer.image.setAnimations([('conditional', 'effect=fade start=0 end=90 time=250 delay=125 condition=true',), ('conditional', 'effect=slide start=0,400 end=0,0 time=250 condition=true',)])
    # viewer.image1.setAnimations([('conditional', 'effect=fade start=0 end=90 time=250 delay=125 condition=true',), ('conditional', 'effect=slide start=0,400 end=0,0 time=250 condition=true',)])
    # viewer.image2.setAnimations([('conditional', 'effect=fade start=0 end=90 time=250 delay=125 condition=true',), ('conditional', 'effect=slide start=0,400 end=0,0 time=250 condition=true',)])
    # viewer.image3.setAnimations([('conditional', 'effect=fade start=0 end=90 time=250 delay=125 condition=true',), ('conditional', 'effect=slide start=0,400 end=0,0 time=250 condition=true',)])
    # firstimage = False
    # elif curr_time == 59:
    # viewer.image.setAnimations([('conditional', 'effect=fade start=90 end=90 time=0 condition=true',), ('conditional', 'effect=slide start=0,0 end=0,400 time=250 condition=true',)])
    # viewer.image1.setAnimations([('conditional', 'effect=fade start=90 end=90 time=0 condition=true',), ('conditional', 'effect=slide start=0,0 end=0,400 time=250 condition=true',)])
    # viewer.image2.setAnimations([('conditional', 'effect=fade start=90 end=90 time=0 condition=true',), ('conditional', 'effect=slide start=0,0 end=0,400 time=250 condition=true',)])
    # viewer.image3.setAnimations([('conditional', 'effect=fade start=90 end=90 time=0 condition=true',), ('conditional', 'effect=slide start=0,0 end=0,400 time=250 condition=true',)])
    # print "catch"
    # else:
    # viewer.image.setAnimations([('conditional', 'effect=fade start=90 end=90 time=0 condition=true',)])
    # viewer.image1.setAnimations([('conditional', 'effect=fade start=90 end=90 time=0 condition=true',)])
    # viewer.image2.setAnimations([('conditional', 'effect=fade start=90 end=90 time=0 condition=true',)])
    # viewer.image3.setAnimations([('conditional', 'effect=fade start=90 end=90 time=0 condition=true',)])
    # print curr_time
    xbmc.sleep(500)

    #xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER).play('/media/usb0/videos/Nissan/0_Nissan Mexico_0.flv')
    #the_player = xbmc.Player(xbmc.PLAYER_CORE_AUTO)
    #the_player.play(url)
    #while the_player.isplaying():
    # xbmc.sleep(250)
    #the_player.stop()

    viewer.close()
    del viewer

    • Thanks, have you tested this? Can you check it into my repo if you would like access. Or arrange to email me the file so that any character encoding issues in the browser doesn’t screw it up.

  5. Great script, thanks for sharing. I thought I would give back by adding some comments.

    For those of you who are looking for the json call:

    From a browser:

    http://ip:port/jsonrpc?request={“jsonrpc”:”2.0″,”id”:1,”method”:”Addons.ExecuteAddon”,”params”:{“addonid”:”script.doorbell”}}

    where:
    ip = ip address or name of xbmc pc
    port: xbmc port number

    From a linux shell:

    wget –user=xbmc –password=’xbmc’ ‘http://ip:port/jsonrpc?request={“jsonrpc”:”2.0″,”id”:1,”method”:”Addons.ExecuteAddon”,”params”:{“addonid”:”script.doorbell”}}’

    where:
    xbmc = username
    xbmc = password
    ip = ip address or name of xbmc pc
    port: xbmc port number

    Also you must make sure that the url used in this script pulls and image from your camera.

    For Foscam IP camera owners you can utilize the following url in this script:

    http://ip:port/snapshot.cgi?user=cam&pwd=pass

    where:
    ip = ip address of camera
    port: camera port number
    cam = username
    pass = password

    If you would like to increase the frames per second (makes it look more like a video) then decrease the amount of time the while loop sleeps by decreasing the value in the ‘xbmc.sleep(500)’ line. I decreased to 10, which leads to the popup box actually looking like a streaming video.

    Hope this helps someone.

  6. Is it possible to open a .strm file instead of a static image? I would love to be able to stream 10 seconds of video instead of just a static image. Would make a great security monitor/screen saver too.

    • It’s actually not a static image, it’s a stream of images. One frame per second, configurable. XBMC supports strm files but based on other forum posts i’ve read it will interrupt whatever is currently playing.

  7. Excellent script! I interfaced it with ZoneMinder and decided to add a way to see motion from multiple cameras, as well as display them on all XBMC installations simultaneously. Here are my changes:

    doorbell.py_________________________________________
    import sys
    args = ['CamID','CamName']
    dbvar = {‘CamID’: 1,
    ‘CamName’: ‘Default Camera’}

    for item in sys.argv:
    arg = item.split(‘=’)
    i = arg[0]
    if arg[0] in args:
    j = arg[1]
    dbvar.update({arg[0]:arg[1]})

    url=’http://zoneminderserver/cgi-bin/nph-zms?mode=single&monitor=’+str(dbvar['CamID'])+’&scale=100&user=myuname&pass=mypass’

    xoptions=”Notification(\”Motion on “+str(dbvar['CamName'])+” camera detected\”,%s, 13800, special://masterprofile/media/bell1.png)” % (nowtime)
    _________________________________________

    For anyone else attempting to do this, I used the trigger script found in the ZM wiki:
    http://www.zoneminder.com/wiki/index.php/FAQ#How_can_I_use_ZoneMinder_to_trigger_something_else_when_there_is_an_alarm.3F

    I have this as an upstart job on my Ubuntu server named ZoneMinderAlarm. In the “Do Your Stuff Here” section, I had it call a python script with the specific camera ID and Name, then pause for a bit instead of continually retriggering during the event:

    system(“/sbin/ZoneMinderTrigger CamID=”.$monitor->{Id}.” CamName=”.$monitor->{Name});
    sleep(12)

    I’m more familiar with Python, so that’s why it’s not all confined in the ZM perl script
    ZoneMinderTrigger_________________________________________
    #!/usr/bin/python

    # This script is called by the ZoneMinderAlarm daemon/script and notifies
    # all XBMC installations to overlay pictures on the screen
    # It requires the doorbell xbmc plugin
    # http://homeawesomation.wordpress.com/2013/02/18/doorbell-ipcam-xbmc-update/
    # Credit for send_json_command to u/sffjunkie
    # http://forum.xbmc.org/showthread.php?tid=92196

    import json, httplib, base64, sys

    xbmc_host=['myHTPC','192.168.1.102'] #List of XBMC HTPCs to send notification to
    xbmc_port=’8080′
    username=’uname’
    password=’pword’

    args = ['CamID','CamName']
    dbvar = {‘CamID’: 1,
    ‘CamName’: ‘Default’}
    for item in sys.argv:
    arg = item.split(‘=’)
    i = arg[0]
    if arg[0] in args:
    j = arg[1]
    dbvar.update({arg[0]:arg[1]})

    def send_json_command(xbmc_host, xbmc_port, method, params=None, id=1, username=username, password=password):
    command = {‘jsonrpc’: ’2.0′, ‘id’: id, ‘method’: method}
    if params is not None: command['params'] = params
    payload = json.dumps(command, ensure_ascii=False, sort_keys=True)
    payload.encode(‘utf-8′)
    headers = {‘Content-Type’: ‘application/json’}
    if password != ”:
    userpass = base64.encodestring(‘%s:%s’ % (username, password))[:-1]
    headers['Authorization'] = ‘Basic %s’ % userpass
    conn = httplib.HTTPConnection(xbmc_host, xbmc_port)
    data = None
    try:
    conn.request(‘POST’, ‘/jsonrpc’, payload, headers)
    response = conn.getresponse()
    if response.status == 200: data = json.loads(response.read())['result']
    else: data = ‘Response Error’
    except:
    data = ‘Connection Error’
    conn.close()
    return data

    def xbmc_doorbell(xbmc_host, xbmc_port=xbmc_port):
    for x in range(0, len(xbmc_host)):
    result = send_json_command(xbmc_host[x], xbmc_port, ‘Addons.ExecuteAddon’,{‘addonid’:’script.doorbell’,’params’:{‘CamID’:str(dbvar['CamID']),’CamName’:str(dbvar['CamName'])}})
    print xbmc_host[x]+”: “+result

    xbmc_doorbell(xbmc_host)
    _________________________________________

    There’s probably better ways to do this (I’m a shadetree programmer), but it seems to work well for me.

  8. I get a parse error on the Json call are you sure you code is correct I can get the picture to show from running the addon in xbmc but cant make it pop up by the trigger. XBMC gotham alpha 7

    • I’ve never tried it with that version. It’s not an issue with the script since you can run it. It’s an issue with the json call. You’ll probably have to look at XBMC’s wiki for that version.

    • I had some issues with the json call as well. I think there was a typo or a formatting issue using the command from above. It has smart quotes instead of plain quotes. I’m not sure if there was anything else.

      I was able to use the following command (all on one line) from a shell prompt:
      wget –user=xbmc –password=’xbmc’ ‘http://zbox-xbmc:8080/jsonrpc?request={“jsonrpc”: “2.0″, “method”:”Addons.ExecuteAddon”,”params”:{“addonid”:”script.doorbell”}}’

      I am successfully using my Elk M1 security system to trigger my ISY/Insteon controller to make a http call to all of my XBMC boxes. It is using the following (same) parameters, minus the URL & credentials:
      /jsonrpc?request={“jsonrpc”: “2.0″, “method”:”Addons.ExecuteAddon”,”params”:{“addonid”:”script.doorbell”}}

      I have my camera mounted upside down so I had to modify the script using image.rotate, but it works very well. Next step will be multiple cameras at once using Manuel’s code from above.

  9. to jrock,

    when I put the Jsonrpc request on chrome browser as follow

    http://ip:port/jsonrpc?request={“jsonrpc”:”2.0″,”id”:1,”method”:”Addons.ExecuteAddon”,”params”:{“addonid”:”script.doorbell”}}

    it showed this error
    {“error”:{“code”:-32700,”message”:”Parse error.”},”id”:null,”jsonrpc”:”2.0″}

    and the xmbc log showed the following
    22:50:03 T:2795217984 ERROR: JSONRPC: Failed to parse ‘{? sonrpc? id?

    Thanks

    • Thanks for posting the logs instead of just begging for help like most people do :)

      “Parse error” most certainly means that it’s an issue with quoting. Which is the issue with copying and pasting stuff like this from a browser. Go through you command and replace all “, ‘ and `’s manually. I can tell just by looking at your pasted line that it’s using the wrong characters for the quotes so xbmc doesn’t know how to parse that line properly.

  10. Great script! The path to the icon of the bell is not correct in the version i got to download. Only as info for you. Good job

  11. Pingback: An Intelligent Doorbell with IP Camera | Vitt Nexia Home Automation Installer

      • Thanks for the reply, I have looked at a lot of tutorials and have modified some code as per below but I get no response.
        I am testing by sending a popup message. This works from a browser;

        http://10.0.0.24:8082/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22GUI.ShowNotification%22,%22params%22:{%22title%22:%22Motion%20Detected%22,%22message%22:%22Front%20Door%22},%22id%22:1}

        Im sure its connecting to xbmc as when I change the port it wont connect.
        Im thinking its a syntax problem.

        #include
        #include

        /////////////////
        // MODIFY HERE //
        /////////////////
        byte mac[] = { 0×00, 0xAA, 0xBB, 0xCC, 0xDE, 0×19 }; // Be sure this address is unique in your network

        //Numeric Pin where you connect your switch
        #define pinDevid1 3 // Example : the mailbox switch is connect to the Pin 3

        // Debug mode
        #define DEBUG true
        ///////
        //End//
        ///////

        char serverName[] = “10.0.0.24″;
        boolean pinDevid1State = false;

        char buffer [256];
        int offtime = 100;
        int ontime = 10;

        // Initialize the Ethernet client library
        // with the IP address and port of the server
        // that you want to connect to (port 80 is default for HTTP):
        EthernetClient client;

        void setup() {
        Serial.begin(9600);
        pinMode(pinDevid1, INPUT);

        // start the Ethernet connection:
        if (Ethernet.begin(mac) == 0) {
        Serial.println(“Failed to configure Ethernet using DHCP”);
        // no point in carrying on, so do nothing forevermore:
        while(true);
        }
        else{
        Serial.println(“Ethernet ready”);
        }
        // give the Ethernet shield time to initialize:
        delay(500);
        }

        void loop()
        {
        ////
        // Listening for the pinDevid1 state
        ////
        if (digitalRead(pinDevid1) == HIGH && pinDevid1State == false) // switch on pinDevid1 is ON
        {
        if(DEBUG){Serial.println(“pinDevid1 is HIGH”);}
        pinDevid1State = true;
        //Sending message to xbmc when the pin is HIGHT
        sendToXBMC();
        }
        if (digitalRead(pinDevid1) == LOW && pinDevid1State == true) // switch on pinDevid1 is OFF
        {
        if(DEBUG){Serial.println(“pinDevid1 is LOW”);}
        pinDevid1State = false;
        //Sending message to xbmc when the pin is LOW
        //sendToXBMC(DEVID1);
        }
        }

        //Function for sending the message to xbmc
        void sendToXBMC()
        {
        if(DEBUG){Serial.println(“connecting…”);}

        if (client.connect(serverName, 8082)) {
        if(DEBUG){Serial.println(“connected”);}

        if(DEBUG){Serial.print(“sendind request”);}
        //NONE OF THESE WORK
        client.println(“/jsonrpc?request={ jsonrpc : 2.0 , method : GUI.ShowNotification , params :{ title : Motion Detected , message : Front%20Door }, id :1}”);
        client.println(“GET /jsonrpc?request={ jsonrpc : 2.0 , method : GUI.ShowNotification , params :{ title : Motion Detected , message : Front%20Door }, id :1}”);
        client.println(“/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22GUI.ShowNotification%22,%22params%22:{%22title%22:%22Motion%20Detected%22,%22message%22:%22Front%20Door%22},%22id%22:1}”);
        client.println(“GET /jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22GUI.ShowNotification%22,%22params%22:{%22title%22:%22Motion%20Detected%22,%22message%22:%22Front%20Door%22},%22id%22:1}”);
        }
        else {
        if(DEBUG){Serial.println(“connection failed”);}
        }

        // if there are incoming bytes available
        // from the server, read them and print them:
        if(DEBUG){
        if (client.available()) {
        char c = client.read();
        Serial.print(c);
        }
        }

        if(DEBUG){Serial.println();}
        if(DEBUG){Serial.println(“disconnecting.”);}
        client.stop();
        }

  12. In simple terms could you tell me how to set this up? I have a doorbell, would like to buy a Pi as the “doorbell server” and an ip camera to hook it up.

    No idea what I’d need to put on the Pi or how to set it up to trigger the call to the XBMC machines around the house?

    • You’ll have to write a script to handle this. My script won’t work as it was designed with X10. But you could simply hook your doorbell wires up to the pin, have a script monitor it. And then fire off requests when the button is pushed.

      For email notifications, you’ll have to rip images off the camera, and then fire off an email about it. I will put my web/email code up sometime but I don’t have the time right now. There’s a lot of work involved like configuring postfix email from the command line, so if you aren’t familiar with linux you have to learn about that stuff first.

      The XBMC trigger is simple, it’s been described in the comments on the post. And in the post itself.

    • could you please give me more information on the error? You’ll probably have to check your xbmc.log file. Does the script run manually or are you having issues with the pop-up notification?

      • Hey
        I have attempted to fix it for you and was hoping to post the results here.. anyway..
        heres what happens:

        Fresh install of XBMC Gotham or Openelec Gotham (Any nightly)

        Go the install from a zip and get this on screen:
        http://s27.postimg.org/aa2jxxrlf/screenshot004.png

        LOG:
        11:01:40 T:15476 NOTICE: Thread JobWorker start, auto delete: true
        11:02:42 T:10408 NOTICE: Previous line repeats 1 times.
        11:02:42 T:10408 NOTICE: Thread BackgroundLoader start, auto delete: false

        ============================
        So this is what I did following this: –
        http://xbmc.org/xbmc-13-gotham-note-to-add-on-developers/

        I edited the addon.xml to include this line

        but got the not correct structure.

        ==============================

        Anyway, after more digging, the issue is caused by editing the file in the zip instead of creating a NEW zip of the plugin..

      • What did you change in the code? Anything worth contributing back? I’m still on xbmc 11, I’m slow to adopt. So maybe other people could benefit from your changes.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s