UI4 UI5 Migration

From MiOS
(Difference between revisions)
Jump to: navigation, search
m
 
(41 intermediate revisions by one user not shown)
Line 1: Line 1:
[[Category:UI5]]
+
[[Category:Development]] [[Category:UI5]]
 
Our newest Ui5 does some things differently than Ui4.  This page explains the changes in Ui5 that may not be obvious to Ui4 users.
 
Our newest Ui5 does some things differently than Ui4.  This page explains the changes in Ui5 that may not be obvious to Ui4 users.
  
Line 24: Line 24:
 
They are now called "Triggers", but they work exactly the same way.  It's a tab in the scene editor.
 
They are now called "Triggers", but they work exactly the same way.  It's a tab in the scene editor.
  
==Developer changes==
+
== Developer changes ==
  
=== eventList ===
+
=== eventList2  ===
The '''eventList''' in the D_...json is now normalized. The format from UI4 was a mistake all along, treating arrays as objects. So this:
+
 
 +
The '''eventList''' in the D_...json is now '''eventList2'''.
 +
 
 +
'''eventList''' and '''argumentList''' are now arrays containing an element '''id''' that has the id, rather than putting the id in the tag name (i.e. '''event_1''' becomes '''"id": 1''').
 +
 
 +
Also, to support multi-language firmwares, some changes have been made:
 +
 
 +
1. The following objects now have a property called '''HumanFriendlyText''':
 +
 
 +
*arguments from '''argumentList''',  
 +
*values from '''allowedValueList'''.
 +
 
 +
HumanFriendlyText is an object that has the following properties:
 +
 
 +
*'''lang_tag''': an ID for the text used for translation;
 +
*'''text''': the text to be displayed on the UI. There are 2 placeholders that can be used in this text:
 +
**'''_DEVICE_NAME_''', which will be replaced with the device name,
 +
**'''_ARGUMENT_VALUE_''', available only for arguments in the '''argumentList''', which will be replaced by the actual value set by the user.
 +
 
 +
2. '''label''', '''prefix''' and '''suffix''' are now objects which have 2 properties: '''lang_tag''' and '''text'''.
 +
 
 +
e.g. This event list:  
  
 
     "eventList": {
 
     "eventList": {
        "event_1": {
+
      "event_1": {
            "label": "Incoming call from",
+
          "label": "Thermostat HEAT set point goes over",
            "serviceId": "urn:upnp-ap15e-com:serviceId:FCM1",
+
          "serviceId": "urn:upnp-org:serviceId:TemperatureSetpoint1_Heat",
            "norepeat": "0",
+
          "argumentList": {
            "argumentList": {
+
              "argument_1": {
                "argument_1": {
+
                  "dataType": "i4",
                    "dataType": "string",
+
                  "name": "CurrentSetpoint",
                    "name": "CallSource",
+
                  "comparisson": ">",
                    "comparisson": "=",
+
                  "prefix": "temperature: ",
                    "prefix": "Phone number",
+
                  "suffix": " degrees"
                    "suffix": ""
+
              }
                }
+
          }
            }
+
      },
        },
+
      "event_2": {
        "event_2": {
+
          "label": "A device is turned on or off",
            "label": "Outgoing call to",
+
          "serviceId": "urn:upnp-org:serviceId:SwitchPower1",
            "serviceId": "urn:upnp-ap15e-com:serviceId:FCM1",
+
          "argumentList": {
            "norepeat": "0",
+
              "argument_1": {
            "argumentList": {
+
                  "dataType": "boolean",
                "argument_1": {
+
                  "defaultValue": "1",
                    "dataType": "string",
+
                  "allowedValueList": {
                    "name": "CallDestination",
+
                      "Off": "0",
                    "comparisson": "=",
+
                      "On": "1"
                    "prefix": "Phone number",
+
                  },
                    "suffix": ""
+
                  "name": "Status",
                }
+
                  "comparisson": "=",
            }
+
                  "prefix": "Which mode",
        }
+
                  "suffix": ""  
    },
+
              }  
 +
          }  
 +
      }
 +
  }
 +
 
 +
