Best Practice Development

After 40 years of coding 6 weeks with ThingsPlex (TP) was an interesting experience. I will try to summarize some of them. Main lesson learned is that if you just try to do it, not doing it the right way, the system can byte you. And that is a lesson learned from mc6800 and z80 … that is still valid.

Variable names
Have a plan for naming variables . I propose that you set yourself a standard. I use Name HAN for the flow reading HAN device . The W value is than stored Globally in a variable named HAN.W , If needing more descriptive names I use full name TIMERS.HourOfDay . Variables that are Global, used by several Flows , set by one and used as commands in others are given names like COMMON.VV.Setpoint . It is set to 0…100 in my main routine, and is interpritated by my water boiler as the % duty cycle per hour that the boiler should be on. …

Creating and debugging a FLOW
When you create your first flow , it is so easy to just jump into it… but stop and think…
Behind the pencil at the top of the edit window you can select if new instances of the flows is to :

  • Run in parallell with old ones

  • Keep old, and disregard new ones

  • Keep new ones and abort old ones :heart:

The last is what you should select , so easy to create a loop …

Development Test and Production enviroments
From the days of SAP systems , doing changes directly in production was unheard . We had 3 or more enviroments, and nothing was introduced in production before being tested . Unless you are having several hubs , this is difficult .

Therefore it is important to take some safety actions. If a flow gobbles up too much resources, it can be hard to stop , and get in contact with HUB. Setting the correct run mode (ABORT OLD ONES) is important.

When saving your flow a Black Bar appears at the bottom of your screen . Allow it to complete. Do not jump out and wait for results. If it takes more than 30 seconds , something might be wrong . Press on the LOG , and await the results of TP interpretering your flow. A report shows up, with error messages . Important that each block has a label , so that it is easy to read and locate the error messages.

When the flow saves ok , the debugging starts. Saving ok , running ok , does not always equals working.

My first error
Typecasting is the term that indicates that if you take price =“100.00 KR” and multiply with vat=1.25 you will in some languages return 125 or “125 KR” or 0 or NULL .

So to set a float to an integer you need to fore a type change by multiplying an integer with a real .
This is why the price from the standard Flow is so hard to get into a global variable of type flow.

But how do you find these errors ?

If the “save” went well , typically the flow is executed top down , and you can insert DEBUGG Blocks in the flow . SET Common.DebuggVariable : "Passing checkpoint Charlie " . You can also break lines below , to only execute down to the DEBUGG Block , it then becomes a Breakpoint.

Then remember that a flow can have multiple triggers. So if you have an action executed every hour , you dont have to wait an hour , just insert a second time trigger to fire the part of the code you are debugging.

Large calculations has been a problem for me . instead of transform in one block like

  Common.PowerEstimate = HAN.W*Common.Faktor/Common.MID  

I use several transform blocks

   Common.PowerEstimate = HAN.W*Common.Faktor
   Common.PowerEstimate = Common.PowerEstimate /Common.MID  

This also allows me to see where error occurs in my calculation .

Structuring the tasks
I have created Shortcuts for all my actions related to hardware. I do not communicate , except for trigger with the devices . This means that when power is cheap and consumption is low , I turn on by calling a Shortcut in Home Actions. The ShortCut is AILoad or AIUnload. In winter I can edit, from my phone , that it should turn up my heat , and in summer turn on my AC .

I try to put all that is device related in one flow for that device. If I should change my VW heater , I would only have to change that flow. The flow for my old on off VW heater , heats with a duty cycle , so that it can heat for 7,5 minutes every 15 minutes , reducing consumption from 2kW to 1 kW. It reads consumption and detects that the heater is “on” but not “eating” power , and then set VW.Temperature to 80 . For each hour without allowing the VW tank to consume power the temperature estimate is reduced by 14/24 .

Is there a conclusion soon ?

So all in all , it’s a jungle out there , if you behave , Tarzan is nice to the nice guys , and beats the bad guys. You cannot force these systems to work, gentle , gentle is the key word !

Start with something simple , like setting up a timer to switch from HOME to SLEEP at 2400 and back at 0700.

But we cannot leave the message stream and the adapter section uncommented. BEFORE trying to set up a flow using device related triggers, go to message stream and find the message you are looking for . Thingsplex Advanced UI (version 13.0) – Futurehome If you dont find it, it means you have to send a specific report request to get it. Then go to Adapter/Services and Manually try to trigger requested report. Verify in message stream. When you manage manually , you can start to code.

HAPPY CODING ! :+1:

9 Likes

The SHOW SOURCE Button

image

