Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


SDK for remote and offline HC3 development


jgab

Recommended Posts

 

Please login or register to see this link.

 

Note, I currently only support my new emulator,

Please login or register to see this link.

It's a rewrite with the learnings I have made coding fibaroapiHC3.lua...

 

(Note: The new version of the emulator has gone through extensive rewrite and is stabilising (0.300). The old version of the emulator is here 

Please login or register to see this link.

.)

 

 

This is a thread for the fibaroapiHC3.lua sdk that is under development (keeping it separate from the 

Please login or register to see this link.

thread)

I've started to run and test HC3 QuickApps offline and have made a fibaroapi.lua file that can be included to emulate the fibaro calls and call out to the HC3.

This means that a whole QA can be developed offline, debugged and verified before deploying to the HC3. Something that significantly reduces the development process.

It's an emulation so it's not 100% but it will cater for 99.99% of the needs to catch bugs, get decent error messages when things doesn't work (like timers). Be able to set breakpoints and inspect states etc. It's complete enough to run the most demanding QuickApps that I have found on the forum so far... If it runs in the emulator and it doesn't run on the HC3 or vice versa I will prioritise to fix it.

 

Latest version here 

Please login or register to see this link.

 (v0.311) 

The code is updated weekly so please make sure you have the latest...

It was inspired by the old

Please login or register to see this link.

in a thread started by @riemers but has evolved with more extensive support to create a better debugging and "offline experience"... in fact, it's really an HC3 emulator now.

 

The video is an earlier version of the emulator but the principles are more or less the same. Note the nice tooltip and autocompletion of fibaro commands we get with the

Please login or register to see this link.

for ZBS. Enable English subtitles to see instructions...

 

Some benefits:

  • Use a modern development environment such as

    Please login or register to see this link.

    Please login or register to see this image.

    /monthly_2020_03/zerobrane-logo.png.6e96ab226afa8e1a54036c331e5169ad.png" />  (free for Mac/PC/Linux,

    Please login or register to see this link.

    ) on your laptop/PC to develop and debug QuickApps and Scenes.

    Please login or register to see this link.

  • Step through code, inspect Lua variables, set break-points etc - all that is possible in a good IDE.
  • Faster to pin-point errors as the error messages are better than on the HC3 - stack-traces etc.
  • Advanced timer info (setTimeout) warning of late timers and from where the offending function was called if a timer function crashes.
  • Info from where an eronous json.encode was called from in your code so you can easily find the error (instead of seeing a line from deep inside the json encoder)
  • Use the whole Fibaro API fibaro.call etc and net.HTTPClient(), setTimeout(), json.ecode/decode, QuickApp self:functions like self:getVariable, self:updateView
  • Support for MQTT client and QuickApp child devices
  • Both QuickApps and Scenes are supported. Scenes support most conditions and are triggered by real triggers from the HC3 or simulated triggers.
  • Speed up clock to run faster than real time, to watch a Scene or QuickApp over days/weeks/months in seconds.
  • Start at any given time and date - test if your scene behaves on week-ends ? 
  • Automatically create a proxy QuickApp on the HC3 that sends UI clicks back to the code your are running and displays self:updateView updates. This way you can test the QuickApp UI (buttons etc) and still debug the main code on your PC.
  • Develop and run multi-file QuickApps, allowing you to build up a library of common code to share between your QAs.
  • Run completely disconnected from the HC3 simulating devices and other resources (now you can take your coding with you on your vacation :-) )
    • There is a possibility to download resource definitions from the HC3 and use them (devices, globals etc) while running disconnected.
  • Load multiple QAs/Scenes into the emulator at the same time to debug interaction patterns between QAs (or just run all your QAs offline and use the HC3 as a wave GW :-) )
  • Telnet into the running emulator to capture logs or issue Lua commands like turning on/off devices at runtime to test you QA/Scene.
  • Move the code as-is over to the HC3 when it runs in the emulator - and it will most likely run on the HC3. Scenes needs to be moved to conditions/actions part on the HC3 - may automat that in the future.
  • Oh, and

    Please login or register to see this link.

    so you can try out button/slider clicks without connecting to the HC3.
  • And lastly, it makes it fun to develop code for the HC3 :-)

 

 

To get going download the  

Please login or register to see this link.

 and put in in the working directory where you code your QA(s)

If you run ZerobraneStudio (recommended) paste this and run

Please login or register to see this code.

Please note the 'end--hc3' that ends the 'if dofile and not hc3_emulator then' statement. It requires the '--end' comment so I can recognise it.

 