is now:
 +
 
 +
    "eventList2": [
 +
      {
 +
          "id": 1,
 +
          "label": {
 +
              "lang_tag": "thermostat_heat_point_goes_over",
 +
              "text": "Thermostat HEAT set point goes over"
 +
          },
 +
          "serviceId": "urn:upnp-org:serviceId:TemperatureSetpoint1_Heat",
 +
          "argumentList": [
 +
              {
 +
                  "id": 1,
 +
                  "dataType": "i4",
 +
                  "name": "CurrentSetpoint",
 +
                  "comparisson": ">",
 +
                  "prefix": {
 +
                      "lang_tag": "temperature",
 +
                      "text": "Temperature"
 +
                  },
 +
                  "suffix": {
 +
                      "lang_tag": "degrees",
 +
                      "text": "degrees"
 +
                  },
 +
                  "HumanFriendlyText": {
 +
                      "lang_tag": "hft_thermostat_heatpoint_goes_over",
 +
                      "text": "_DEVICE_NAME_: Heat setpoint goes over _ARGUMENT_VALUE_ degrees"
 +
                  }
 +
              }
 +
          ]
 +
      },
 +
      {
 +
          "id": 2,
 +
          "dataType": "boolean",
 +
          "defaultValue": "1",
 +
          "allowedValueList": [
 +
              {
 +
                  "value": "0",
 +
                  "HumanFriendlyText": {
 +
                      "lang_tag": "hft_device_turned_off",
 +
                      "text": "_DEVICE_NAME_ is turned off"
 +
                  }
 +
              },
 +
              {
 +
                  "value": "1",
 +
                  "HumanFriendlyText": {
 +
                      "lang_tag": "hft_device_turned_on",
 +
                      "text": "_DEVICE_NAME_ is turned on"
 +
                  }
 +
              }
 +
          ],
 +
          "name": "Status",
 +
          "comparisson": "=",
 +
          "prefix": {
 +
              "lang_tag": "which_mode",
 +
              "text": "Which mode"
 +
          },
 +
          "suffix": {}
 +
      }
 +
  ]
 +
 
 +
=== sceneList ===
 +
 
 +
The ''sceneList'' tag is obsolete. In UI5 the commands available for scenes are the same commands that can be given to a device from the dashboard controls. So if we have a device with 4 buttons in the Control Panel, but only 2 of them on the dashboard, only these 2 can be used in the scene.
 +
 
 +
=== New device tags ===
 +
 
 +
The device is the top level container. It has the following tags:
 +
 
 +
*'''inScene''': If this tag is present and has the value ''"1"'', the device will be usable in the scene editor.
 +
*'''x''', '''y''': These represent the device box dimensions, ''x'' and ''y'' being the width and the height respectively. 1x = 80 pixels, 1y = 24 pixels. These are used to tell the UI how much space you need to draw all the controls (excluding the header and the icon). A button has x = 1 and y = 1, an horizontal slider has x = 2 and y = 1 and a vertical slider has x = 0.5 and y = 3.
 +
 
 +
The device can have 0 or more ''SceneGroups''.
 +
 
 +
=== ''SceneGroup'' ===
 +
 
 +
''SceneGroup'' is a new type of container, similar to a ControlGroup, but with some key differences: it is customizable (by setting its position and dimensions) and it defines the behavior of the buttons assigned to the same state variable. If two buttons in the same SceneGroup are assigned to the same variable, only one of them can be activated in the scene editor (radio buttons behavior). If two buttons assigned to the same variable are in different SceneGroups, both can be activated at the same time in the scene editor (checkboxes behavior).
 +
 
 +
It has the following tags:
 +
 
 +
*'''id''': A numeric value (positive integer numbers).
 +
*'''top''': The offset from the device header. It uses the same units as ''x'' and ''y''.
 +
*'''left''': The offset from the device icon. It uses the same units as ''x'' and ''y''.
 +
*'''x''', '''y''': the dimensions of the SceneGroup. e.g If I have two horizontally aligned buttons in the SceneGroup, ''x'' will be ''2'' and ''y'' will be ''1''.
 +
 
 +
A ''SceneGroup'' can contain one or more ''ControlGroups''.
 +
 
 +
=== New ''ControlGroup'' tags ===
 +
 
 +
In UI5, the ''ControlGroup'' is an intermediary container between the controls and the ''SceneGroups''. You can't place a control on the dashboard unless you place it in a ''ControlGroup'', which in turn must be placed in a ''SceneGroup''.
 +
 
 +
*'''scenegroup''': This tells the UI in which SceneGroup this ControlGroup will be placed.
 +
*'''isSingle''': Since controls cannot be grouped in drop-down lists anymore, this tag has a different role in UI5. When ''isSingle'' is ''"1"'', the buttons in the ControlGroup will have a background (e.g. the ''BinaryLight'' buttons). If ''isSingle'' is missing, the buttons won't have a background (e.g. the Thermostat buttons).
 +
 
 +
'''Note:''' ''type'' is not used anymore.
 +
 
 +
=== New control tags ===
 +
 
 +
Controls can be positioned relative to the ''SceneGroup'' in which they're placed with the following tags:
 +
 
 +
*'''top'''
 +
*'''left'''
 +
 
 +
Also, their dimensions can be specified with
 +
 
 +
*'''x''', '''y'''
 +
 
 +
Similar to the scene group dimensions, 1x = 80px, 1y = 24px. Dimensions are applicable to '''variables''' and '''labels''' only. Default dimensions for a control are ''1x'' and ''1y''.
 +
 
 +
For '''variables''' and '''labels''' text alignment can be specified with:
 +
 
 +
*'''text_align''': this can be ''left'', ''right'' or ''center''. The default value is ''center''.
 +
 
 +
'''Note:''' ''ControlPair'' and ''ControlHeader'' are not used anymore.
 +
 
 +
[[Image:Demo grid.jpg|600px|Demo grid.jpg]]
 +
 
 +
=== Lua Files  ===
 +
==== The '''''<files>''''' tag ====
 +
<span style="color: rgb(255, 0, 0);">'''Note:''' The Lua files must be terminated with a newline character, i.e the last code line shouldn't be the last line in the file.</span>
  
