Run Java script inside automation

The code works

Weird. It did not work when I was testing in the developer tools. Then it suddenly did. Something weird going on…

Here is a screenshot of the variable.

This is strange. I can’t see anything else being done with the mA value but being averaged before it goes in to this calculation in the javascript.

I wonder what the values are in the node red script.

Can you add a few node.warn(variable_name);
in the code and run it in node red?

Example:

// Main starts here
var y;
var measured_mA = msg.payload; // get mA value from Sensor as input
node.warn(measured_mA);
var measured_mA_mean;
measured_mA_mean = context.get('measured_mA_mean');
node.warn(measured_mA_mean);
if (context.get('Startup') == 341487) {
    context.set("Startup", 0)
    measured_mA_mean = measured_mA;
}
node.warn(measured_mA_mean);

and so on.

output
image

and the code

template:
  - sensor:
      - name: 'Füllstand_Zisterne_l'
        state: >
          {% set measured_mA_mean = (states('sensor.fullstand_zisterne_ma')|int) %} 
          {% set list = {
            0: 0,
            100: 135,
            200: 320,
            300: 550,
            400: 825,
            500: 1120,
            600: 1450,
            700: 1800,
            800: 2160,
            900: 2530,
            1000: 2895,
            1100: 3245,
            1200: 3580,
            1300: 3885,
            1400: 4160,
            1500: 4430,
            1600: 4585,
            1700: 4720,
            1800: 4780} %}
           {{ list[((5 * 1000 / (20 - 4) * (measured_mA_mean - 4)) / 100) | int *100]  }}

I think I’ve got it. The variable seems to be recognized as a string. If I convert this to int, the sensor is displayed correctly

Big thanks for your help

But unfortunately the calculation does not seem to fit correctly.

If I now test both calculations with different values, I don’t get anywhere near the same results.
Example mA value 7.6
Jinja = 2530
Javascript = 3329

Example mA value 6.5
Jinja = 1450
Javascript = 2093

Example mA value 9.2
Jinja = 4430
Javascript = 4619

Is there still a chance to adapt the jinja script so that the results are more similar to the javascript?

Well, no. You originally cast to a float, that should work just as well numerically for the calculation. But then when you go to your lookup table it only has discrete steps, asking for anything in between would return undefined.

For your information, we are talking about a water tank whose content can be calculated based on the height of the water.
The height is the first value in the table, the volume is the second value.

However, the volume is not linear. In the middle is more volume with less increasing height. I hope you understand what I mean.

a picture of the water tank

If the form can be approximated close enough with a cylinder, it shouldn’t be very difficult to calculate the volume from the height. Just a tiny bit of trigonometry. If the shape is more irregular though then maybe not worth it…

It doesn’t have to be accurate to the liter. I received the volume specification for the corresponding height from the manufacturer.
The height is given in cm.
The Javascript uses this to calculate the available water in the tank.
Unfortunately, I don’t have the knowledge to implement it in Jinja or another language.

One thing I don’t really understand in the JavaScript code is the max height. It says 5 but comment say 4m.

In the code it seems this value is used as the height of the tank, but the table only goes to 1.8.

When it try with 1.8 instead of 5 the values seems more reasonable.

Edit: only the last line has changed

{% set measured_mA_mean = 5 %} # states('sensor.mean_value_ma')

{% set list = {
      0: 0,
    100: 135,
    200: 320,
    300: 550,
    400: 825,
    500: 1120,
    600: 1450,
    700: 1800,
    800: 2160,
    900: 2530,
    1000: 2895,
    1100: 3245,
    1200: 3580,
    1300: 3885,
    1400: 4160,
    1500: 4430,
    1600: 4585,
    1700: 4720,
    1800: 4780} %}
{{ list[((1.8 * 1000 / (20 - 4) * (measured_mA_mean - 4)) / 100) | int *100] }}

They don’t match the JavaScript output.
But is really 9.2 almost full?
The value can go to 20.

To be clear this code is not accurate.
It rounds down the height to closest hundred and compares with the table.
It can be made more accurate but, just need to see of it matches somewhat.

3 = error
4 = 0
5 = 135
6.5 = 320
7.6 = 825
9.2 = 1120
15 = 3580
20 = 4780
21 = error

I may be wrong but I think the original Javascript example does more than just a quick arithmetic calculation to find a list index.

For example, not sure what this custom function spline(measured_mA_mean) achieves but it appears to tweak the passed variable. Another part of the code, after performing a lookup in the list, attempts to interpolate a result if it didn’t find a perfect match in the list.

That might explain why the OP reports the Javascript and Jinja2 versions don’t produce identical results.

Yes I know about the interpolation.
That is could be done in Jinja too, but I’m not sure that is a correct thing to do.

I also tried to find what spline does but I didn’t find it with a quick search.

But I believe the number should be 1.8 and not 5.
In my opinion the numbers make sense.
I can try and do one for each value between 4 and 20.

Hello StefanW,

Well the table conversion could easily be done with the Compensation Integration. This would even allow you to extrapolate beyond the dataset.
Then the rest is just simple automation or script logic.

The code in the previous post gives this:

4: 0
5: 135
6: 320
7: 550
8: 825
9: 1120
10: 1450
11: 1800
12: 2530
13: 2895
14: 3245
15: 3580
16: 3885
17: 4160
18: 4430
19: 4585
20: 4780

Less change in the start and end and more in the middle.

Thank you for your help. Background. There is a probe in the tank. The probe hangs almost at the bottom of the tank and sends a value between 4 and 20mA depending on the water pressure (fill level). The probe can detect a water depth of 5m.

However, as my tank is only 1.8m deep, my probe is already full at 10mA and should then display 4780 liters.

If the probe sends 4mA, the tank is almost empty. So about 300-400 liters.

The script must now convert the mA into liters. We had the best experience with spline back then. I got a lot of help for the script.

I hope this now brings some clarity to the existing environment.

You could have told us that 10 was full.
Anyways in that case I can’t see what is wrong here.

4.0: 0
4.5: 135
5.0: 550
5.5: 825
6.0: 1450
6.5: 1800
7.0: 2530
7.5: 2895
8.0: 3580
8.5: 4160
9.0: 4430
9.5: 4720
10.0: 4780

I will test it. What calculation did you use to arrive at the values?

We had a few different ones.

That was the original with max height 5