Also, you need to set the Lua interpreter to version 5.3 (In ZBS, Menu ; Project -> Lua Interpreter -> Lua 5.3)

 

It will install the. ZBS plugin in ~/.zbstudio/packages and some code templates in ~/.zbstudio/hc3emu/

(Restart ZBS for the plugin to. be installed)

 

Create a Lua file and create a header + QA/scene code.

An example of a minimal QA can look like

Please login or register to see this code.

We wrap the emulator specific stuff inside "if dofile and not hc3_emulator then .... end" as the symbol 'dofile' is not defined on the HC3 and will thus be false and not include the code - This means that we can take the code as-is and paste it into the HC3 and it works. Note the credentials that contains the IP, username and password so that the emulator can access the HC3 box.

 

If you use ZBS and the plugin there is an Edit-HC3 SDK templates-> menu that will insert a standard QA and Scene header + code in the current buffer.

 

Most of the functions are there and will be improved over time.

  • There are support for net.HTTPClient() and setTimeout/clearTimeout and api.*
  • There are support for getting triggers and events from the HC3
    • Support for auto-creating a QuickApp proxy with UI elements that sends events back to the code being debugged.
  • There are support for both QuickApps and Scenes (with conditions)

 

Currently supported (v 0.300)

Please login or register to see this code.

 

Some of the parameters that affect the behaviour of the emulator and can be set in the header are:

Please login or register to see this code.

 

Some useful emulator functions:

Please login or register to see this code.

 

Some debug flags that can be set with hc3_emulator.debug.<flag>=<value>

Please login or register to see this code.


In the example in the beginning, the HC3 credentials are listed in the header. If you don't want that (it's easy to forget it and share the code with your passwords in plain sights<9 you can create a credentials.lua file with your secret stuff and it will be automatically included by the SDK.

The format should be

Please login or register to see this code.

It returns a Lua table with the relevant keys. ip, user,and pwd is used to log into the HC3.

We have added another key here to 'mySecret'. Assume that you want you QA to have a defined quickAppVariable with the value of mySecret. It could be the password to log into an external services. Then you can do like this

Please login or register to see this code.

This define a quickAppVariable with the name 'password' and it fetches the key 'mySecret' from the credentials table and uses that as the value.

When you QA starts up you can do self:getVarible('password') and it will return the credential. This is useful as not to litter your code with visible credentials.

NOTE. Be aware that if you deploy the real QA with hc3_emulator.deploy=true or using the menu commands with the plugin, the deployed QA will have the quickAppVariable defined and if you upload that for sharing people will see your credential.

 

If someone wants to try this in another IDE than Zerobrane that I use (like Visual Studio) the only thing that could be an issue is to have access to the Lua libraries

Please login or register to see this code.

They are pretty standard lua libraries - based on LuaSocket. @10der 

Please login or register to see this link.

. Here is an updated library/project map to work with the latest version of the emulator 

Please login or register to see this attachment.

. Note that you should update the

Please login or register to see this link.

file provided i the archive when new are released as I will not update this archive for every new release.
@petergebruers 

Please login or register to see this link.

.

 

Any improvements are happily received (in code) and credits will be due granted.

 

