Scope to add Description as a variable e.g. gc_NextEventDesc

Hi @stuart

Not sure if this has been requested before, so i might be alone in this :slight_smile:

Would you consider adding the description of an event as another variable within your plugin ?

[quote=ā€œparkerc, post:1, topic:193564ā€]Hi @stuart

Not sure if this has been requested before, so i might be alone in this :slight_smile:

Would you consider adding the description of an event as another variable within your plugin ?[/quote]

I could easily add it to gc_jsonEvents and you can access it from there. How do you want to use it ?

Hi @Stuart

Iā€™ve been working to integrate my Vera with Panicā€™s Status Board app on iOS , and not being a programmer, I recently found a panel that I would like to try and tweak to reference variables held in your GCal app.

So if the description was to be added as its own variable, I would look to include it in a new panel(HTML widget) which I would try to generate and host on Vera.

** if there was scope to search the description for keywords too, that could come in handyā€¦**

Ive attached an example.

I will make a change so that the description information is included in the gc_jasonEvents variable. That way - you can build your own scene and play with Lua code to get it to do whatever you want.

Iā€™ll post an updated file in the next day or two.

Thanks so much @Stuart

One other thing - as Iā€™m not a programmer/developer, would you know how I would remove the ā€˜[{ā€™ characters that will already be in the gc_JsonEvents variable field when you add the Description ?

The [{ is displayed in UI5 is because UI5 is not displaying what it should. The variable is an encoded json string but itā€™s being truncated in the UI. There really is data there !

There is some sample lua code in the instructions for GCal3 that shows how to access the variable and get at the various entries. You will have to learn some Lua - but you likely needs to do so anyway so you can get the data into the application you plan on using to display it all.

I admire your optimism in me :slight_smile:

Ok, I think is have found the code you are referring to.

function testJson() local GCAL_SID = "urn:srs-com:serviceId:GCalIII" local jsonEvents = luup.variable_get(GCAL_SID, "gc_jsonEvents",lul_device) if (jsonEvents == "[]") then -- equivalent of a nul so don't try return end

local json = require(?json?)
local eventList =json.decode(jsonEvents)
package.loaded.json = nil
local numberEvents = #eventList
local startevent, startDate, startTime, endevent, endTime, eventname, event for i = 1,numberEvents do
startevent = eventList[i].eventStart
startDate = os.date(ā€œ%Y-%m-%dā€, startevent)
startTime = os.date(ā€œ%H:%M:%Sā€, startevent)
endevent = eventList[i].eventEnd
endTime = os.date(ā€œ%H:%M:%Sā€, endevent)
eventname = eventList[i].eventName
end
return
end

Hi @stuart

In preparation for the description being added, I thought I would have a go at using your sample code to decode the JSON,

That way I can hopefully try work out what I might need to lookup/learn to do to extract just the descriptionā€™part in the futureā€¦

[code]function testJson()
local GCAL_SID = ā€œurn:srs-com:serviceId:GCalIIIā€
local jsonEvents = luup.variable_get(GCAL_SID, ā€œgc_jsonEventsā€,lul_device)
if (jsonEvents == ā€œ[]ā€) then ā€“ equivalent of a nul so donā€™t try
return
end

local json = require ā€œakb-jsonā€
local eventList =json.decode(jsonEvents)
package.loaded.json = nil
local numberEvents = #eventList
local startevent, startDate, startTime, endevent, endTime, eventname, event for i = 1,numberEvents do
startevent = eventList.eventStart
startDate = os.date(ā€œ%Y-%m-%dā€, startevent)
startTime = os.date(ā€œ%H:%M:%Sā€, startevent)
endevent = eventList.eventEnd
endTime = os.date(ā€œ%H:%M:%Sā€, endevent)
eventname = eventList.eventName
end
return
end

testJson()

[/code]

However, after addressing one error before, I am still getting the following errors in the log ???

01 09/02/16 8:04:39.989 GetLuaInterface can't find device type: 0/0x1b1f1d0 str: (null) <0x310ba680> 01 09/02/16 8:04:39.990 luup_variable_get interface 0x1ab65b8 args 3 <0x310ba680> 01 09/02/16 8:04:39.991 LuaInterface::StartEngine failed run: 0 [string "function testJson() ..."]:11: attempt to get length of local 'eventList' (a nil value) <0x310ba680> 01 09/02/16 8:04:39.991 JobHandler_LuaUPnP::RunLua failed: function testJson()

what version of vera are you using UI5 or UI7 ?

In UI5 it should be

local json = require "json"

and in UI7 it should be

local json = require "dkjson"

This is because vera did not provide a json encode/decode library in UI5 - so GCal downloads one (json) . In UI7 vera provided one (dkjson). Of course this may have been inconsistent on veraā€™s side (across models), so GCal loads json if it cannot find dkjson.

Not sure where you got the idea to use akb-json. Perhaps from someone elseā€™s example where they had loaded that version onto their machine.

Thanks @stuart

Replacing lul_device reference with the actual device ID allows the code to work without any errors. But now Iā€™m stuck :slight_smile:

Can you help me with what to do next just to see the contents of gc_JasonEvents variable e.g in the log?

What do I need to add at the end ?

What do you want to do with the variables once you have them ? Are you interested in all the events in gc_jasonEvents or just the currently triggered event ? Some other event ? How are you planning on executing your code ā€“ as part of a scene ? If so what would be the scene trigger ?

Writing them to the log file will only tell you that you have them (which is not that interesting). Painting a scenario of what you want to do will let others have a better idea and offer advice.

Hi Stuart

My current goal is to create a (web) widget (using the same design I posted earlier/above) to work with the Status Board app to show what the next trigger event is.

To do that I was just going to try and work out some code that will capture the required information / variables and then generate the webpage which would be hosted on Vera in /www/

Using your code above, my question was because I was not sure how I could run the code and see the decoded results - just to see if it worked (or not).

Iā€™m mocking it up at the moment and im thinking I can replace bits of the template each time using (is it called concatenation? ) " ā€¦ gc_variable ā€¦ " with the information I could get from your plugin.

All with no formal programming understanding/ experience :slight_smile:

Hi Stuart

Here is my working current code, not the pretty version just yet.

What I canā€™t work out/need is how to create (extract) the other bits of event information I need such as the start time, the month, day and the description.

[code]local GCAL_SID = ā€œurn:srs-com:serviceId:GCalIIIā€
local gcNext = luup.variable_get(GCAL_SID, ā€œgc_NextEventā€, 330)
local gcNextTime = luup.variable_get(GCAL_SID, ā€œgc_NextEventTimeā€, 330)

local text = [[

		<div id="GCal3 Container">

			<h2>Next GCal Event</h2>
			<ul class="custom-listing">
  • ]] .. gcNext ..[[

    	 <div class="small_cal_month_dash">.. Three letter month to go here ..</div>
    	 <div class="small_cal_day_dash">.. Two digit date to go here .. </div>  
    	 <div class="dash_time">.. Day .. " - " ..start time .. </div>  
    
    <p>
    <p><strong><span class="caps">Vera Home Control</span></p>
    


    .. Event description ..

    </p>
    
  • 		</div><!-- GCal3 Container -->
    	
    </body>]]
    

    local file = io.open(ā€œ/www/gcalnext.htmlā€, ā€œwā€)
    file:write(text)
    file:close()[/code]

    @ parkerc

    Update your V2.3 with the two files located here. This version includes the description in gc_jsonEvents

    http://forum.micasaverde.com/index.php/topic,26692.msg292407.html#msg292407

    The code below should get you going. Paste it into a scene and test it out.

    luup.log("***********************     VERA EVENT  EXECUTED          ****************************")
    
    local GCAL_SID = "urn:srs-com:serviceId:GCalIII"
    local lul_device = 50 -- change this to be the Gcal plugin number
    
    function getEventDescription(device, event, eventtime )
    -- returns the description of the matching event, or
    -- "No Events" if there are no matching events
    -- "No Description" if there is no description
    
      local GCAL_SID = "urn:srs-com:serviceId:GCalIII"
      
      -- get the contents of gc_jsonEvents
      local jsonEvents = luup.variable_get(GCAL_SID, "gc_jsonEvents",device)
      if (jsonEvents == "[]") then -- equivalent of a nul
        return "No Events"
      end
    
      -- read the events in gc_jsonEvents into an array 
      local json = require("json") -- depending on your vera version you may need to use require("dkjson")
      local eventList =json.decode(jsonEvents) 
      package.loaded.json = nil
    
      local eventstart, starttime, eventname, eventdescription
      
      -- now process the array one entry at a time
      for i = 1,#eventList do
        -- get the start time for this event
        eventstart = eventList[i].eventStart
        -- create a string with the same start format as gc_nextEventTime
        starttime = os.date("%H:%M %b %d", eventstart) .. " to " -- will be shorter then eventtime parameter
    	-- get the event name
    	eventname = eventList[i].eventName
    	 -- truncate it because the variable gc_NextEvent is truncated for display reasons
    	eventname = string.sub(eventname,1,40) -- will be same size or shorter then event parameter
    	-- get the description if it has one otherwise use a default
    	eventdescription = eventList[i].eventDescription or "No Description"
        
    	-- test to see if the name and start time match
    	-- need to do a partial string match
    	
       if (string.find(event, eventname) and string.find(eventtime, starttime)) then
       -- this event matches the input parameters so we return the description
    	return eventdescription
        end
      end
      return "No Events"
    end
    
    --  Main Program
    
    -- get the information on the next event
    local gcNext = luup.variable_get(GCAL_SID, "gc_NextEvent", lul_device) or "No Event"
    local gcNextTime = luup.variable_get(GCAL_SID, "gc_NextEventTime", lul_device) or "No EventTime"
    
    --get the description for this event
    local gcNextDescription = getEventDescription(lul_device, gcNext, gcNextTime)
    
    local Msg = "Event "  .. gcNext .. " at " .. gcNextTime .. " has description " .. gcNextDescription
    luup.log(Msg)
    
    

    Thanks so much @Stuart this is a great help.

    If I could ask one more thing, as I canā€™t seem to work out how to do it myself ā€¦ ???

    Calling - ā€¦ gcNextTime ā€¦
    Returns - 23:00 Sep 07 to 00:01 Sep 08

    How can i separate that gcNextTime variable so i can use/call ā€œ23:00ā€ and ā€œSeptā€ and ā€œ07ā€ separately ?

    Take a look at the line

    starttime = os.date("%H:%M %b %d", eventstart)

    you could create separate variables to capture the various bits and pass them back in the function call. Google ā€˜luup os.dateā€™ and you will find details of the formatting.

    or you could use something like string.find using the gcNextTime value

    local _,_,time,month,day = string.find(gcNextTime, pattern)

    you will need to figure out the pattern. Google ā€˜Luup string.findā€™ and you will get plenty of examples.

    Another comment: I HIGHLY recommend you get a copy of ZeroBrane as you can easily execute and debug elements of your Lua code without needing to have it execute on the vera. A slightly more advanced usage also allows you to run your code on the vera. Personally - I mostly use it to syntax check and to try out things (like getting the patter on string.find correct).