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


Recommended Posts

Posted (edited)

Welcome to the completely unnecessary applications series! Part N+1.

TableMan: An HTML Table Server for Nice/Fibaro HC3

The Fibaro UI has quite a few limitations. But it also has some real possibilities: it supports simple HTML tags, it can display SVG, and that opens up quite a few ways to present data sensibly.

 

One of the simplest and most commonly used ways of presenting data is a table. We can see tables in many user applications. I think quite a few people have written their own libraries for handling HTML tables and then include them in their next QuickApps.

I did the same. Over time I ended up with five “generations” of increasingly sophisticated libraries, plus one mini version. One of those libraries used SVG instead of HTML and could display tables stacked on top of each other like windows (they even cast shadows!). This turned out to be very useful, for example, for preference screens (very long preference sections in many applications I have seen are a problem).

The last HTML approach already had table filtering and sorting, cell merging, formatting, a two-level cache, and a few other bells and whistles. The code exceeded 900 lines.

 

There were 15 user applications, and each of them had to carry those 900 lines and meet their memory requirements. That meant about 13,000 lines of repeated code: some applications used this part, others used that part, and none of them used everything. I do not even want to mention how much work updating it required. And yes, bugs did happen.

 

That led to the question: can tables in Fibaro be done in a client-server model? Can large libraries included in every application be replaced with one central QuickApp that handles tables for everyone, while leaving only a thin client inside each application? It turned out that yes, they can. After a few weeks of work, a working version of TableMan was born.

 

Command Language

The assumption was simple: it should be possible to build complex tables with single lines of code, and writing a value to a table cell should be almost as simple as print. The whole thing comes down to a small command language. It is a set of simple commands that can be used to construct and update tables. The currently available commands are:

 

link, display, hide, delete, set, style, setRow, setCol, styleRow, styleCol, styleAll, clear, clearCell, clearValue, clearStyle, header, merge, unmerge, addRows, deleteRows.

 

You can combine several tables into one view, merge ranges of cells, format individual cells, whole rows and columns, change colors, clear values or styles, add and delete rows. The server can also automatically choose a contrasting text color for the background. Thanks to this, quite sophisticated tables can be created in a very simple way.

Typical usage looks like this (first you need to register with the service and create a table using new😞

Please login or register to see this code.

 

Most commands accept many attributes that make it possible to control practically every aspect of the table’s appearance: text and background colors, font and font size, horizontal and vertical alignment, and so on.

Importantly, only the explicitly provided attribute is changed. Everything else remains as it was. This makes it possible to shape the table’s appearance incrementally, without having to set all attributes at once.

 

Server

It is one central QuickApp that receives commands from its clients. It stores private table data for each client, executes commands, and, when needed, updates the client’s UI directly.

There is no classic return communication here. The client sends a command (fire and forget), and the server does the rest. There are no confirmations, negotiations, callbacks, or additional protocol. If something needs to be displayed, the server sends ready HTML directly to the appropriate UI element of the client.

This is a deliberate simplification. It is hard to expect execution confirmation from print.

The server has extensive error diagnostics, but it does not return errors to the client. It logs them on its own console. There are more than thirty types of errors, so it is visible whether the problem is an invalid cell range, a nonexistent table, bad parameters, and so on.

It also has its own administrative tables: it shows clients, their activity, number of operations, traffic profile, and the load generated by individual applications and tables. This is very helpful for finding the chattiest applications and trimming them down.

Writing to a table does not automatically display it. So you can build or update a table with many commands (at minimal CPU cost), and only at the end execute the display command.

 

Client

On the application side there are two client variants.

The first one is very simple. It is suitable for applications that rarely update data or have small tables. It has about 80 lines of code. It collects commands into batches and sends them to the server in one go, to reduce the number of hub.call

 

The second client is larger, about 220 lines, but it contains a simple yet very effective cache mechanism: if a given command has already been sent to the server and nothing in it has changed, the client does not send it again. It also cuts off display if there were no real changes in the table. This greatly reduces communication for semi-static tables, where some cells do not change and only individual values are updated. The application no longer needs its own layer for limiting communication.

The cache is fast. It is based on calculating a hash, which is cheaper than ordinary cache searching: the table index is the command and address (which is also based on hashing, just internally in LUA) and the value is a hash of the parameters. One has to be very careful, because once every ~30 years or so there may be a hash collision (2^32). The effectiveness in reducing communication is impressive, considering the simplicity of the solution.

 

Results

The work is still in progress, but I think the results are very good.

Thanks to the optimizations, the CPU load of the hub did not increase, or increased only very slightly. On the other hand, for reasons that are not entirely clear, memory demand visibly calmed down. There is about six times less code (overall), but the data still has to be stored somewhere.
The consequence of no back-communication to client is that cells data cannot be read, only write. If needed it's application responsibility to remember such data. But The client have to be very simple, so it's the price. The second reason is that it would have to be asynchronous, which I personally do not like.

 

The most important benefit, however, is architectural.

The server model allows functionality to be added and improved without interfering with client applications. This is achieved by the fact that the client has only three functions, completely independent of the command language: register, new, and exec. Client is completely stupid. It does not know the commands, parameters, it checks nothing. 

Only sends an "intention": execute the commands, show the result. Rest is server-sided.

 
If a new feature appears in the server, an application can use it without replacing the client. It is enough to call the new command through exec.

Only very large architectural changes would require replacing the client.

 

Please login or register to see this attachment.

 

Please login or register to see this attachment.

 
 
 
 
Edited by Łukasz997
  • Like 6
  • 3 weeks later...
Posted

Will you share your code when finished?

  • Topic Author
  • Posted

     

    13 minut temu, Christb napisał:

    Will you share your code when finished?

    I will think about it and answer soon.

    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...