Links to notable post

  • Please login or register to see this link.

    when developing code (high-level)
          Some in-depth posts
    • Running "Offline" (TBD)

    • Running in "Mix mode". Mixing real devices and locally emulated devices  (TBD)

    • Running with a "Proxy QA"  (TBD)

    • Using real QA as "Proxy"  (TBD)

    • Downloading HC3 resources to file and emulate them locally  (TBD)

    • Running standard Lua with access to HC3 functions (developing management scripts etc)  (TBD)

    • Loading multiple QAs/Scenes and run them in parallel in the emulator (also getting QAs/Scenes from the HC3 and install them in emulator on the fly...)  (TBD)

    • Running faster than real-time and manipulating start dates  (TBD)

  • Please login or register to see this link.

    to make life easier while debugging
  • Please login or register to see this link.

    .   
  • Please login or register to see this link.

    .  Scene support is not complete.
  • Please login or register to see this link.

  • Please login or register to see this link.

     
  • Please login or register to see this link.

     
  • Please login or register to see this link.

    <here> (nice way to test your code)
  • Using the Web GUI
  • Debugging setTimeout code and tracking timers.
  • Please login or register to see this link.

  • Please login or register to see this link.

    .
  • Please login or register to see this link.

    - if you would like to hack on it :-)
  • A collection of QA's I developed with the SDK - which means that they can be run offline
    • ChildrenOfHue. A QA that creates QA children devices for your Hue devices (It's the Hue QA I use myself these day)
    • Please login or register to see this link.

      . An iOS geopresence QA.
    • iCal (iOS,Google) QA
    • Please login or register to see this link.

      .
    • Please login or register to see this link.

      QA. Helper QA to get/subscribe on event triggers
    • Please login or register to see this link.

      . Send SMS.

 

Changelog:

v 0.67 - numerous bug fixes caused by the restructuring. hc3_emulator.start{startTime="07:00 4/5/2000"} - will start the simulation at the given time. 

v 0.68 - fibaro.debug behaves more like original.

v 0.70 - better offline support and speeding.

v 0.72 - More offline and support for downloading HC3 resources to be used while running disconnected from the HC3

v 0.73 - Various speed-time related bugs

v 0.75 - Better http sync behaviour. Set hc3_emulator.asyncHTTP=true to get some pseudo asynchronous behaviour

v 0.77 - Support for 5.030.45. Initial support for childDevices and fixes for the changed handling of UI events

v 0.78 - UI fix. Name of callbacks defaults to button.."Clicked", unless you have a onReleased=name or onChanged=name in the UI table struct.

v 0.80 - Fixed bug in self:getVariable and self:setVariable

v 0.81 - Better quickVariables handling for proxies, and self.childDevices list updated when children are deleted.

v 0.83 - self:getVariable returns the empty string "" if the variable does not exists according to the latest behaviour on the HC3... 'class' is not redefined if available from Luabind... However, I've not had a chance to test if it's 100% compatible yet...

v 0.84 - Initial support for mqtt. You need to have installed 

Please login or register to see this link.

 so that require("mqtt") works from fibaroapiHC3.lua. I have tried to mimic the HC3 mqtt api but I have not really used mqtt that much so if someone uses it with fibaroapiHC3.lua and discovers if stuff is not compatible with the HC3 implementation please let me know and we fix it.

v 0.85 - Compatibility fix for function 'class' to adhere more closely to the HC3/luabind version

v 0.90 - Cleanup of code, Better handling of children and QuickApps, ZBS color output with ansi escapes; hc3_emulator.colorDebug=true

v 0.93 - New model for QuickApp proxies. Better child device compatibility.

v 0.95 - Various bug fixes - log prints more in line with HC3 log console. fibaro.emitCustomEvent bug fix.

v 0.98 - First support for backup/download/upload with the

Please login or register to see this link.

 (

Please login or register to see this link.

v 0.99 - Better trigger handling and new way to include SDK in your QA/scene code. No hc3_emulator.start at the end.

v 0.100 - Web GUI emulator for QuickApps. New format for using credentials.lua. Bug fixes...

v 0.102 - Better handling of children and their quickAppVariables

v 0.104 - Rewrite of offline mode. Better web UI support.

v 0.105 - Support for new QA file format (proxies work again)

v 0.106 - Added support for net.UDPSocket()

v 0.109 - UDPSocket bug fix. ( @10der), property() support for class() - much harder than it looks...

v 0.110 - Oops, serious bug in 'class' affecting ...everything. Hopefully fixed.

v 0.111 - Removed unnecessary os.exit(). urlencode api calls ( @10der)

v 0.112 - UDP fixes. ( @10der)

v 0.114 - Bug fix (global 'self' escaped)

v 0.115 - Bug in url encode for api calls. UDPSocket :bind(ip,port) function added.

v 0.116 - :bind(ip,port) really fixed....

v 0.117 - startup fix

v 0.119 - "Softer os.exit()" - better compatibility with Visual Studio (thanks @10der)

v 0.120 - Debugger friendly QuickApp class (no __index). First version of file/backup

v 0.121 - api.get bug fix. Faster proxy/deploy.

v 0.123 - QuickApp:setVariable bug (thanks  @10der)

v 0.124 - fibaro.clearTimeout added, MQTT fixes.

v 0.125 - fibaro.alarm() was buggy - fixed. Set self.USERPIN to pincode to allow fibaro.alarm("disarm") to be allowed from emulator.

v 0.126 - fix __fibaro_get_device() ( @10der)

v 0.128 - fix sort order of triggers. Default room in offline mode ( @10der)

v 0.130 - fix UI handling ( @rangee. More UI options.

v 0.131 - fix uiCallbacks not always updating when updating proxy

v 0.135 - fixes...

v 0.137 - TCPSocket fixes

v 0.138 - setTimeout for negative times are inserted in the queue.... i.e. will execute as soon as possible.

v 0.140 - fixed bug with setInterval (clearInterval within a setInterval function didn't work...)

v 0.141 - fix bug in net.TCPClient()

v 0.145 - bug in printout of sockets... stricter class constructor requirements

v 0.148 - MQTT event format bug ( @jayrock)

v 0.150 - Initial websocket support. Need to download wsLua_ER.lua from my github and put in project directory.

v 0.152 - support fibaroapiHC3plug.lua v0.4

v 0.155 - bugfixes. 

v 0.156 - html color bugfix

v 0.198 - New version of emulator with better support for everything. Thanks to @petrkl12 that has been a guinea pig and helped in debugging the code.

v 0.200 - Fixed bug in speedTime. plugin.restart() now restarts the QA in a correct way.

v 0.299 - Major rewrite of the HC3 API - cleaner architecture and prepared for being split into sub-files (I'm approaching 10k lines now). Note 'end--hc3' required to end header.

v 0.300 - Bugfixes from v0.299

v 0.301 - Better/simpler class definition - easier to debug/step into classes (avoiding __index unless class uses property() )

 

Edited by jgab
  • Like 2
  • Thanks 4
Link to comment
Share on other sites

  • Topic Author
  • Here is a post with some notes on the implementation of the SDK.

     

    The overall components looks like this

    Please login or register to see this attachment.

    From a scene or a quickapp you interact with the HC3 using the fibaro.*() functions, like fibaro.call(id,action), or directly using the api.*() calls, like api.get("/devices/88")

    If you run remotely towards the HC3 the api.*() commands are translated to http REST commands to the HC3.

    That's pretty straightforward.

     

    The SDK supports to automatically install a proxy QA for the QA you are developing with the SDK. That proxy traps all the UI events, when you press a button or drag a slider, and make callbacks to the SDK. The SDK starts a WebAPI server on port 6872 when you run the code that listens for incoming requests from the HC3, like requests for UI triggers. The WebAPI then looks up the corresponding QuickApp:function in the QA you are developing and calls it. In this way your QA can react to UI clicks and you can debug it.

    All the QuickApp functions available from self:*, like self:updateView() or self:getVariable() are just translated to api.*() calls so they go to the HC3.

     

    There is also a remote event loop that continuously polls the HC3 for new events using the /refresStates REST api. New events can cause triggers to start your scene if you are developing a scene. Scenes have a "conditions" part that is compiled and filters the triggers to decide if a trigger should start the scene.

    If you run a QuickApp, the remote event loop doesn't do that much for you, but behind the scenes we cache events that we get so that remote calls like fibaro.getValue don't have to make a remote calls every time. Also if you call api.get("/refreshState...") it will fetch the data from the local cache.

     

    If you set 'hc3_emulator.offline=true", the api.*() commands sends their requests to a local api handler with a database with the resources, like devices, globalVariables etc. Remember that the api.*() calls do REST get/post/put/delete operations.

    The database checks if the actions changes a value and in that case emits a trigger that scenes can trigger on.

     

    That's more or less it.

     

    The actual code when folded looks like this:

    Please login or register to see this attachment.

    It's one big honking  file with everything included. Part of the philosophy is that it should be easy to setup. Now it's just one file in the same folder as the code you are working on. The non-standard Lua dependencies that exists is on the included libraries for socket and http - but they are included with Zerobrane, and should be available for most other environments (they seem to be based on Luasocket)

     

    So, first in the file is the version - always use the latest.

    Then some libraries that is needed for socket and http functions - they come bundled with ZeroBrane Studio but may need to be added for other environments.

    Local variables that are important. We create our own versions of os.time() and os.date() so we can speed up the time if wanted.

    Then the 9 modules that make up the SDK.

    • FibaroAPI - all the fibaro.*() and api.*() functions are defined here
    • Timer - The important implementation of setTimeout resides here. That is the heart or engine of the SDK that drives all the other parts. It can also do tricks like speeding up the time.
    • QuickApp - the definition of QuickApp.* and some extra functions for creating proxies etc.
    • Scene - compiler for "conditions" that filter triggers.
    • Trigger - the remote event loop that polls the HC3 for events
    • Utilities - common code used by the other modules
    • Json - a open source json library from Rix
    • WebAPI - the web server for remote calls from the HC3. In the future it could also serve up som GUI - maybe simulate QuickApp GUI too?
    • Offline - the offline database and the simulated rest APIs used when you have set hc3_emulator.offline=true

    at the bottom we load the module in the right order needed, and add some functions to the hc3_emulator that is good to have.

    ...and then we define the hc3_emulator.start{} function used to start the emulator and that is called from the user's code. It's decides if the code is a QA or a Scene and calls runQA or runScene from respective module.  The last thing that the hc3_emulator.start{} does is to do Timer.start() that runs and schedules all the timers that drive the emulator in a tight loop. Every piece of code that gets called after that somehow originates from a timer/setTimout (polling the HC3, the WebAPI, users own timers etc)

     

    Despite the ~3000 lines of code there are still things that are incomplete:

    • Scene handling could be better. Some conditions like cron-intervals are not yet supported (mostly because I think the semantic is iffy). Regular cron with "match" works + sunset/sunrise
    • Offline handling only deals with basic resources like devices, globals, and customEvents at the moment.
    • Better error checks...
    • More support for tracing...
    • Would like to have an interpreter plugin for ZBS so that the header and start can be omitted from the code.
    • ...and of course - bugs bugs bugs...

     

    You are all welcome to improve the code if you find it useful.

    Edited by jgab
    • Thanks 1
    Link to comment
    Share on other sites

    Here's error report.

    When trigger incoming,  if value contains "%" char then  it return's error.

    fibaroapiHC3.lua:1490: bad argument #2 to 'format' (no value)

    line1490 : local str = format(table.unpack(args))

    Link to comment
    Share on other sites

  • Topic Author
  • 1 hour ago, rangee said:

    Here's error report.

    When trigger incoming,  if value contains "%" char then  it return's error.

    fibaroapiHC3.lua:1490: bad argument #2 to 'format' (no value)

    line1490 : local str = format(table.unpack(args))

    Thanks for the report, a classic bug that I accidentally have done many times - will fix asap.

    Edited by jgab
    Link to comment
    Share on other sites

  • Topic Author
  • 48 minutes ago, rangee said:

    Here's error report.

    When trigger incoming,  if value contains "%" char then  it return's error.

    fibaroapiHC3.lua:1490: bad argument #2 to 'format' (no value)

    line1490 : local str = format(table.unpack(args))

     

    Fixed bug in format. v0.66

    Link to comment
    Share on other sites

  • Topic Author
  • Here is an example running a scene.

    The HC3 scene code is from 

    that @robw et.al has been testing out.

     

    I make no claims about the correctness of the code, but that's not the purpose of this post. Instead, let's try to run it offline, without using the HC3 at all, simulating the devices involved.

    We use the fibaroapiHC3.lua code and Zerobrane.

    Because scenes are divided up in a 'conditions' section and an 'actions' sections we need to put those parts in

    Please login or register to see this code.

    and

    Please login or register to see this code.

    The first being a Lua table and the second being a Lua function, because we need to call it when the scene is triggered.

    Because we are running offline we need to define the devices involved (type of devices) and their initial states.

    We do that inside a "preamble" function

    Please login or register to see this code.

    The complete "simulated" scene code looks like

    Please login or register to see this code.

    In the preamble, we create the devices involved, dimmer, motion sensor and lux sensor. We initiate them to the values they should have when we start up.

    Then we end by breaching the motion sensor after 5 seconds, and then we set it back to safe after another 20s.

    The scene ’condition’ is defined so that the scene should be triggered when the motion sensor is set to safe.

    Running the code produces.

    Please login or register to see this code.

    We can see at the logged times that things happens when we expect them. We can also set breakpoints and inspect Lua variables etc.

    The scene turns off the light after 180s of motion sensor being safe. It can be a bit boring waiting for that when coding/debugging.

    Setting 'speed' to true in hc3_emulator.start{...} at the end will run the scene faster than real time - but the logged times will still be correct.

    We can also set the time we want to start at (maybe Xmas next year?) by setting 'startTime' to another time in hc3_emulator.start{}.

     

    Well, it's a start and I will improve the code to cater for more "features" and less bugs :-) 

     

     

     

    Edited by jgab
    • Like 2
    Link to comment
    Share on other sites

    Thank you! Looking forward to new smart light code :)

     

    I tried your code like below, but got "[ERROR] 2020-03-14 14:00:28: (load):78: <eof> expected near 'end'". If I delete the last "end" it runs and turns on the light for about 2-3 seconds then turns it off. I've set luxmin very high just for the tests. It was about 733 lux when I tested.

     

     

    local hc = fibaro
    jT = json.decode(hc.getGlobalVariable("HomeTable")) 
     
    local light = {jT.Bathroom.bathroomlamp}
    local motion = jT.Bathroom.motion
    local lux = tonumber(hc.getValue(jT.Bathroom.lux, "value"))
    local luxmin = 800
     
      count = 0
      function checkLights()
        if #light > 0 then
          for i = 1, #light
          do
            if hc.getValue(light"state"then count = count+1 end
          end
        end
      end
     
      function turnon()
        if #light > 0 then
          for i = 1, #light
          do
            hc.call(light,"turnOn");
            hc.debug("","Turning on");
            hc.sleep(100)
          end
        end
      end
     
      function turnoff()
        if #light > 0 then
          for i = 1, #light
          do
            hc.call(light,"turnOff");
            hc.debug("","Turning off");
            hc.sleep(100)
          end
        end
      end
     
      checkLights()
      if count >0 then state = "On" else state = "Off" end
     
      hc.debug("","Current lux: ",lux)
      hc.debug("","minlux: ",luxmin)
      if state == "Off" then
        if luxmin < lux then hc.debug("","room to light to turn on  lights")
        else
          local maxTime = 1*60  -- max time the sensor should be safe before turning off
          local sleepTime = 3   -- time in seconds between each check of the sensor
     
          turnon()
     
          local safeTime = 0
          while safeTime < maxTime do
            hc.sleep(sleepTime*1000)                 
            safeTime=safeTime+sleepTime                   -- count up safeTime
            hc.debug("","Counting up safeTime ",safeTime,maxTime)  
     
            count = 0 
            checkLights()
            if count >0 then state = "On" else state = "Off" end
            if state == "Off" then hc.debug("","Light(s) turned off manual");
              break 
            end
     
            if hc.getValue(motion,"value"then -- motion breached
              safeTime=0                                 -- reset safeTime
              hc.debug("","Reset")
            end
          end 
     
          turnoff()
       end
      else hc.debug("","Light manual turned on")
      end
      hc.debug("","Scene ended")
      end
    Link to comment
    Share on other sites

  • Topic Author
  • Please login or register to see this link.

     Here is a plugin for ZeroBrane studio. 

    Put it in the zerobrane folder, in ZBS/packages/ or HOME/.zbstudio/packages folder (where ZBS is the path to ZeroBrane Studio location and HOME is the path specified by the HOME environment variable)

    Plugin: 

    It's not fully developed yet but has a few features.

    • In ZBS 'Help' menu there are links to this thread, the Fibaro QuickApp manual, and Fibaro Lua Scene manual etc.
    • Under 'File' menu there is a "Create HC3sdk database" command that copies some of the most common resources from the HC3 and stores it in a file in the current working directory. File is named "HC3sdk.db". That file can then be loaded into the emulator when you run a scene/QA by adding the option hc3_emulator.start{loadDB=true}. This only works when running offline, but is a convenient way to have access to "existing" devices and globals in offline testing
    • Under 'File' there is a "Create HC3 backup" that downloads QuickApps, Scenes, Global variables, Locations, and Custom Events to a backup directory - more below.
    • Under 'File' there is a "Download files..." that downloads the selected resource from GitHub  - more below.
    • Under "Edit" there is a menu that inserts in the current window templates for a QuickApps and a Scene with the added hc3_emulator commands needed.
    • There is also under "View" a "HC3 Emulator" command that opens a web page available while a QA/Scene is running.

    Future add-on that would be nice...

    • Upload of Scene to the HC3
    • ...

     

    Please login or register to see this attachment.

    "Copy HC3 data..." copies resource info from the HC3 and stores it in "HC3sdk.db". Can be used in offline-offline mode.

     

    Please login or register to see this attachment.

    "Download files from my Github into the current directory. Requires HC3 credentials to have been setup. By default I try to load "credentials.lua" from current directory to get the credentials.

     

    Please login or register to see this attachment.

    "HC3 SDK templates..." insert a Scene or QuickApp code skeleton in the current buffer to be used with the emulator.

     

    Please login or register to see this attachment.

    Deploy QuickApp will build and deploy the complete QuickApp in the current editor buffer to the HC3. If multiple files (like the toolbox) is included it will add this files to the QA.

     

    Please login or register to see this image.

    /monthly_2020_04/plug5.png.a437e22a4f53029f7e19dabbb4e36e8e.png" />

    Practical browser links to this thread and Fibaro's Scene and QuickApp documentation.

     

    plug3.png.81904e873f706a6f0fb488687da11d88.png

    Autocompletion for HC3 Lua commands, fibaro.* etc.

     

    plug1.png.ea6bd4af45c047c42bdb4c314fc7438a.png

    ..with arguments

    Please login or register to see this attachment.

    ...and tooltip

     

     

    200331 - auto completion and tooltips added for HC3 functions.

    200405 - download option for latest fibaroapiHC3.lua

    200512 - resource management

     

    Please login or register to see this attachment.

    Edited by jgab
    Link to comment
    Share on other sites

    • 2 weeks later...

    I was testing 

        net.HTTPClient({ timeout = 5000 })

     

    And noticed the emulator stayed at 60 seconds timeout

    If you change this:

          options = options or {}

          for k,v in pairs(moptions or {}) do options[k]=v end

          local req = options.options or {}

     

    To this:

          options = options or {}
          for k,v in pairs(moptions or {}) do options.options[k]=v end
          local req = options.options or {}
     

    It seems to work. I don't know if you can pass other arguments than "timeout" to net.HTTPClient.

    Link to comment
    Share on other sites

  • Topic Author
  • 4 hours ago, petergebruers said:

    I was testing 

        net.HTTPClient({ timeout = 5000 })

     

    And noticed the emulator stayed at 60 seconds timeout

    If you change this:

          options = options or {}

          for k,v in pairs(moptions or {}) do options[k]=v end

          local req = options.options or {}

     

    To this:

          options = options or {}
          for k,v in pairs(moptions or {}) do options.options[k]=v end
          local req = options.options or {}
     

    It seems to work. I don't know if you can pass other arguments than "timeout" to net.HTTPClient.

     

    Thanks, old bug - never use the init arg to HTTPClient...

    I also added hc3_emulator.asyncHTTP=true to enable pseudo asynchronous behaviour. (your test case with the tick loop works more "realistic"). I timeout every second to let other setTimeout get time to run. It's a not enabled by default as it is very special cases I guess this is needed - e.g. refreshStates....

    Also, in hc3_emulator.BasicAuthentication is the base64 encoded credentials. "Basic ...."

    v 0.75.

    Edited by jgab
    • Thanks 1
    Link to comment
    Share on other sites

  • Topic Author
  • Updates of the Zerobrane plugin with autocompletions, tooltips and other practical stuff.

     

    Link to comment
    Share on other sites

  • Topic Author
  • New version 0.77.

    Support for childDevices and fixes for the changed handling of UI events

    The example in the Fibaro QuickApp child documentation works.

    The requirement is to enable proxy on the HC3. (hc3_emulator.start{proxy=true}

    They are surprisingly fun to play with :-)

     

    Btw, it was also fun and challenging to get to the bottom with the class structure they use QuickAppBase -> QuickApp, QuickAppBase -> QuickAppChild and all the intrinsics of getting a proxy run with self:createChildDevice, self:initChildDevices... but I think I have figured it out.

    So childDevices are cool and have nice GUIs but can we add a custom GUI to them?

    Ex. I have this "com.fibaro.colorController" child device and I get on/off buttons and 2 sliders for color and brightness automatically. Can I add more custom UI elements to it?

     

    Anyway, here is an example using this QuickApp code in the SDK emulator

    Please login or register to see this code.

    Create the following on the HC3 (316 - the 'main' device should be com.fibaro.deviceController, but I changed before I took the screenshot)

    Please login or register to see this attachment.

    ..and you can set breakpoints in the SDK emulator and debug your child devices :-)

    There are a number of child devices in the screenshot (7 to be precise) because the example creates a new child every time it starts. A real example would save away already created devices like in Fibaro's own example doc.

     

    The log in ZeroBrane then look like:

    Please login or register to see this code.

     

     

    Edited by jgab
    Link to comment
    Share on other sites

    Thanks for the update v0.81. I am not 100% sure but I think your definition of "class" might clash if this was general purpose Lua. But it is not general purpose, it is HC3 specific so I doubt it is significant. But I changed this, to be in line with other functions in your code... to see what it would look like. Feel free to implement or ignore...

     

    So line 812

    class 'QuickAppBase'()

    becomes

    Util.class 'QuickAppBase'()

     

    Same change line 861 Util.class 'QuickApp'(QuickAppBase) and 897 Util.class 'QuickAppChild'(QuickAppBase)

     

    Then line 1732

    function class(name)

     

    becomes

    self.class = function (name)

     

    Haven't had a chance to play with "child devices" yet... Looks promising.

    Link to comment
    Share on other sites

  • Topic Author
  • 5 hours ago, petergebruers said:

    Thanks for the update v0.81. I am not 100% sure but I think your definition of "class" might clash if this was general purpose Lua. But it is not general purpose, it is HC3 specific so I doubt it is significant. But I changed this, to be in line with other functions in your code... to see what it would look like. Feel free to implement or ignore...

     

    So line 812

    class 'QuickAppBase'()

    becomes

    Util.class 'QuickAppBase'()

     

    Same change line 861 Util.class 'QuickApp'(QuickAppBase) and 897 Util.class 'QuickAppChild'(QuickAppBase)

     

    Then line 1732

    function class(name)

     

    becomes

    self.class = function (name)

     

    Haven't had a chance to play with "child devices" yet... Looks promising.

    Thanks.

     'class' is a global function on the HC3, and so is 'QuickAppBase' and 'QuickAppChild' (actually, the latter are "classes"). With HC3 global functions I'm a bit sloppy and declare them a bit here and there.

    'class' is defined in Util. but not scoped with Util because it's supposed to be a global function anyway. I could do

    self.class = function(name)

    but I would need to do

    class = Util.class

    anyway to export it as a global.

    'class' does not exist in standard Lua so my version is a variant that tries to mimic the one in HC3 by allowing the syntax

    class 'ClassName'(ParentClass)

     

     

    Edited by jgab
    Link to comment
    Share on other sites

    12 hours ago, jgab said:

     'class' is a global function on the HC3

    Yes. It is not documented but it is used in "plugins" so also HC2 has it. Not sure why it is not documented.

     

    12 hours ago, jgab said:

    'class' does not exist in standard Lua so my version is a variant that tries to mimic the one in HC3 by allowing the syntax

    Sure, mimicking this is a good thing as long as class does not get defined elsewhere, and I am totally fine with the way you do it now. I assume it would conflict if you had eg luabind on your pc, I did not try... Thinking out loud, you could define global 'class' only if it does not already exist.

    Link to comment
    Share on other sites

  • Topic Author
  • 49 minutes ago, petergebruers said:

    Yes. It is not documented but it is used in "plugins" so also HC2 has it. Not sure why it is not documented.

     

    Sure, mimicking this is a good thing as long as class does not get defined elsewhere, and I am totally fine with the way you do it now. I assume it would conflict if you had eg luabind on your pc, I did not try... Thinking out loud, you could define global 'class' only if it does not already exist.

    Ok I understand what you mean. I will look at it.

    Link to comment
    Share on other sites

  • Topic Author
  • 16 minutes ago, jgab said:

    Ok I understand what you mean. I will look at it.

    Ok, I don't redefine 'class' if it's already available. A bit worried if I'm 100% compatible though.. Could be that I'm doing something with class that's not allowed by Luabind's version... Well, we will find out :-)

     

    • Thanks 1
    Link to comment
    Share on other sites

  • Topic Author
  • Initial support for mqtt.

    Please login or register to see this code.

    prints the log

    Please login or register to see this code.

    If you find discrepancies with the HC3 api let me know..

    You need to have installed 

    Please login or register to see this link.

     so that require("mqtt") works from fibaroapiHC3.lua

    Edited by jgab
    Link to comment
    Share on other sites

  • Topic Author
  • The SDK can be useful for coding and debugging large projects with a lot of moving parts. Zerobrane studio allows for setting conditional breakpoints and live variables watches which is real time savers compared to a myriad of debug printouts.

    Have my own little project with 3000+ lines of code but lets take another example how to setup a project.

    A recent great QA from @Krikroff for controlling a Sonos players is advanced enough to exercise most corners of the SDK/emulator.

     

    Normally we setup  a QA post- and preamble that includes the SDK/emulator into the QA you are developing.

    Another approach is to have a skeleton/template and include the QA code:

    Please login or register to see this code.

    We could have included the code, but its many lines of code and we don't want to make any accidental changes to the code. Instead we do a Lua 'dofile' to insert the code.

    The QA also have a GUI with buttons. we declare them also so that the proxy on the HC3 will get the same buttons. 

    (I'm working on a method to automatically import and export QAs to Zerobrane so this would be autogenerated)

    Anyway, we set proxy=true which means that when we run the code it creates a proxy on the HC3 with buttons that send requests back to the QA you run in Zerobrane.

    Please login or register to see this attachment.

     

    In  ZeroBrane studio we get the log:

    Please login or register to see this code.

    ...and we can open the file ""SonosKrikroff.lua"" in another window in Zerobrane and set breakpoints and step through the code... Zerobrane understands files included with dofile.

    We can also click on buttons on the HC3 QA UI and get triggers back into the button handlers in Zerobrane.

     

    In Zerobrane it is also possible to set the template/skeleton file as start file, meaning that when you press run it will always run that file.

    That mean that you can have the real file you work on open and when you press run, it runs the right file first.

     

    So at the moment its a little bit of setup needed for a project but its usually worth it in the development speed gained - compared to run and debug on the HC3...

     

    Edited by jgab
    • Like 2
    Link to comment
    Share on other sites

    @jgab thanks for your advices and framework! 
    Without your fibaroapiHC3.lua, I would not be able to create my QAs.

    Link to comment
    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...