boc-tothefuture / openhab-jruby

JRuby Libraries for Openhab
Eclipse Public License 2.0
6 stars 9 forks source link

Error when dividing items #640

Closed pacive closed 1 year ago

pacive commented 1 year ago

Just encountered a freak error when trying to do some math: Non-terminating decimal expansion; no exact representable decimal result. (Java::JavaLang::ArithmeticException)

I guess it would be hard to reproduce, since it probably depends on the state of the items at the time of the calculation, but this is the code, and full log output (might be reproducible using items with these exact states, but not sure):

rule 'Test' do
  on_start
  run do
    logger.info("Helper library version: #{OpenHAB::VERSION}")
    logger.info("Current: #{Tibber_Currentprice}")
    logger.info("Mean: #{Tibber_Meanprice}")
    logger.info("Stddev: #{Tibber_Pricestddev}")
    logger.info("Difference: #{Tibber_Currentprice - Tibber_Meanprice}")
    logger.info("Normalized deviation: #{(Tibber_Currentprice - Tibber_Meanprice) / (Tibber_Pricestddev)}")
  end 
end
2022-09-17 20:45:46.750 [INFO ] [rulesupport.loader.ScriptFileWatcher] - Loading script '/etc/openhab/automation/jsr223/ruby/personal/test.rb'
2022-09-17 20:45:49.953 [INFO ] [g.openhab.automation.jruby.test.test] - Helper library version: 4.44.2
2022-09-17 20:45:49.958 [INFO ] [g.openhab.automation.jruby.test.test] - Current: 1.5047
2022-09-17 20:45:49.960 [INFO ] [g.openhab.automation.jruby.test.test] - Mean: 0.7526999999999998
2022-09-17 20:45:49.962 [INFO ] [g.openhab.automation.jruby.test.test] - Stddev: 0.48311340913594664
2022-09-17 20:45:49.970 [INFO ] [g.openhab.automation.jruby.test.test] - Difference: 0.7520000000000002
2022-09-17 20:45:49.980 [ERROR] [obj.OpenHAB.DSL.Rules.AutomationRule] - Non-terminating decimal expansion; no exact representable decimal result. (Java::JavaLang::ArithmeticException)
In rule: Test
java.math.BigDecimal.divide(java/math/BigDecimal.java:1722)
RUBY.<main>(/etc/openhab/automation/jsr223/ruby/personal/test.rb:11)
RUBY.<main>(/etc/openhab/automation/jsr223/ruby/personal/test.rb:3)
java.util.Optional.ifPresent(java/util/Optional.java:183)
java.util.concurrent.Executors$RunnableAdapter.call(java/util/concurrent/Executors.java:515)
java.util.concurrent.FutureTask.run(java/util/concurrent/FutureTask.java:264)
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(java/util/concurrent/ScheduledThreadPoolExecutor.java:304)
java.util.concurrent.ThreadPoolExecutor.runWorker(java/util/concurrent/ThreadPoolExecutor.java:1128)
java.util.concurrent.ThreadPoolExecutor$Worker.run(java/util/concurrent/ThreadPoolExecutor.java:628)

Seems to be some issue with BigDecimal, but doing som other calculations using BigDecimal doesn't err:

logger.info(BigDecimal(1) / BigDecimal(3))

gives

2022-09-17 20:49:06.811 [INFO ] [g.openhab.automation.jruby.test.test] - 0.333333333333333333e0

Also, doing the exact same thing in Rules DSL works, even when explicitly converting to BigDecimal:

logInfo('Test', 'Current: {}', Tibber_Currentprice.state)
logInfo('Test', 'Mean: {}', Tibber_Meanprice.state)
logInfo('Test', 'Stddev: {}', Tibber_Pricestddev.state)
logInfo('Test', 'Difference: {}', ((Tibber_Currentprice.state as DecimalType).toBigDecimal - (Tibber_Meanprice.state as DecimalType).toBigDecimal))
logInfo('Test', 'Normalized deviation: {}', ((Tibber_Currentprice.state as DecimalType).toBigDecimal - (Tibber_Meanprice.state as DecimalType).toBigDecimal) / (Tibber_Pricestddev.state as DecimalType).toBigDecimal)
2022-09-17 20:51:08.943 [INFO ] [org.openhab.core.model.script.Test  ] - Current: 1.5047
2022-09-17 20:51:08.946 [INFO ] [org.openhab.core.model.script.Test  ] - Mean: 0.7526999999999998
2022-09-17 20:51:08.947 [INFO ] [org.openhab.core.model.script.Test  ] - Stddev: 0.48311340913594664
2022-09-17 20:51:08.950 [INFO ] [org.openhab.core.model.script.Test  ] - Difference: 0.7520000000000002
2022-09-17 20:51:08.953 [INFO ] [org.openhab.core.model.script.Test  ] - Normalized deviation: 1.556570332719516160941622126440062
pacive commented 1 year ago

Jumping through a few hoops made it work:

(Tibber_Currentprice - Tibber_Meanprice).toBigDecimal.divide(Tibber_Pricestddev.state.toBigDecimal, Java::JavaMath::RoundingMode::HALF_UP)

Could adding the RoundingMode to https://github.com/boc-tothefuture/openhab-jruby/blob/main/lib/openhab/dsl/types/decimal_type.rb#L159-L164 solve the issue?

Edit: This also worked, curiously enough without the rounding mode:

(Tibber_Currentprice - Tibber_Meanprice) / (Tibber_Pricestddev.to_d)

So I have a workaround now at least.

github-actions[bot] commented 1 year ago

:tada: This issue has been resolved in version 4.45.1 :tada:

The release is available on:

Your semantic-release bot :package::rocket: