Jump to content

Recommended Posts

I was thinking to store 2 files for each QA (and scene)

QA_<ID>.lua with the Lua code (maybe annotated with the fibaroapiHC3.lua intro/outro)

QA_<ID>.rsrc being the original json struct (but pretty printed to make it easier to eventually edit - like the layout)

Then a restore command deploy/restore command that combine them to a .fqa and upload them to the HC3.

 

Because we don't have a clean format we need some kind of resource fork. However, it's really nice with a flat file format that is easily edited.

Alternatively, we come up with some format that can be included in a comment in the code that describe the other properties like layout and quickvars and type etc.

Similar to what I attempted with <link>

--[[
%%LibDevice
properties: {
"name": "Test device1",
"type":"com.fibaro.binarySensor",
"variables":{
   "myVar":"This is a test"
   },
"UI":[
  {"button":"button1","text":"B1"},
  [{"button":"button2","text":"B2"},{"button":"button3","text":"B3"}],
  {"slider":"slider1","text":"","min":0,"max":100},
  {"label":"label1","text":"L1"}
  ]
}
--]]

if dofile then
  dofile("fibaroapiHC3.lua")
  local cr = loadfile("credentials.lua"); if cr then cr() end
  QuickApp:setVariable("IP",_HueIP)
  QuickApp:setVariable("User",_HueUserName)
end

function QuickApp:onInit()
   self:debug("Device1")
end
 

 

 

Link to post
Share on other sites
Posted (edited)

That makes three of us working on this ;) I think splitting Lua scenes in "conditions" and "code" like @10der did is the way to go, but the conditions are "json" and not lua (check extension)

Keep in mind though block scenes are JSON only ("actions" is array instead of Lua). Edit: If it's a block scene the conditions part is a json struct. If it's a lua scene it's a Lua table. At the moment I do not split scenes anymore.

 

I name my scenes based on ID and name, eg SC0042_BatteryCheck_v5.json but I've thought about using directories instead, because I think whatever we try to export on HC3 will end up as more than one file, but you might need all of those files to get back the original.

 

FQA's ... I export both the output of the device API and the FQA. There is a lot of overlap...

 

 

Edited by petergebruers
Link to post
Share on other sites

OMG!

 

New notations in ECMAScript 2015

 

 

// Shorthand property names (ES2015)
let a = 'foo', b = 42, c = {};
let o = {a, b, c}

// Shorthand method names (ES2015)
let o = {
  property(parameters) {}
}

// Computed property names (ES2015)
let prop = 'foo'
let o = {
  [prop]: 'hey',
  ['b' + 'ar']: 'there'
}

 

Link to post
Share on other sites
Posted (edited)

Oops! I am talking nonsense I guess ;) Big Oops! Those are Lua tables, aren't they? Edit: If it's a block scene the conditions part is a json struct. If it's a lua scene it's a Lua table.

Edited by petergebruers
  • Thanks 1
Link to post
Share on other sites

but no

 

{
    operator = "all",
    conditions = {
        {
            type = "device",
            id = 25,
            property = "value",
            operator = "==",
            value = true,
            isTrigger = true
        },
        {
            operator = "any",
            conditions = {
                {
                    type = "device",
                    id = 26,
                    property = "value",
                    operator = "==",
                    value = true,
                    isTrigger = true
                },
                {
                    type = "device",
                    id = 27,
                    property = "value",
                    operator = "==",
                    value = true,
                    isTrigger = true
                }
            }
        }
    }
}

it's WRONG JS!!

 

1 minute ago, petergebruers said:

Those are Lua tables, aren't they?

yep Sir!

it''s LUA 😃 

Link to post
Share on other sites
2 minutes ago, 10der said:

yep Sir!

it''s LUA 😃 

Yeah, sorry, my bad. I am programming an ESP8266 to connect a PM2.5 dust sensor and my brain is all messed up with C++ :D

Link to post
Share on other sites
7 minutes ago, petergebruers said:

