openhab / openhab-webui

Web UIs of openHAB
Eclipse Public License 2.0
223 stars 239 forks source link

Dynamic expressions doesn't return Integer for Number item state. #1272

Closed marcinczeczko closed 4 months ago

marcinczeczko commented 2 years ago

The problem

I was about to configure Default Widget for the Number item representing battery level of the sensor.

I wanted to dynamically assign icon depending on the item state. So, if used following expression that gets the item via items[props.item] in the "Icon" field I'm always getting the "else" condition value:

value: ""
config:
  icon: '=(items[props.item].state > 50) ? "if:mdi:battery-100" :
    "if:mdi:battery-alert"'

I investigated a little bit and found out that, if I use expression with the Item name directly, then apparently the state value is integer and condition is evaluated as expected

value: ""
config:
  icon: '=(items.Test.state > 50) ? "if:mdi:battery-100" : "if:mdi:battery-alert"'
  iconUseState: true

Expected behavior

items[props.item].state should behave same way as items.<ItemName>.state and return same type (integer for Number items)

Steps to reproduce

  1. Create dummy Item Number Test
  2. Configure DefaultWidget Metadata for the item as explained above
  3. Using OSGi console send updated to the items to see the issue (try two versions of expressions) openhab:send Test <Value>

Your environment

runtimeInfo:
  version: 3.2.0
  buildString: Release Build
locale: pl-PL
systemInfo:
  configFolder: /etc/openhab
  userdataFolder: /var/lib/openhab
  logFolder: /var/log/openhab
  javaVersion: 11.0.13
  javaVendor: Azul Systems, Inc.
  javaVendorVersion: Zulu11.52+13-CA
  osName: Linux
  osVersion: 5.10.63-v7l+
  osArchitecture: arm
  availableProcessors: 4
  freeMemory: 755099344
  totalMemory: 1424363520
bindings:
  - amazonechocontrol
  - astro
  - automower
  - exec
  - hpprinter
  - http
  - mail
  - mqtt
  - network
  - ntp
  - openweathermap
  - samsungtv
  - spotify
  - systeminfo
  - zwave
clientInfo:
  device:
    ios: false
    android: false
    androidChrome: false
    desktop: true
    iphone: false
    ipod: false
    ipad: false
    edge: false
    ie: false
    firefox: false
    macos: true
    windows: false
    cordova: false
    phonegap: false
    electron: false
    nwjs: false
    webView: false
    webview: false
    standalone: false
    os: macos
    pixelRatio: 1
    prefersColorScheme: dark
  isSecureContext: true
  locationbarVisible: true
  menubarVisible: true
  navigator:
    cookieEnabled: true
    deviceMemory: 8
    hardwareConcurrency: 8
    language: pl
    languages:
      - pl
      - en
      - en-US
    onLine: true
    platform: MacIntel
  screen:
    width: 1920
    height: 1080
    colorDepth: 24
  support:
    touch: false
    pointerEvents: true
    observer: true
    passiveListener: true
    gestures: false
    intersectionObserver: true
  themeOptions:
    dark: dark
    filled: true
    pageTransitionAnimation: default
    bars: light
    homeNavbar: default
    homeBackground: default
    expandableCardAnimation: default
  userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36
    (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
timestamp: 2022-01-11T13:12:12.932Z

Browser console

Empty

Browser network traffic

Additional information

Rossko57 commented 2 years ago

Are you sure your Item state doesn't have a unit incorporated? (e.g. % for battery)

ghys commented 2 years ago

items.<itemName>.state and items['<itemName>'].state should be the same, at least the syntax is supposed to be equivalent. Those always return strings, no matter what the actual item type is, because that's how the REST API behaves. Try something like: icon: '=(Number.parseInt(items.Test.state > 50)) ? "if:mdi:battery-100" : "if:mdi:battery-alert"'

Rossko57 commented 2 years ago

Comment: Number type Items can hold both integer and float states. So a string version of the state (that you are usually dealing with in widgets) will be "5" or "5.0". Those are mathematically equal of course, but "5" does not equal "5.0" - two different strings. You need to be careful to parse the string into a number if you want to do maths comparisons on it.

florian-h05 commented 4 months ago

In case you need a number, please use the new .numericState property. (It will be available with openHAB 4.2.0 in two weeks.)

Closing now as this should solve your problem.