Problem of the day was that I regularly check to see if a device should be turned on or off , based on relative (%) , absolute (Kr) or comfort (Wife) cost of doing so.

The default “Home Mode Tracker” is a built in example that store A text , home,sleep,away … in a global fh.home.mode variable … So, no problem , new flow , “Home Action Tracker” , same trigger , but now select SHORTCUT , instead of Home mode

image

Then after trigger completes , dump result in a global variable , and see what happens…

image

The Variable is set to 1, for my first custom ShortCut , 2 for the next , 3 for next … etc etc…

So far so god, just add a bunch of IF’s ? heek = 1 heek = 2 … Ohhhhhh NO !

When saving I started gettin error messages , hitting the LOG button I found “cant convert to 64 float” and other strange messages .

After a long time I startet reading the code … "SHOW SOURCE" . The error found was same if I used seperate IF’s or I used a Transform Map.

The transform looks like this :

But the code for the same was like this

    "ValueMapping": [
          {
            "LValue": {
              "Value": 1,
              "ValueType": "string"
            },
            "RValue": {
              "Value": "A01",
              "ValueType": "string"
            }
          },
          {
            "LValue": {
              "Value": 2,
              "ValueType": "string"
            },
            "RValue": {
              "Value": "A02",
              "ValueType": "string"
            }
          },
          

Do YOU Spot the ERROR ? The conditions never triggered. Neither if used in IF or MAP.

If you compare the LValue to the RValue you see it . Both are defined as string , but since Thingsplex thinks that 1 is an integer it drops the “” .

Editing code to this , and it all works .

    "ValueMapping": [
          {
            "LValue": {
              "Value": "1",
              "ValueType": "string"
            },
            "RValue": {
              "Value": "A01",
              "ValueType": "string"
            }
          },
          {
            "LValue": {
              "Value": "2",
              "ValueType": "string"
            },
            "RValue": {
              "Value": "A02",
              "ValueType": "string"
            }
          },
          

So … For IF and MAP … check that constants, are converted to code correctly , Strings need quotation marks.

And then , in the back … somebody raises his voice and says … STUPID … use Integer and integer on both sides …

 "LValue": {
              "Value": "1",
              "ValueType": "int"
            },
            "RValue": {
              "Value": 1,
              "ValueType": "int"
            }

:sweat_smile:

So … clearly a case of Copy 1,2, edit 2,1 error .

Creating left and right side BOTH as xxx01 and yyy02 as ALFA numerical made “” inserted corectly . Then edit yyy02 to 02 to 2 did not remove the “” .

1 Like

And… ALWAYS read documentation :sweat_smile:

Installatør og avanserte brukere – Futurehome

Avansert oppsett – Futurehome

Avansert bruk av Futurehome - YouTube

Ikke alt helt oppdatert til siste versjon … så les og lytt , men vær kilde kritisk .

For hardcore brukere ligger GITHUB klar GitHub - thingsplex/fimpui .

1 Like

Lots of useful tips here, so good work @ThomasR! I started a similar thread a few years ago, hopefully this might also be useful to some people reading this thread for advice:

3 Likes

MIN HAN KODE

Jeg leser av W i venstre streng , setter variabel W , transformerer w til kW , Transformerer med enkelt filter for ikke å se peaker fra bla induksjonskomfyr, regner på desimaler , teller opp Målinger pr time (MID), summerer målinger pr time, og regner ut ett timesestimat i p1,p2,p3 basert på forrige times forbruk og målepunkter.

Som kuriosa kan nevnes at at om det hadde vært like mange målinger pr minutt fra HAN hadde faktor skulle vært 1. nå er den mello 0.8 og 1.2 , så snntidsprogramering er litt en utfordring når delta T er variabel. Men det er neglisjerbart for alle formål.

Så i Høyre streng gjør jeg noe av det samme med kWh avlesning .

Viktig å merke seg at MID og integral , med flere settes til null i en annen flow , som kjører en gang i timen .

{
  "Id": "4b20ee00-5638-11ed-90a6-71cc296c8b9f",
  "ClassId": "4b20ee00-5638-11ed-90a6-71cc296c8b9f",
  "Author": "hytta@okbase.com",
  "Version": 0,
  "CreatedAt": "2022-10-27T20:45:29.696193Z",
  "UpdatedAt": "2022-11-16T22:17:32.990298573+01:00",
  "Name": "HAN",
  "Group": "sensor_wattage",
  "Description": "",
  "Nodes": [
    {
      "Id": "58",
      "Type": "trigger",
      "Label": "Watt",
      "SuccessTransition": "62",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "pt:j1/mt:evt/rt:dev/rn:zigbee/ad:1/sv:meter_elec/ad:12_2",
      "Service": "meter_elec",
      "ServiceInterface": "evt.meter.report",
      "Config": {
        "InputVariableType": null,
        "IsValueFilterEnabled": false,
        "LookupServiceNameAndLocation": false,
        "PropFilterName": "unit",
        "PropFilterValue": "W",
        "RegisterAsVirtualService": false,
        "Timeout": 0,
        "ValueFilter": {
          "Value": 0,
          "ValueType": "float"
        },
        "ValueJPath": null,
        "ValueJPathResultType": null,
        "VirtualServiceGroup": "ch_0",
        "VirtualServiceProps": {}
      },
      "Ui": {
        "nodeType": "",
        "papp": {
          "customValues": null,
          "nodeId": "16",
          "nodeName": "wattage",
          "nodeType": "wattage"
        },
        "x": 163,
        "y": 203
      },
      "TypeAlias": "Trigger",
      "LastValue": "1142 W"
    },
    {
      "Id": "62",
      "Type": "set_variable",
      "Label": "W",
      "SuccessTransition": "93",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "DefaultValue": {
          "Value": 0,
          "ValueType": ""
        },
        "IsVariableInMemory": false,
        "Name": "W",
        "UpdateGlobal": true,
        "UpdateInputMsg": false
      },
      "Ui": {
        "nodeType": "",
        "x": 159,
        "y": 395
      },
      "TypeAlias": "Set variable"
    },
    {
      "Id": "68",
      "Type": "transform",
      "Label": "Filter",
      "SuccessTransition": "70",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "kW*0.05+kWglatt*0.95",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "kW",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "kWglatt",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 154,
        "y": 741
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "70",
      "Type": "transform",
      "Label": "desimaler",
      "SuccessTransition": "71",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "((kWglatt * 100) - ( (kWglatt * 100) % 1 ) ) / 100",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "kWglatt",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "kWglatt",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 154,
        "y": 919
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "71",
      "Type": "transform",
      "Label": "MID",
      "SuccessTransition": "87",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "MID+1",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "MID",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "MID",
        "TargetVariableType": "int",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 147,
        "y": 1102
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "80",
      "Type": "trigger",
      "Label": "kWh",
      "SuccessTransition": "82",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "pt:j1/mt:evt/rt:dev/rn:zigbee/ad:1/sv:meter_elec/ad:12_2",
      "Service": "meter_elec",
      "ServiceInterface": "evt.meter.report",
      "Config": {
        "InputVariableType": null,
        "IsValueFilterEnabled": false,
        "LookupServiceNameAndLocation": false,
        "PropFilterName": "unit",
        "PropFilterValue": "kWh",
        "RegisterAsVirtualService": false,
        "Timeout": 0,
        "ValueFilter": {
          "Value": "kWh",
          "ValueType": "float"
        },
        "ValueJPath": null,
        "ValueJPathResultType": null,
        "VirtualServiceGroup": "ch_0",
        "VirtualServiceProps": {}
      },
      "Ui": {
        "nodeType": "",
        "x": 677,
        "y": 213
      },
      "TypeAlias": "Trigger",
      "LastValue": "1142 W"
    },
    {
      "Id": "81",
      "Type": "set_variable",
      "Label": "kWh",
      "SuccessTransition": "85",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "DefaultValue": {
          "Value": 0,
          "ValueType": ""
        },
        "IsVariableInMemory": false,
        "Name": "kWh",
        "UpdateGlobal": true,
        "UpdateInputMsg": false
      },
      "Ui": {
        "nodeType": "",
        "papp": {
          "customValues": null,
          "nodeId": "16",
          "nodeName": "wattage",
          "nodeType": "wattage"
        },
        "x": 701,
        "y": 923
      },
      "TypeAlias": "Set variable"
    },
    {
      "Id": "82",
      "Type": "set_variable",
      "Label": "KWH_Temp",
      "SuccessTransition": "84",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "DefaultValue": {
          "Value": 0,
          "ValueType": ""
        },
        "IsVariableInMemory": false,
        "Name": "kWh_Temp",
        "UpdateGlobal": true,
        "UpdateInputMsg": false
      },
      "Ui": {
        "nodeType": "",
        "x": 682,
        "y": 391
      },
      "TypeAlias": "Set variable"
    },
    {
      "Id": "83",
      "Type": "if",
      "Label": "change",
      "SuccessTransition": "",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": [
          {
            "BooleanOperator": "",
            "LeftVariableIsGlobal": true,
            "LeftVariableName": "kWh_Temp",
            "Operand": "gt",
            "RightVariable": {
              "Value": 0,
              "ValueType": "float"
            }
          }
        ],
        "FalseTransition": "",
        "TrueTransition": "81"
      },
      "Ui": {
        "nodeType": "",
        "x": 681,
        "y": 748
      },
      "TypeAlias": "If condition"
    },
    {
      "Id": "84",
      "Type": "transform",
      "Label": "KWH fra temp",
      "SuccessTransition": "83",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "kWh_Temp - kWh",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "kWh",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "kWh_Temp",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 680,
        "y": 569
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "85",
      "Type": "transform",
      "Label": "kWh_LastHour",
      "SuccessTransition": "86",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "kWh_Temp - kWh_LastHour",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "kWh_Temp",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "kWh_LastHour",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 713,
        "y": 1100
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "86",
      "Type": "transform",
      "Label": "kWh_LastHour",
      "SuccessTransition": "88",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "kWh_Temp",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "kWh_Temp",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "kWh_LastHour",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 721,
        "y": 1255
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "87",
      "Type": "transform",
      "Label": "WIntegral",
      "SuccessTransition": "90",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "WIntegral +  kW ",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "kW",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "WIntegral",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 136,
        "y": 1266
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "88",
      "Type": "transform",
      "Label": "Faktor",
      "SuccessTransition": "94",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "kWh_LastHour / (WIntegral / MID )",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "kWh_LastHour",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "Faktor",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 748,
        "y": 1419
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "90",
      "Type": "transform",
      "Label": "Estimate p1",
      "SuccessTransition": "91",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "WIntegral ",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "WIntegral",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "Estimate",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 129,
        "y": 1426
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "91",
      "Type": "transform",
      "Label": "Estimate p2",
      "SuccessTransition": "92",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "Estimate /  MID ",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "MID",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "Estimate",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 135,
        "y": 1575
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "92",
      "Type": "transform",
      "Label": "Estimate p3",
      "SuccessTransition": "",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "Estimate * Faktor ",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "Faktor",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "Estimate",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 126,
        "y": 1740
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "93",
      "Type": "transform",
      "Label": "kW = W /1000",
      "SuccessTransition": "68",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "W / 1000.0",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "W",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "kW",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 146,
        "y": 558
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "94",
      "Type": "transform",
      "Label": "Calculate MID til 0",
      "SuccessTransition": "95",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "MID - MID +1 ",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "MID",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "MID",
        "TargetVariableType": "int",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 739,
        "y": 1596
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "95",
      "Type": "transform",
      "Label": "Null integral",
      "SuccessTransition": "",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "WIntegral - WIntegral",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "WIntegral",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "WIntegral",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 621,
        "y": 1776
      },
      "TypeAlias": "Transform"
    }
  ],
  "Settings": null,
  "IsDisabled": false,
  "IsDefault": false,
  "ParallelExecution": "keep_last"
}type or paste code here
```https://forum.futurehome.io/t/best-practice-development/3931/3

TRAPPE VENDERE OG PULS UTGANGER

Må bare dele dette fine svaret fra @jon : Relé til å automatisk slå seg av? - Thingsplex / Advanced flows - Futurehome

MIN VV kode

Dette er koden for standard rele i pakken fra FH, som jeg bruker.
Fordi denne er stille til den blir spurt , har jeg først en time trigger som ber om rapport, og så en trigger som ber om verdier.

Her leser jeg av slik at min “en gang i timen rutine” finner ut om VV er mett …

KODE :

{
  "Id": "IVBI3zEMh2FwDGz",
  "ClassId": "IVBI3zEMh2FwDGz",
  "Author": "",
  "Version": 0,
  "CreatedAt": "2022-11-08T13:21:35.065544508+01:00",
  "UpdatedAt": "2022-11-11T15:57:53.856610318+01:00",
  "Name": "Status VV",
  "Group": "",
  "Description": "",
  "Nodes": [
    {
      "Id": "1",
      "Type": "time_trigger",
      "Label": "",
      "SuccessTransition": "2",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "DefaultMsg": {
          "Value": "",
          "ValueType": ""
        },
        "Expressions": [
          {
            "Comments": "",
            "Expression": "@every 0h10m00s",
            "Name": ""
          }
        ],
        "GenerateAstroTimeEvents": false,
        "Latitude": 0,
        "Longitude": 0,
        "SunriseTimeOffset": 0,
        "SunsetTimeOffset": 0
      },
      "Ui": {
        "nodeType": "",
        "x": 16,
        "y": 212
      },
      "TypeAlias": "Time trigger"
    },
    {
      "Id": "2",
      "Type": "action",
      "Label": "",
      "SuccessTransition": "",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "pt:j1/mt:cmd/rt:dev/rn:zigbee/ad:1/sv:meter_elec/ad:11_1",
      "Service": "meter_elec",
      "ServiceInterface": "cmd.meter.get_report",
      "Config": {
        "DefaultValue": {
          "Value": "",
          "ValueType": "string"
        },
        "Props": {},
        "RegisterAsVirtualService": false,
        "ResponseToTopic": "",
        "VariableName": "",
        "VirtualServiceGroup": "",
        "VirtualServiceProps": {}
      },
      "Ui": {
        "nodeType": "",
        "x": 19,
        "y": 367
      },
      "TypeAlias": "Action"
    },
    {
      "Id": "3",
      "Type": "trigger",
      "Label": "Les VV",
      "SuccessTransition": "4",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "pt:j1/mt:evt/rt:dev/rn:zigbee/ad:1/sv:meter_elec/ad:11_1",
      "Service": "meter_elec",
      "ServiceInterface": "evt.meter.report",
      "Config": {
        "IsValueFilterEnabled": false,
        "LookupServiceNameAndLocation": false,
        "RegisterAsVirtualService": false,
        "Timeout": 0,
        "ValueFilter": {
          "Value": "",
          "ValueType": "float"
        },
        "VirtualServiceGroup": "ch_0",
        "VirtualServiceProps": {}
      },
      "Ui": {
        "nodeType": "",
        "x": 284,
        "y": 213
      },
      "TypeAlias": "Trigger"
    },
    {
      "Id": "4",
      "Type": "set_variable",
      "Label": "PowerVV",
      "SuccessTransition": "8",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "DefaultValue": {
          "Value": 0,
          "ValueType": ""
        },
        "IsVariableInMemory": false,
        "Name": "PowerVV",
        "UpdateGlobal": true,
        "UpdateInputMsg": false
      },
      "Ui": {
        "nodeType": "",
        "x": 275,
        "y": 402
      },
      "TypeAlias": "Set variable"
    },
    {
      "Id": "5",
      "Type": "transform",
      "Label": "VVTodayTotal",
      "SuccessTransition": "9",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "PowerVV - PowerVVLastDay",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "PowerVV",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "PowerVVToday",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 267,
        "y": 756
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "8",
      "Type": "transform",
      "Label": "VVON",
      "SuccessTransition": "5",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "(PowerVV - PowerVVToday - PowerVVLastDay)*6",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "PowerVV",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "PowerVVLastHour",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [
          {
            "LValue": {
              "Value": 0,
              "ValueType": "float"
            },
            "RValue": {
              "Value": 0,
              "ValueType": "int"
            }
          }
        ],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 272,
        "y": 575
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "9",
      "Type": "transform",
      "Label": "desimaler",
      "SuccessTransition": "10",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "((PowerVVToday*100)-(PowerVVToday*100)%1)/100",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "PowerVVToday",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "PowerVVToday",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 260,
        "y": 917
      },
      "TypeAlias": "Transform"
    },
    {
      "Id": "10",
      "Type": "transform",
      "Label": "desimaler",
      "SuccessTransition": "",
      "TimeoutTransition": "",
      "ErrorTransition": "",
      "Address": "",
      "Service": "",
      "ServiceInterface": "",
      "Config": {
        "Expression": "((PowerVVLastHour*100)-(PowerVVLastHour*100)%1)/100",
        "IsLVariableGlobal": true,
        "IsRVariableGlobal": false,
        "IsTargetVariableGlobal": true,
        "IsTargetVariableInMemory": false,
        "LVariableName": "PowerVVLastHour",
        "RValue": {
          "Value": 0,
          "ValueType": "int"
        },
        "RVariableName": "",
        "Rtype": "var",
        "TargetVariableName": "PowerVVLastHour",
        "TargetVariableType": "float",
        "Template": "",
        "TransformType": "calc",
        "ValueMapping": [],
        "XPathMapping": []
      },
      "Ui": {
        "nodeType": "",
        "x": 256,
        "y": 1073
      },
      "TypeAlias": "Transform"
    }
  ],
  "Settings": null,
  "IsDisabled": false,
  "IsDefault": false,
  "ParallelExecution": "keep_last"
}type or paste code here

Tok meg litt tid å forstå i og med at det er gøymt i koden, men her satte du meg på sporet av noe nyttig:

1 Like