Yeah, sorry, my bad. I am programming an ESP8266 to connect a PM2.5 dust sensor and my brain is all messed up with C++ :D

O!!!!!!!! please share your code in PM. please.

pm2.5 was delivered from alie yesterday...

Link to post
Share on other sites

Hi,

 

What do you think about this ?

 

 

  • multiplatform
  • can access remote controllers
  • configurable
  • lots of good things to come :)

 

image.png.78059720d43614cd6c1044610d89af22.png

 

image.png.a27cbeddc185f5c0ae9059b54638203c.png

 

image.png.33254bd4c3bcd9b7dbd86c0fdef6e61d.png

 

 

 

image.png.740bf5165f9ffb1a9b47c8442e97890b.png

 

  • Like 2
  • Thanks 1
Link to post
Share on other sites

One thing I worry about (without having a clear answer) is the restrictions of filenames on different platforms. For example, ? (question mark) is valid on Mac but available on windows. And then there is case sensitive, case preserving issue. Maybe "?" is not the best example, it may be more about UTF support. It is a mess ;) - I bet the source code of "Syncthing" can learn us something in that respect. I run Syncthing on linux/max/windows and it is tricky sometimes (it has the potential to delete entire directories because of naming issues)

Link to post
Share on other sites
12 minutes ago, petergebruers said:

One thing I worry about (without having a clear answer) is the restrictions of filenames on different platforms.

 

I will test on different platforms ;)

 

  • Thanks 2
Link to post
Share on other sites

Python (3)

cross platformed

support UTF

no issues on win

 

  • Like 1
Link to post
Share on other sites
1 minute ago, Krikroff said:

I will test on different platforms ;)

Awesome!

 

1 minute ago, 10der said:

no issues on win

Generally speaking "no issues" but that "?" issue is an O/S thing so no language can work around that...

Link to post
Share on other sites
8 minutes ago, 10der said:

Python (3)

cross platformed

support UTF

no issues on win

 

 

The two projects can coexist no worries, on the contrary it's cool :)

 

Link to post
Share on other sites

No your project win ;) 

All ok I just share idea 

Link to post
Share on other sites

So, I'm downloading and uploading QuickApps today. The format is a flat form.

For backup purposes I have settled on the same flat format where I put device struct in a comment at the end of the file.

HC3Format.lua

I have no opinion on what to name the files.

 

Then I have functions that convert between. format - including the "upload" format of QuickApps.

I kind of like the flat format as it's easier to keep in sync and allows for easy edit/debug workflow. Edit and upload (including modifying struct. properties)

Planning the same for scenes.

deviceStruct = HC3Format.downloadQuickApp(122)
fileText = HC3Format.QuickApp2Flat(deviceStruct)
print("---------- First flat ------------------")
print(fileText)
 
uploadStruct = HC3Format.flat2QuickApp(fileText)
print("---------- Upload struct ------------------")
print(json.encode(uploadStruct))

deviceStruct = HC3Format.upload2DownloadStruct(uploadStruct) -- They differ a bit...

fileText = HC3Format.QuickApp2Flat(deviceStruct) -- make sure that we have a "stable" conversion method...
print("---------- Second flat ------------------")
print(fileText)

Running it gives

Debugging session started in '/Users/erajgab/Dropbox/LUA/EventRunner/EventRunner/'.
---------- First flat ------------------
--[[ <<QuickApp>>
  Name:Test
  Id:  122
  Type:com.fibaro.multilevelSensor
--]]

if dofile then
  dofile("fibaroapiHC3.lua")
  hc3_emulator.quickVars["X"]="Hej"
end

function QuickApp:onInit()
  self:debug("onInit",self.id)
  self:debug("HHH:",debug.info)
end

if dofile then
  hc3_emulator.start{
    name = "Test",    -- Name of QA
    poll = 2000,      -- Poll HC3 for triggers every 2000ms
    deploy=true
  }