now needs to be like this, where '''eventList''' and '''argumentList''' are now arrays containing an element '''''id''''' that has the id, rather than putting the id in the tag name (i.e. '''event_1''' becomes '''"id": 1'''):
+
Since firmware version 1.5.228, LuaUPnP has native support for Lua files, so it's not necessary anymore to create modules and "require" them. In the implementation file you must add the '''&lt;files&gt;''' XML tag, which is a comma separated list of .lua files to be included in the same Lua state as the device. So now you can mix code in the I_ file and .lua files without any need for ''requires''; they all get merged at runtime anyway.
  
    "eventList": [
+
e.g. This is how the implementation file for the Z-Wave Routing Matrix plugin looks like. The ''startup'' function is defined in the L_ZWaveRoutingMatrix.lua file. It '''must not be declared as local''', otherwise it won't be found.
        {
+
            "id": 1,
+
            "label": "Incoming call from",
+
            "serviceId": "urn:upnp-ap15e-com:serviceId:FCM1",
+
            "norepeat": "0",
+
            "argumentList": [
+
                {
+
                    "id": 1,
+
                    "dataType": "string",
+
                    "name": "CallSource",
+
                    "comparisson": "=",
+
                    "prefix": "Phone number",
+
                    "suffix": ""
+
                }
+
            ]
+
        },
+
        {
+
            "id": 2,
+
            "label": "Outgoing call to",
+
            "serviceId": "urn:upnp-ap15e-com:serviceId:FCM1",
+
            "norepeat": "0",
+
            "argumentList": [
+
                {
+
                    "id": 1,
+
                    "dataType": "string",
+
                    "name": "CallDestination",
+
                    "comparisson": "=",
+
                    "prefix": "Phone number",
+
                    "suffix": ""
+
                }
+
            ]
+
        }
+
    ],
+
  
 +
<implementation>
 +
    <specVersion>
 +
        <major>1</major>
 +
        <minor>0&</minor>
 +
    </specVersion>
 +
    <files>L_ZWaveRoutingMatrix.lua</files>
 +
    <startup>startup</startup>
 +
</implementation>
  
===New Tags===
+
==== The '''''require()''''' function  ====
====ui5_x, ui5_y====
+
These tags can appear in root or in '''[[#ui5_SceneGroup|ui5_SceneGroup]]''' and they represent the device box dimensions, '''ui5_x''' and '''ui5_y''' being the width and the height respectively. 1x = 100 pixels, 1y = 24 pixels.
+
  
====ui5_onDashboard====
+
In firmware version 1.5.261 the '''require''' Lua function has been overloaded to handle compressed Lua files. Also, setting the '''package.path''' variable is no longer necessary for Lua files in '''/etc/cmh-lu''' and '''/etc/cmh-ludl'''.  
If this tag is present and has the value '''"1"''' the device will be pinned on the dashboard at creation.
+
  
====ui5_inScene====
+
'''<span style="color: rgb(255, 0, 0);">NOTE:</span>'''<span style="color: rgb(255, 0, 0);"> The compressed modules must be declared with '''module()''', and not using any of the alternative forms.</span>
If this tag is present and has the value '''"1"''', the device can be used in scenes.
+
  
====ui5_image_src====
+
=== New device file tags  ===
Used in '''[[#image_player|image_player]]''' controls for specifying the image file to be used for the skin.
+
  
====ui5_SceneGroup====
+
==== ''<Category_Num>'' and ''<SubCategory_Num>''  ====
ui5_SceneGroup is an array which contains the definition for all the control groups (clusters).
+
  
    "ui5_SceneGroup": [
+
These tags were previously added at runtime. Starting with firmware version 1.5.308 it's possible to specify the device [http://wiki.micasaverde.com/index.php/Luup_UPNP_Files#Device_Categories category] and [http://wiki.micasaverde.com/index.php/Luup_UPNP_Files#Device_Sub-Categories subcategory] using these tags.
        {
+
            "id": "1",
+
            "isSingle": "1",
+
            "ui5_top": "0",
+
            "ui5_left": "0",
+
            "ui5_x": "2",
+
            "ui5_y": "1"
+
        }
+
    ]
+
  
===New Control Types===
+
For a heater, this is how the tags look like:
====image_player====
+
This is a skinnable button. It has the same tags as a button plus the '''[[#ui5_image_src|ui5_image_src]]''' tag for specifying the image used for the skin.
+
  
e.g. Here is the '''Up''' button from the camera:
+
<Category_Num>5</Category_Num>
    {
+
<SubCategory_Num>2</SubCategory_Num>;
        "ControlType": "image_player",
+
        "Label": {
+
            "lang_tag": "cmd_up",
+
            "text": "Up"
+
        },
+
        "Display": {
+
            "Top": 49,
+
            "Left": 466,
+
            "Width": 75,
+
            "Height": 20
+
        },
+
        "Command": {
+
            "Service": "urn:micasaverde-com:serviceId:PanTiltZoom1",
+
            "Action": "MoveUp",
+
            "Parameters": [
+
               
+
            ]
+
        },
+
        "ui5_image_src": "images/player/image_control_up.png"
+
    },
+

Latest revision as of 06:10, 8 June 2013

Our newest Ui5 does some things differently than Ui4. This page explains the changes in Ui5 that may not be obvious to Ui4 users.

Contents

[edit] Single user interface

With UI4 there were several different user interfaces, such as the dashboard, the wizard, the cp.mios.com portal, etc. To view the current status of a device you went to the dashboard. To view the history of a device you went to cp.mios.com. Now there's just one UI and everything is one place. As always some of the features are handled locally by Vera, and others are handled by a server. But rather than having to check 2 UI's, they are all together. If you are viewing a popup or a tab that requires features handled by the server, such as a history of your notifications, you will see that you are prompted to login with your mios.com username when you try to choose those tabs or features. Also, if you do login to mios.com, but do not yet have a Vera, you will be notified of this when you select features that are handled by Vera locally, such as controlling devices.

[edit] Scenes

Scenes have been changes substantially. In Ui4 there were up to 4 different ways to specify "turn on light #3". On the dashboard there were on and off buttons, and in the wizard similar buttons. When adding light #3 to a scene, on and off were pull-downs. And you had the option of adding it both as a 'normal' scene and as an 'advanced' scene, and as part of a delay (ie turn off light #3 and 30 seconds later turn it on).

With Ui5 the goal is to make sure that the same action is always done exactly the same way. So if you want to turn on light #3 in the dashboard, you click the 'on' button for the light. If you're creating a scene and want it to turn on light #3, you still see the same control like on the dashboard and still click 'on' the same way.

So now when you create or edit a scene you'll see that you essentially get your dashboard. Devices that are grayed out are not involved in the scene (ie unchanged). Click one of the controls in the device to add it to the scene. Clicking 'on', like you would on the dashboard, means turn the light on. The delays are handled now by a the "Add commands to be run X seconds after the scene". So if previously in UI4 you had light #3 turn on and turn off after 30 seconds, and light #4 turn on and turn off after 45 seconds, then when you migrate to UI5 you'll have a pull-down that has "Immediate" which shows light #3 and #4 on, and also a "after 30 seconds" which has light #3 off, and also an "after 45 seconds" which has light #4 off. You can now add as many delays as you want, like, immediately do nothing to light #3, turn it on after 30 seconds, dim it to 50% after 60 seconds, and turn it off after 5 minutes.

Also in UI4 you had 'advanced' command (on the advanced tab) vs. 'normal' commands (on the command tab). And it was impossible to see all your commands in one place. In Ui5 there's no longer the concept of normal vs. advanced commands. There is still an Advanced tab, but this is only an advanced "view" of the same commands. The same commands are shown on the devices tabs as on the advanced tab. The advanced tab just presents it in a table view with all the commands in the scene. Whereas the devices tab let's you build a scene more like a macro recorder, by just clicking on the devices the same way you would on the dashboard.

[edit] Timers

They are now called "Schedules", but they work exactly the same way. It's a tab in the scene editor.

[edit] Events

They are now called "Triggers", but they work exactly the same way. It's a tab in the scene editor.

[edit] Developer changes

[edit] eventList2

The eventList in the D_...json is now eventList2.

eventList and argumentList are now arrays containing an element id that has the id, rather than putting the id in the tag name (i.e. event_1 becomes "id": 1).

Also, to support multi-language firmwares, some changes have been made:

1. The following objects now have a property called HumanFriendlyText:

  • arguments from argumentList,
  • values from allowedValueList.

HumanFriendlyText is an object that has the following properties:

  • lang_tag: an ID for the text used for translation;
  • text: the text to be displayed on the UI. There are 2 placeholders that can be used in this text:
    • _DEVICE_NAME_, which will be replaced with the device name,
    • _ARGUMENT_VALUE_, available only for arguments in the argumentList, which will be replaced by the actual value set by the user.

2. label, prefix and suffix are now objects which have 2 properties: lang_tag and text.

e.g. This event list:

   "eventList": {
      "event_1": {
          "label": "Thermostat HEAT set point goes over",
          "serviceId": "urn:upnp-org:serviceId:TemperatureSetpoint1_Heat",
          "argumentList": {
              "argument_1": {
                  "dataType": "i4",
                  "name": "CurrentSetpoint",
                  "comparisson": ">",
                  "prefix": "temperature: ",
                  "suffix": " degrees" 
              } 
          } 
      },
      "event_2": {
          "label": "A device is turned on or off",
          "serviceId": "urn:upnp-org:serviceId:SwitchPower1",
          "argumentList": {
              "argument_1": {
                  "dataType": "boolean",
                  "defaultValue": "1",
                  "allowedValueList": {
                      "Off": "0",
                      "On": "1" 
                  },
                  "name": "Status",
                  "comparisson": "=",
                  "prefix": "Which mode",
                  "suffix": "" 
              } 
          } 
      }
  }

is now:

   "eventList2": [
      {
          "id": 1,
          "label": {
              "lang_tag": "thermostat_heat_point_goes_over",
              "text": "Thermostat HEAT set point goes over"
          },
          "serviceId": "urn:upnp-org:serviceId:TemperatureSetpoint1_Heat",
          "argumentList": [
              {
                  "id": 1,
                  "dataType": "i4",
                  "name": "CurrentSetpoint",
                  "comparisson": ">",
                  "prefix": {
                      "lang_tag": "temperature",
                      "text": "Temperature"
                  },
                  "suffix": {
                      "lang_tag": "degrees",
                      "text": "degrees"
                  },
                  "HumanFriendlyText": {
                      "lang_tag": "hft_thermostat_heatpoint_goes_over",
                      "text": "_DEVICE_NAME_: Heat setpoint goes over _ARGUMENT_VALUE_ degrees"
                  }
              }
          ]
      },
      {
          "id": 2,
          "dataType": "boolean",
          "defaultValue": "1",
          "allowedValueList": [
              {
                  "value": "0",
                  "HumanFriendlyText": {
                      "lang_tag": "hft_device_turned_off",
                      "text": "_DEVICE_NAME_ is turned off"
                  }
              },
              {
                  "value": "1",
                  "HumanFriendlyText": {
                      "lang_tag": "hft_device_turned_on",
                      "text": "_DEVICE_NAME_ is turned on"
                  }
              }
          ],
          "name": "Status",
          "comparisson": "=",
          "prefix": {
              "lang_tag": "which_mode",
              "text": "Which mode"
          },
          "suffix": {}
      }
  ]

[edit] sceneList

The sceneList tag is obsolete. In UI5 the commands available for scenes are the same commands that can be given to a device from the dashboard controls. So if we have a device with 4 buttons in the Control Panel, but only 2 of them on the dashboard, only these 2 can be used in the scene.

[edit] New device tags

The device is the top level container. It has the following tags:

  • inScene: If this tag is present and has the value "1", the device will be usable in the scene editor.
  • x, y: These represent the device box dimensions, x and y being the width and the height respectively. 1x = 80 pixels, 1y = 24 pixels. These are used to tell the UI how much space you need to draw all the controls (excluding the header and the icon). A button has x = 1 and y = 1, an horizontal slider has x = 2 and y = 1 and a vertical slider has x = 0.5 and y = 3.

The device can have 0 or more SceneGroups.

[edit] SceneGroup

SceneGroup is a new type of container, similar to a ControlGroup, but with some key differences: it is customizable (by setting its position and dimensions) and it defines the behavior of the buttons assigned to the same state variable. If two buttons in the same SceneGroup are assigned to the same variable, only one of them can be activated in the scene editor (radio buttons behavior). If two buttons assigned to the same variable are in different SceneGroups, both can be activated at the same time in the scene editor (checkboxes behavior).

It has the following tags:

  • id: A numeric value (positive integer numbers).
  • top: The offset from the device header. It uses the same units as x and y.
  • left: The offset from the device icon. It uses the same units as x and y.
  • x, y: the dimensions of the SceneGroup. e.g If I have two horizontally aligned buttons in the SceneGroup, x will be 2 and y will be 1.

A SceneGroup can contain one or more ControlGroups.

[edit] New ControlGroup tags

In UI5, the ControlGroup is an intermediary container between the controls and the SceneGroups. You can't place a control on the dashboard unless you place it in a ControlGroup, which in turn must be placed in a SceneGroup.

  • scenegroup: This tells the UI in which SceneGroup this ControlGroup will be placed.
  • isSingle: Since controls cannot be grouped in drop-down lists anymore, this tag has a different role in UI5. When isSingle is "1", the buttons in the ControlGroup will have a background (e.g. the BinaryLight buttons). If isSingle is missing, the buttons won't have a background (e.g. the Thermostat buttons).

Note: type is not used anymore.

[edit] New control tags

Controls can be positioned relative to the SceneGroup in which they're placed with the following tags:

  • top
  • left

Also, their dimensions can be specified with

  • x, y

Similar to the scene group dimensions, 1x = 80px, 1y = 24px. Dimensions are applicable to variables and labels only. Default dimensions for a control are 1x and 1y.

For variables and labels text alignment can be specified with:

  • text_align: this can be left, right or center. The default value is center.

Note: ControlPair and ControlHeader are not used anymore.

Demo grid.jpg

[edit] Lua Files

[edit] The <files> tag

Note: The Lua files must be terminated with a newline character, i.e the last code line shouldn't be the last line in the file.

Since firmware version 1.5.228, LuaUPnP has native support for Lua files, so it's not necessary anymore to create modules and "require" them. In the implementation file you must add the <files> XML tag, which is a comma separated list of .lua files to be included in the same Lua state as the device. So now you can mix code in the I_ file and .lua files without any need for requires; they all get merged at runtime anyway.

e.g. This is how the implementation file for the Z-Wave Routing Matrix plugin looks like. The startup function is defined in the L_ZWaveRoutingMatrix.lua file. It must not be declared as local, otherwise it won't be found.

<implementation>
   <specVersion>
       <major>1</major>
       <minor>0&</minor>
   </specVersion>
   <files>L_ZWaveRoutingMatrix.lua</files>
   <startup>startup</startup>
</implementation>

[edit] The require() function

In firmware version 1.5.261 the require Lua function has been overloaded to handle compressed Lua files. Also, setting the package.path variable is no longer necessary for Lua files in /etc/cmh-lu and /etc/cmh-ludl.

NOTE: The compressed modules must be declared with module(), and not using any of the alternative forms.

[edit] New device file tags

[edit] <Category_Num> and <SubCategory_Num>

These tags were previously added at runtime. Starting with firmware version 1.5.308 it's possible to specify the device category and subcategory using these tags.

For a heater, this is how the tags look like:

<Category_Num>5</Category_Num>
<SubCategory_Num>2</SubCategory_Num>;
Personal tools