end

--[[ <<Device struct>>
{
 "id":122, 
 "name":"Test", 
 "roomID":219, 
 "type":"com.fibaro.multilevelSensor", 
 "baseType":"com.fibaro.sensor", 
 "enabled":true, 
 "visible":true, 
 "isPlugin":true, 
 "parentId":0, 
 "viewXml":true, 
 "configXml":false, 
 "interfaces":[
  "quickApp"  
 ], 
 "properties":{
  "emailNotificationID":0,  
  "mainFunction":"",  
  "model":"",  
  "smsNotificationID":0,  
  "smsNotificationType":0,  
  "deadReason":"",  
  "deviceControlType":0,  
  "deviceIcon":47,  
  "saveLogs":true,  
  "emailNotificationType":0,  
  "typeTemplateInitialized":true,  
  "uiCallbacks":[
   {
    "name":"button1",    
    "callback":"test",    
    "eventType":"onReleased"    
   }   
  ],  
  "log":"",  
  "unit":"",  
  "logTemp":"",  
  "quickAppVariables":[
   {
    "name":"FOO",    
    "value":"BAR"    
   },   
   {
    "name":"X",    
    "value":"Hej"    
   }   
  ],  
  "userDescription":"",  
  "value":0.0,  
  "dead":false,  
  "pushNotificationID":0,  
  "viewLayout":{
   "$jason":{
    "head":{
     "title":"quickApp_device_122"     
    },    
    "body":{
     "sections":{
      "items":[
       {
        "type":"vertical",        
        "style":{
         "weight":"1.2"         
        },        
        "components":[
         {
          "type":"space",          
          "style":{
           "weight":"0.5"           
          }          
         },         
         {
          "name":"button1",          
          "type":"button",          
          "style":{
           "weight":"1.2"           
          },          
          "text":"btn"          
         }         
        ]        
       }       
      ]      
     },     
     "header":{
      "style":{
       "height":"50"       
      },      
      "title":"quickApp_device_122"      
     }     
    }    
   }   
  },  
  "apiVersion":"1.1",  
  "useEmbededView":true,  
  "categories":[
   "other"   
  ],  
  "manufacturer":"",  
  "pushNotificationType":0  
 }, 
 "actions":[], 
 "created":1589103129, 
 "modified":1589103129, 
 "sortOrder":14 
}
--]]
---------- Upload struct ------------------
{"baseType":"com.fibaro.sensor","initialProperties":{"value":0,"smsNotificationID":0,"viewLayout":{"$jason":{"body":{"sections":{"items":[{"components":[{"style":{"weight":"0.5"},"type":"space"},{"text":"btn","name":"button1","style":{"weight":"1.2"},"type":"button"}],"style":{"weight":"1.2"},"type":"vertical"}]},"header":{"title":"quickApp_device_122","style":{"height":"50"}}},"head":{"title":"quickApp_device_122"}}},"manufacturer":"","categories":["other"],"useEmbededView":true,"apiVersion":"1.1","pushNotificationID":0,"deviceControlType":0,"model":"","quickAppVariables":[{"value":"BAR","name":"FOO"},{"value":"Hej","name":"X"}],"saveLogs":true,"uiCallbacks":[{"eventType":"onReleased","name":"button1","callback":"test"}],"pushNotificationType":0,"emailNotificationType":0,"deviceIcon":47,"typeTemplateInitialized":true,"mainFunction":"if dofile then\n  dofile(\"fibaroapiHC3.lua\")\n  hc3_emulator.quickVars[\"X\"]=\"Hej\"\nend\n\nfunction QuickApp:onInit()\n  self:debug(\"onInit\",self.id)\n  self:debug(\"HHH:\",debug.info)\nend\n\nif dofile then\n  hc3_emulator.start{\n    name = \"Test\",    -- Name of QA\n    poll = 2000,      -- Poll HC3 for triggers every 2000ms\n    deploy=true\n  }\nend\n\n","unit":"","smsNotificationType":0,"userDescription":"","emailNotificationID":0},"id":122,"sortOrder":14,"actions":[],"interfaces":["quickApp"],"type":"com.fibaro.multilevelSensor","roomID":219,"viewXml":true,"enabled":true,"configXml":false,"apiVersion":"1.1","name":"Test","isPlugin":true,"visible":true}
---------- Second flat ------------------
--[[ <<QuickApp>>
  Name:Test
  Id:  122
  Type:com.fibaro.multilevelSensor
--]]

if dofile then
  dofile("fibaroapiHC3.lua")
  hc3_emulator.quickVars["X"]="Hej"
end

function QuickApp:onInit()
  self:debug("onInit",self.id)
  self:debug("HHH:",debug.info)
end

if dofile then
  hc3_emulator.start{
    name = "Test",    -- Name of QA
    poll = 2000,      -- Poll HC3 for triggers every 2000ms
    deploy=true
  }
end


--[[ <<Device struct>>
{
 "id":122, 
 "name":"Test", 
 "roomID":219, 
 "type":"com.fibaro.multilevelSensor", 
 "baseType":"com.fibaro.sensor", 
 "enabled":true, 
 "visible":true, 
 "isPlugin":true, 
 "viewXml":true, 
 "configXml":false, 
 "interfaces":[
  "quickApp"  
 ], 
 "properties":{
  "emailNotificationID":0,  
  "mainFunction":"",  
  "model":"",  
  "smsNotificationID":0,  
  "smsNotificationType":0,  
  "deviceControlType":0,  
  "deviceIcon":47,  
  "saveLogs":true,  
  "emailNotificationType":0,  
  "typeTemplateInitialized":true,  
  "uiCallbacks":[
   {
    "name":"button1",    
    "callback":"test",    
    "eventType":"onReleased"    
   }   
  ],  
  "unit":"",  
  "quickAppVariables":[
   {
    "name":"X",    
    "value":"Hej"    
   },   
   {
    "name":"FOO",    
    "value":"BAR"    
   }   
  ],  
  "userDescription":"",  
  "value":0.0,  
  "pushNotificationID":0,  
  "viewLayout":{
   "$jason":{
    "head":{
     "title":"quickApp_device_122"     
    },    
    "body":{
     "sections":{
      "items":[
       {
        "type":"vertical",        
        "style":{
         "weight":"1.2"         
        },        
        "components":[
         {
          "name":"button1",          
          "type":"button",          
          "style":{
           "weight":"1.2"           
          },          
          "text":"btn"          
         },         
         {
          "type":"space",          
          "style":{
           "weight":"0.5"           
          }          
         }         
        ]        
       }       
      ]      
     },     
     "header":{
      "style":{
       "height":"50"       
      },      
      "title":"quickApp_device_122"      
     }     
    }    
   }   
  },  
  "apiVersion":"1.1",  
  "useEmbededView":true,  
  "categories":[
   "other"   
  ],  
  "manufacturer":"",  
  "pushNotificationType":0  
 }, 
 "actions":[], 
 "sortOrder":14 
}
--]]

 

  • Like 1
Link to post
Share on other sites

Jan, I hope Fibaro will make a native tools for it ;) 

Link to post
Share on other sites
Posted (edited)
2 hours ago, jgab said:

The format is a flat form.

I like it. The funny thing though is this: the HC2 had "triggers" as comments at the top of the scene code, then HC3 moves away from this and has separate edit windows for condition and action.

The trouble with JSON is ... it needs special diff tool, it does not work well when using classic text diff/merge. Sorting the keys/values might help, I have never tried. Same issue with Lua tables and key/value stores in other languages, they do not define a fixed order (most people assume by that "insertion order" and some "alphabetical order") by design. After all it does not matter if you say "a=1; b=2;" or "b=2; a=1;" when that text represents k/v pairs.

Edited by petergebruers
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...