# vera_devices.yaml
#
# Copyright (C) 2020-2025 Kedron Holdings LLC, All Rights Reserved
# This file is part of Reactor.
#
# *** IMPORTANT ***
# This is a system file. DO NOT place overrides or make modifications here.
# You can add or override implementation section items by specifying them
# in local_vera_devices.yaml in your site configuration.
---
version: 25020
revision: 1
format: 1
copyright: Copyright (C) 2020-2025 Kedron Holdings LLC, All Rights Reserved

typemap:
  # 1: "Interface"
  2: "Light"
  3: "Switch"
  4: "SecuritySensor"
  5: "Thermostat"
  6: "Camera"
  7: "Lock"
  8: "Cover"
  11: "Switch"  # Generic I/O
  12: "ValueSensor"  # Generic sensor
  # 13:"SceneCtrl"  # Scene controller
  15: "MediaPlayer"
  16: "ValueSensor"  # Humidity
  17: "ValueSensor"  # Temperature
  18: "ValueSensor"  # Light (lux)
  24: "Switch"  # Siren
  28: "ValueSensor"  # UV
  33: "ValueSensor"  # Flow
  34: "ValueSensor"  # Voltage

deviceclass:
  generic_device:
    capabilities:
      x_vera_device:
        attributes:
          failed:
            source: urn:micasaverde-com:serviceId:HaDevice1/CommFailure
            expr: '( isnull( value ) || ! len( value ) ) ? null : ( int(value) != 0 )'
          configured:
            source: urn:micasaverde-com:serviceId:HaDevice1/Configured
            expr: '( isnull( value ) || ! len( value ) ) ? null : ( int(value) != 0 )'
          device_number: false    # protected value, set by VeraController
          device_type: false      # protected value, set by VeraController
          parent_device: false    # protected value, set by VeraController
        actions:
          set_variable:
            action: urn:micasaverde-com:serviceId:HomeAutomationGateway1/SetVariable
            parameters:
              DeviceNum:
                deref: entity.x_vera_device.device_number
              Service:
                parameter: service
              Variable:
                parameter: variable
              Value:
                parameter: value
  generic_switch:
    extends: generic_device
    capabilities:
      power_switch:
        attributes:
          state:
            source: urn:upnp-org:serviceId:SwitchPower1/Status
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
        actions:
          'on': true  # Use default implementation
          'off': true  # Use default implementation
          'set':
            action: urn:upnp-org:serviceId:SwitchPower1/SetTarget
            parameters:
              newTargetValue:
                expr: "bool( parameters.state ) ? '1' : '0'"
      toggle:
        actions:
          toggle: true  # Use default implementation
  generic_dimmer:
    extends: generic_switch
    capabilities:
      dimming:
        attributes:
          level:
            source: urn:upnp-org:serviceId:Dimming1/LoadLevelStatus
            expr: max(0,min(1, (value ?# 0)/100.0))
        actions:
          set:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: int(parameters.level*100)
          up: true  # uses Controller base default implementation
          down: true  # uses Controller base default implementation
  rgb_dimmer:
    extends: generic_dimmer
    capabilities:
      rgb_color:
        attributes:
          red:
            source: urn:micasaverde-com:serviceId:Color1/CurrentColor
            expr: "int(replace(match(value, `2=\\d+`), `2=`, `` )) ?# null"
          green:
            source: urn:micasaverde-com:serviceId:Color1/CurrentColor
            expr: "int(replace(match(value, `3=\\d+`), `3=`, `` )) ?# null"
          blue:
            source: urn:micasaverde-com:serviceId:Color1/CurrentColor
            expr: "int(replace(match(value, `4=\\d+`), `4=`, `` )) ?# null"
        actions:
          set_rgb:
            action: urn:micasaverde-com:serviceId:Color1/SetColorRGB
            parameters:
              newColorRGBTarget:
                expr: "'R' + str(parameters.red ?? 0) + ',G' + str(parameters.green ?? 0) +
                  ',B' + str(parameters.blue ?? 0)"
          set:
            action: urn:micasaverde-com:serviceId:Color1/SetColorRGB
            parameters:
              newColorRGBTarget:
                expr: t=int(parameters.value ?? 0),r=(t>>16)&255,g=(t>>8)&255,b=t&255,'R'+r+',G'+g+',B'+b
      color_temperature:
        attributes:
          value:
            source: urn:micasaverde-com:serviceId:Color1/CurrentColor
            expr: >
              w=replace(match(value, `0=\d+`), `0=`, `` ) / 255.0,
              d=replace(match(value, `1=\d+`), `1=`, `` ) / 255.0,
              floor( d==0 ? 2000+3500*w : 5500+3500*d ) ?# null
        actions:
          set:
            action: urn:micasaverde-com:serviceId:Color1/SetColor
            parameters:
              newColorTarget:
                expr: >
                  w=max(0,min(255,floor((parameters.value-2000)/3500*255))),
                  d=(parameters.value < 5500) ? 255 : max(0,min(255,floor((parameters.value-5500)/3500*255))),
                  `W`+w+`,D`+d
  lock:
    extends: generic_device
    capabilities:
      lock:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:DoorLock1/Status
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
        actions:
          lock:
            action: urn:micasaverde-com:serviceId:DoorLock1/SetTarget
            parameters:
              newTargetValue: '1'
          unlock:
            action: urn:micasaverde-com:serviceId:DoorLock1/SetTarget
            parameters:
              newTargetValue: '0'
          'set': true  # now uses default Controller base class implementation
      toggle:
        actions:
          toggle: true  # now uses default Controller base class implementation
  binary_sensor:
    extends: generic_device
    capabilities:
      binary_sensor:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:SecuritySensor1/Tripped
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
  security_sensor:
    extends: binary_sensor
    capabilities:
      arming:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:SecuritySensor1/Armed
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
        actions:
          arm:
            action: urn:micasaverde-com:serviceId:SecuritySensor1/SetArmed
            parameters:
              newArmedValue: '1'
          disarm:
            action: urn:micasaverde-com:serviceId:SecuritySensor1/SetArmed
            parameters:
              newArmedValue: '0'
      x_vera_security:
        actions:
          trip:
            action: urn:micasaverde-com:serviceId:HomeAutomationGateway1/SetVariable
            parameters:
              Service: urn:micasaverde-com:serviceId:SecuritySensor1
              Variable: Tripped
              Value: '1'
              DeviceNum:
                deref: entity.attributes.x_vera_device.device_number
          untrip:
            action: urn:micasaverde-com:serviceId:HomeAutomationGateway1/SetVariable
            parameters:
              Service: urn:micasaverde-com:serviceId:SecuritySensor1
              Variable: Tripped
              Value: '0'
              DeviceNum:
                deref: entity.attributes.x_vera_device.device_number
  motion_sensor:
    extends: security_sensor
    capabilities:
      motion_sensor:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:SecuritySensor1/Tripped
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
  door_sensor:
    extends: security_sensor
    capabilities:
      door_sensor:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:SecuritySensor1/Tripped
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
  leak_detector:
    extends: security_sensor
    capabilities:
      leak_detector:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:SecuritySensor1/Tripped
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
  smoke_detector:
    extends: security_sensor
    capabilities:
      smoke_detector:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:SecuritySensor1/Tripped
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
  generic_sensor:
    extends: generic_device
    capabilities:
      value_sensor:
        attributes:
          value:
            source: urn:micasaverde-com:serviceId:GenericSensor1/CurrentLevel
            expr: "value ?# null"
          units:
  humidity_sensor:
    extends: generic_device
    capabilities:
      value_sensor:  # legacy; may be deprecated in future
        attributes:
          value:
            source: urn:micasaverde-com:serviceId:HumiditySensor1/CurrentLevel
            expr: "value ?# null"
          units: "%"
      humidity_sensor:
        attributes:
          value:
            source: urn:micasaverde-com:serviceId:HumiditySensor1/CurrentLevel
            expr: "value ?# null"
          units: "%"
  temperature_sensor:
    extends: generic_device
    capabilities:
      value_sensor:  # legacy; may be deprecated in future
        attributes:
          value:
            source: urn:upnp-org:serviceId:TemperatureSensor1/CurrentTemperature
            expr: "value ?# null"
          units:
            expr: lower(system.attributes.x_vera_sys.temperatureformat)
            handle_null: true
      temperature_sensor:
        attributes:
          value:
            source: urn:upnp-org:serviceId:TemperatureSensor1/CurrentTemperature
            expr: "value ?# null"
          units:
            expr: upper(system.attributes.x_vera_sys.temperatureformat)
            handle_null: true
  light_sensor:
    extends: generic_device
    capabilities:
      value_sensor:
        attributes:
          value:
            source: "urn:micasaverde-com:serviceId:LightSensor1/CurrentLevel"
            expr: "value ?# null"
      light_sensor:
        attributes:
          value:
            source: "urn:micasaverde-com:serviceId:LightSensor1/CurrentLevel"
            expr: "value ?# null"
  uv_sensor:
    extends: generic_device
    capabilities:
      value_sensor:
        attributes:
          value:
            source: "urn:micasaverde-com:serviceId:LightSensor1/CurrentLevel"
            expr: "value ?# null"
      uv_sensor:
        attributes:
          value:
            source: "urn:micasaverde-com:serviceId:LightSensor1/CurrentLevel"
            expr: "value ?# null"
  flow_sensor:
    extends: generic_device
    capabilities:
      value_sensor:
        from_class: generic_sensor
  voltage_sensor:
    extends: generic_device
    capabilities:
      value_sensor:
        attributes:
          value:
            source: "urn:micasaverde-com:serviceId:LightSensor1/CurrentLevel"
            expr: "value ?# null"
      voltage_sensor:
        attributes:
          value:
            source: "urn:micasaverde-com:serviceId:LightSensor1/CurrentLevel"
            expr: "value ?# null"
  sonos_plugin_zone:
    extends: generic_device
    capabilities:
      av_transport:
        attributes:
          state:
            source: urn:upnp-org:serviceId:AVTransport/TransportState
            expr: statemap[upper(value)] ?? value
            context:
              statemap:
                PAUSED_PLAYBACK: Paused
                STOPPED: Stopped
                PLAYING: Playing
                TRANSITIONING: Playing
          current_title:
            source: urn:upnp-org:serviceId:AVTransport/CurrentTitle
          current_track:
            source: urn:upnp-org:serviceId:AVTransport/CurrentTrack
          current_artist:
            source: urn:upnp-org:serviceId:AVTransport/CurrentArtist
          current_album:
            source: urn:upnp-org:serviceId:AVTransport/CurrentAlbum
          album_art:
            source: urn:upnp-org:serviceId:AVTransport/CurrentAlbumArt
        actions:
          play:
            action: urn:upnp-org:serviceId:AVTransport/Play
          pause:
            action: urn:upnp-org:serviceId:AVTransport/Pause
          stop:
            action: urn:upnp-org:serviceId:AVTransport/Stop
      media_navigation:
        actions:
          next_track:
            action: urn:micasaverde-com:serviceId:MediaNavigation1/SkipDown
          previous_track:
            action: urn:micasaverde-com:serviceId:MediaNavigation1/SkipUp
      av_repeat:
        attributes:
          shuffle:
            source: urn:upnp-org:serviceId:AVTransport/CurrentPlayMode
            expr: find(upper(value),'SHUFFLE')>=0
          repeat_mode:
            source: urn:upnp-org:serviceId:AVTransport/CurrentPlayMode
            expr: upper(value)
            map:
              - equals: NORMAL
                value: 'off'
              - equals: SHUFFLE_NOREPEAT
                value: 'off'
              - equals: SHUFFLE
                value: all
              - equals: REPEAT_ALL
                value: all
              - equals: REPEAT_ONE
                value: one
              - value: other
        actions:
          shuffle_on:
            perform: av_repeat.set_shuffle
            parameters:
              state: true
          shuffle_off:
            perform: av_repeat.set_shuffle
            parameters:
              state: false
          set_shuffle:
            action: urn:upnp-org:serviceId:AVTransport/SetPlayMode
            parameters:
              NewPlayMode:
                expr: 'mixedmode[entity.attributes.av_repeat.repeat_mode + '':'' +
                  ( parameters.state ? ''T'' : ''F'' )] ?? ''NORMAL'''
            context:
              mixedmode:
                off:F: NORMAL
                off:T: SHUFFLE_NOREPEAT
                one:F: REPEAT_ONE
                one:T: REPEAT_ONE
                all:F: REPEAT_ALL
                all:T: SHUFFLE
          repeat_all:
            perform: av_repeat.set_repeat
            parameters:
              mode: all
          repeat_one:
            perform: av_repeat.set_repeat
            parameters:
              mode: one
          repeat_off:
            perform: av_repeat.set_repeat
            parameters:
              mode: 'off'
          set_repeat:
            action: urn:upnp-org:serviceId:AVTransport/SetPlayMode
            parameters:
              NewPlayMode:
                expr: 'mixedmode[lower(parameters.mode) + '':'' + ( entity.attributes.av_repeat.shuffle
                  ? ''T'' : ''F'' )] ?? ''NORMAL'''
            context:
              mixedmode:
                off:F: NORMAL
                off:T: SHUFFLE_NOREPEAT
                one:F: REPEAT_ONE
                one:T: REPEAT_ONE
                all:F: REPEAT_ALL
                all:T: SHUFFLE
      volume:
        attributes:
          level:
            source: urn:upnp-org:serviceId:RenderingControl/Volume
            expr: min(1,max(0, (value ?# 0)/100.0))
        actions:
          increase:
            perform: volume.set
            parameters:
              value:
                expr: min( 1, entity.attributes.volume.level + ( parameters.amount
                  ?? 0.05 ) )
          decrease:
            perform: volume.set
            parameters:
              value:
                expr: max( 0, entity.attributes.volume.level - ( parameters.amount
                  ?? 0.05 ) )
          relative:
            perform: volume.set
            parameters:
              value:
                expr: min( 1, max( 0, entity.attributes.volume.level + ( parameters.amount
                  ?? 0 ) ) )
          set:
            action: urn:upnp-org:serviceId:RenderingControl/SetVolume
            parameters:
              DesiredVolume:
                expr: round( parameters.value * 100 )
          set_db:
            action: urn:upnp-org:serviceId:RenderingControl/SetVolumeDB
            parameters:
              DesiredVolume:
                parameter: db
      muting:
        attributes:
          state:
            source: urn:upnp-org:serviceId:RenderingControl/Mute
            expr: int(value) != 0
        actions:
          mute:
            action: urn:upnp-org:serviceId:RenderingControl/SetMute
            arguments:
              DesiredMute: '1'
          unmute:
            action: urn:upnp-org:serviceId:RenderingControl/SetMute
            arguments:
              DesiredMute: '0'
          toggle:
            action: urn:upnp-org:serviceId:RenderingControl/SetMute
            arguments:
              DesiredMute:
                expr: 'entity.attributes.muting.state ? 0 : 1'
          set:
            action: urn:upnp-org:serviceId:RenderingControl/SetMute
            arguments:
              DesiredMute:
                expr: 'parameters.muting ? 1 : 0'
  cover:
    extends: generic_device
    capabilities:
      cover:
        attributes:
          state:
            source: urn:upnp-org:serviceId:Dimming1/LoadLevelStatus
            expr: (value ?# 100) != 0  # true=open (any amount)
        actions:
          open:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget: 100
          close:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget: 0
          set:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: "parameters.state ? 100 : 0"
          stop:
            action: urn:upnp-org:serviceId:WindowCovering1/Stop
      position:
        attributes:
          value:
            source: urn:upnp-org:serviceId:Dimming1/LoadLevelStatus
            expr: round(max(0,min(1, (value ?# 0)/100.0)),2)
        actions:
          set:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: "int((parameters.value ?# 0)*100)"
          relative:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: int( 100 * min( 1, max( 0, entity.attributes.position.value
                  + ( parameters.amount ?# 0 ) ) ) )
          increase:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: int( 100 * min( 1, max( 0, entity.attributes.position.value
                  + abs( parameters.amount ?# 0 ) ) ) )
          decrease:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: int( 100 * min( 1, max( 0, entity.attributes.position.value
                  - abs( parameters.amount ?# 0 ) ) ) )
      toggle:
        attributes: {}
        actions:
          toggle:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: "entity.attributes.position.value != 0 ? 0 : 100"
  cover_iblinds2:
    # Special handling for iBlinds 2.0 support in Vera. These are louvres, where 50% means the slats are flat, so that's
    # considered "open" 100%; 0% means closed with slat near edge fully down, and 100% means closed with near edge fully
    # up. We want 100% range control, but must recognize that both 0 and 100 are closed, and 50 is fully open.
    # The default closed position is 100, per request by tamorgen. In future, we may want an attribute to make that
    # configurable.
    extends: generic_device
    capabilities:
      cover:
        attributes:
          state:
            source: urn:upnp-org:serviceId:Dimming1/LoadLevelStatus
            # Input range >50 is mappped back to 0-50 where 50 is peak and 0/100 are 0 (so 60 == 40, 100 == 0), so
            # both extremes are closed, and anything else is open (any amount).
            expr: >
              d = value ?# 0, d = ( d > 50 ) ? 100 - d : d, d != 0  # true always means open (any amount)
        actions:
          open:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget: 50  # go figure!
          close:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget: 100  # special closed, see above
          set:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: "parameters.state ? 50 : 100"  # special closed, see above
          stop:
            action: urn:upnp-org:serviceId:WindowCovering1/Stop
      position:
        attributes:
          value:
            source: urn:upnp-org:serviceId:Dimming1/LoadLevelStatus
            # We keep the normal mapping of 0-100 = 0.0-1.0
            expr: round(max(0,min(1, (value ?# 0)/100.0)),2)
        actions:
          set:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: "int((parameters.value ?# 0) * 100)"
          relative:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: int( 100 * min( 1, max( 0, entity.attributes.position.value
                  + ( parameters.amount ?# 0 ) ) ) )
          increase:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: int( 100 * min( 1, max( 0, entity.attributes.position.value
                  + abs( parameters.amount ?# 0 ) ) ) )
          decrease:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: int( 100 * min( 1, max( 0, entity.attributes.position.value
                  - abs( parameters.amount ?# 0 ) ) ) )
      toggle:
        attributes: {}
        actions:
          toggle:
            action: urn:upnp-org:serviceId:Dimming1/SetLoadLevelTarget
            parameters:
              newLoadlevelTarget:
                expr: "entity.attributes.cover.state ? 100 : 50"  # special closed, see above
  heatonly_thermostat:
    # Heat unit only with temperature sensor, no blower
    extends:
      - generic_switch
      - temperature_sensor
    capabilities:
      hvac_control:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:HVAC_OperatingState1/ModeState
            expr: "({off:'off',idle:'idle',heating:'heating',cooling:'cooling'})[lower(value)]
              ?? value"
          mode:
            source: urn:upnp-org:serviceId:HVAC_UserOperatingMode1/ModeTarget
            expr: "({off:'off',heaton:'heat',coolon:'cool',autochangeover:'auto'})[lower(value)]
              ?? value"
        actions:
          set_mode:
            action: urn:upnp-org:serviceId:HVAC_UserOperatingMode1/SetModeTarget
            parameters:
              NewModeTarget:
                # Allow null to leak if we can't map mode
                expr: "({off:'Off',heat:'HeatOn',cool:'CoolOn',auto:'AutoChangeOver'})[parameters.mode]
                  ?? parameters.mode"
      hvac_heating_unit:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:HVAC_OperatingState1/ModeState
            expr: lower(value) === 'heating'
          setpoint:
            source: urn:upnp-org:serviceId:TemperatureSetpoint1/CurrentSetpoint
            expr: "value ?# null"
          units:
            expr: lower(system.attributes.x_vera_sys.temperatureformat)
            handle_null: true
        actions:
          set_setpoint:
            action: urn:upnp-org:serviceId:TemperatureSetpoint1/SetCurrentSetpoint
            parameters:
              NewCurrentSetpoint:
                parameter: setpoint
  generic_thermostat:
    extends: temperature_sensor
    capabilities:
      hvac_control:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:HVAC_OperatingState1/ModeState
            expr: "({off:'off',idle:'idle',heating:'heating',cooling:'cooling'})[lower(value)]
              ?? value"
          mode:
            source: urn:upnp-org:serviceId:HVAC_UserOperatingMode1/ModeTarget
            expr: "({off:'off',heaton:'heat',coolon:'cool',autochangeover:'auto'})[lower(value)]
              ?? value"
        actions:
          set_mode:
            action: urn:upnp-org:serviceId:HVAC_UserOperatingMode1/SetModeTarget
            parameters:
              NewModeTarget:
                # Allow null to leak if we can't map mode
                expr: "({off:'Off',heat:'HeatOn',cool:'CoolOn',auto:'AutoChangeOver'})[parameters.mode]
                  ?? parameters.mode"
      hvac_heating_unit:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:HVAC_OperatingState1/ModeState
            expr: lower(value) === 'heating'
          setpoint:
            source: urn:upnp-org:serviceId:TemperatureSetpoint1_Heat/CurrentSetpoint
            expr: "value ?# null"
          units:
            expr: lower(system.attributes.x_vera_sys.temperatureformat)
            handle_null: true
        actions:
          set_setpoint:
            action: urn:upnp-org:serviceId:TemperatureSetpoint1_Heat/SetCurrentSetpoint
            parameters:
              NewCurrentSetpoint:
                parameter: setpoint
      hvac_cooling_unit:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:HVAC_OperatingState1/ModeState
            expr: lower(value) === 'cooling'
          setpoint:
            source: urn:upnp-org:serviceId:TemperatureSetpoint1_Cool/CurrentSetpoint
            expr: "value ?# null"
          units:
            expr: lower(system.attributes.x_vera_sys.temperatureformat)
            handle_null: true
        actions:
          set_setpoint:
            action: urn:upnp-org:serviceId:TemperatureSetpoint1_Cool/SetCurrentSetpoint
            parameters:
              NewCurrentSetpoint:
                parameter: setpoint
      hvac_blower_unit:
        attributes:
          state:
            source: urn:upnp-org:serviceId:HVAC_FanOperatingMode1/FanStatus
            expr: lower(value) === 'on'
          mode:
            source: urn:upnp-org:serviceId:HVAC_FanOperatingMode1/Mode
            expr: "({auto:'auto',periodicon:'periodic',continuouson:'continuous'})[lower(value)]
              ?? value"
          filter_change:
        actions:
          set_mode:
            action: urn:upnp-org:serviceId:HVAC_FanOperatingMode1/SetMode
            parameters:
              NewMode:
                expr: "({auto:'Auto',continous:'ContinousOn',periodic:'PeriodicOn'})[parameters.mode]
                  ?? parameters.mode"
  scene_controller:
    extends: generic_device
    capabilities:
      scene_activation:
        attributes:
          scene_id:
            source: urn:micasaverde-com:serviceId:SceneController1/sl_SceneActivated
            expr: "value ?# null"
          since: false  # do not touch
      zwave_scene_controller:  # deprecated
        attributes:
          central_scene:
            source: urn:micasaverde-com:serviceId:SceneController1/sl_CentralScene
          key_attribute:
            source: urn:micasaverde-com:serviceId:SceneController1/sl_CentralSceneAttr
          scene_activated:
            source: urn:micasaverde-com:serviceId:SceneController1/sl_SceneActivated
          scene_deactivated:
            source: urn:micasaverde-com:serviceId:SceneController1/sl_SceneDeactivated
      x_vera_scene_controller:
        attributes:
          last_scene_id:
            source: urn:micasaverde-com:serviceId:SceneController1/LastSceneID
          last_scene_time:
            source: urn:micasaverde-com:serviceId:SceneController1/LastSceneTime
  siren:
    extends: generic_switch
  scene:
    # does not extend generic_device!
    capabilities:
      script:
        attributes:
          runnable: true
        actions:
          run:
            action: urn:micasaverde-com:serviceId:HomeAutomationGateway1/RunScene
            device: 0
            parameters:
              SceneNum:
                expr: replace( entity.id, 'scene_', '' )
      x_vera_scene:
        attributes:
          active:
            expr: int( entity.attributes.x_vera_scene.active ?? 0 ) != 0
  room:
    capabilities:
      sys_group: {}
  vera_zwave_net:
    capabilities:
      zwave_network:
        attributes:
          state:
            source: urn:micasaverde-com:serviceId:ZWaveNetwork1/NetStatusID
            expr: "'1' === value"
        actions:
          send_data:
            action: urn:micasaverde-com:serviceId:ZWaveNetwork1/SendData
            parameters:
              Node:
                parameter: node
              Data:
                parameter: data
  vera_housemode_entity:
    capabilities:
      x_vera_housemode:
        attributes:
          mode:
        actions:
          set:
            action: urn:micasaverde-com:serviceId:HomeAutomationGateway1/SetHouseMode
            device: 0
            parameters:
              Mode:
                expr: modes[ parameters.mode ] ?? 1
            context:
              modes:
                home: 1
                away: 2
                night: 3
                vacation: 4
  vera_user_entity: {}  # this class requires no implementation; data only, internal
  vera_geotag_entity: {}  # this class requires no implementation; data only, internal
  fibaro_switch_scenecontrol:
    # Fibaro switch/relay device that has scene activation capability via double-tap, etc.
    extends:
      - generic_switch
      - scene_controller
  fibaro_dimmer_scenecontrol:
    # Fibaro dimming device that has scene activation capability via double-tap, etc.
    extends:
      - generic_dimmer
      - scene_controller
  fibaro_cover_scenecontrol:
    # Fibaro cover device that has scene activation capability via double-tap, etc.
    extends:
      - cover
      - scene_controller
  delaylight_plugin_timer:
    extends: generic_device
    capabilities:
      x_vera_plugin_delaylight_timer:
        attributes:
          timing:
            source: urn:toggledbits-com:serviceId:DelayLightTimer/Timing
            expr: (value ?# 0) != 0
        actions:
          trigger:
            action: urn:toggledbits-com:serviceId:DelayLightTimer/Trigger
          reset:
            action: urn:toggledbits-com:serviceId:DelayLightTimer/Reset
          set_enabled:
            action: urn:toggledbits-com:serviceId:DelayLightTimer/Reset
            parameters:
              newEnabledValue:
                expr: 'state ? 1 : 0'
  reactor_plugin:
    extends: generic_device
    capabilities:
      x_vera_plugin_reactor:
        attributes:
          clock_valid:
            source: urn:toggledbits-com:serviceId:Reactor/ClockValid
            expr: bool(value)
          internet_ok:
            source: urn:toggledbits-com:serviceId:Reactor/NetworkStatus
            expr: bool(value)
          house_mode:
            source: urn:toggledbits-com:serviceId:Reactor/HouseMode
            expr: housemodes[value ?# -1] ?? 'unknown'
            context:
              housemodes:
                - ""        # 0 position
                - home      # 1
                - away      # 2
                - night     # 3
                - vacation  # 4
        actions:
          set_house_mode:
            action: urn:toggledbits-com:serviceId:Reactor/SetHouseMode
            parameters:
              NewMode:
                expr: int(parameters.new_mode) ?? (indexOf( [`home`, `away`, `night`,
                  `vacation`], lower(parameters.new_mode) ) + 1)
  housemodes_plugin:
    extends: generic_device
    capabilities:
      x_vera_plugin_housemodes:
        attributes:
          house_mode:
            source: urn:micasaverde-com:serviceId:HouseModes1/HMode
            expr: housemodes[value ?# -1] ?? 'unknown'
            context:
              housemodes:
                - ""        # 0 position
                - home      # 1
                - away      # 2
                - night     # 3
                - vacation  # 4
        actions:
          set_house_mode:
            action: urn:micasaverde-com:serviceId:HouseModes1/SetHMode
            parameters:
              newHModeValue:
                expr: int(parameters.new_mode) ?? (indexOf( [`home`, `away`, `night`,
                  `vacation`], lower(parameters.new_mode) ) + 1)
  harmony_plugin:
    extends: generic_device
    capabilities:
      x_vera_plugin_harmony:
        attributes:
          linkstatus:
            source: urn:rboer-com:serviceId:Harmony1/LinkStatus
          channel:
            source: urn:rboer-com:serviceId:Harmony1/Channel
          current_activity:
            source: urn:rboer-com:serviceId:Harmony1/CurrentActivityID
          activity_status:
            source: urn:rboer-com:serviceId:Harmony1/activityStatus
          last_command:
            source: urn:rboer-com:serviceId:Harmony1/LastCommand
          power_status:
            source: urn:upnp-org:serviceId:SwitchPower1/Status
            expr: "int(value) != 0"
        actions:
          power_off:
            action: urn:rboer-com:serviceId:Harmony1/PowerOff
          start_activity:
            action: urn:rboer-com:serviceId:Harmony1/StartActivity
            parameters:
              newActivityID:
                parameter: id
          change_channel:
            action: urn:rboer-com:serviceId:Harmony1/ChangeChannel
            parameters:
              newChannel:
                parameter: new_channel
          set_sleep_timer:
            action: urn:rboer-com:serviceId:Harmony1/SetSleepTimer
            parameters:
              Interval:
                parameter: interval
          cancel_sleep_timer:
            action: urn:rboer-com:serviceId:Harmony1/CancelSleepTimer
          issue_sequence_cmd:
            action: urn:rboer-com:serviceId:Harmony1/IssueSequenceCommand
            paramters:
              SequenceID:
                parameter: sequence_id
          issue_device_cmd:
            action: urn:rboer-com:serviceId:Harmony1/IssueDeviceCommand
            parameters:
              DeviceID:
                parameter: device
              Command:
                parameter: command
              Duration:
                parameter: duration
          set_hub_polling:
            action: urn:rboer-com:serviceId:Harmony1/SetHubPolling
            parameters:
              newPollFlag:
                parameter: poll_flag
          set_log_level:
            action: urn:rboer-com:serviceId:Harmony1/SetLogLevel
            parameters:
              newLogLevel:
                parameter: level
          set_remote_images:
            action: urn:rboer-com:serviceId:Harmony1/SetRemoteImages
            parameters:
              newImageRemote:
                parameter: type
          update_buttons:
            action: urn:rboer-com:serviceId:Harmony1/UpdateButtons
          force_update_config:
            action: urn:rboer-com:serviceId:Harmony1/ForceUpdateConfig
  harmony_plugin_device:
    extends: generic_device
    capabilities:
      x_vera_plugin_harmony_device:
        attributes:
          last_command:
            source: urn:rboer-com:serviceId:HarmonyDevice1/LastCommand
        actions:
          update_device_buttons:
            action: urn:rboer-com:serviceId:HarmonyDevice1/UpdateDeviceButtons
          send_device_cmd:
            action: urn:rboer-com:serviceId:HarmonyDevice1/SendDeviceCommand
            parameters:
              Command:
                parameter: command
              Duration:
                parameter: duration
  telegram_plugin:
    extends: generic_device
    capabilities:
      x_vera_plugin_telegram:
        actions:
          send:
            action: urn:bochicchio-com:serviceId:VeraTelegram1/Send
            parameters:
              Text:
                parameter: text
              ImageUrl:
                parameter: imageurl
              VideoUrl:
                parameter: videourl
              UrlParams:
                parameter: urlparams
              ChatID:
                parameter: chatid
              Format:
                parameter: format
              DisableNotification:
                parameter: disablenotification
  althue_plugin:
    extends: generic_device
    capabilities:
      x_vera_althue_plugin:
        attributes:
          lastscene:
            source: urn:upnp-org:serviceId:althue1/HueSceneID
          debug:
            source: urn:upnp-org:serviceId:althue1/Debug
            expr: int(value ?? 0) != 0
        actions:
          run_hue_scene:
            action: urn:upnp-org:serviceId:althue1/RunHueScene
            parameters:
              hueSceneID:
                parameter: scene_id
          set_effect:
            action: urn:upnp-org:serviceId:althue1/SetEffect
            parameters:
              childID:
                parameter: child_id
              newEffect:
                parameter: effect
          refresh:
            action: urn:upnp-org:serviceId:althue1/Refresh
          set_debug:
            action: urn:upnp-org:serviceId:althue1/SetDebug
            parameters:
              newDebugMode:
                parameter: state
  althue_plugin_dimmable:
    extends:
      - rgb_dimmer
      - althue_plugin
    capabilities:
      x_vera_althue_plugin_lamp:
        attributes:
          model:
            source: urn:upnp-org:serviceId:althue1/BulbModelID
          lamp_hex_value:
  althue_plugin_dimmable_rgb:
    extends:
      - rgb_dimmer
      - althue_plugin
    capabilities:
      x_vera_althue_plugin_lamp:
        attributes:
          model:
            source: urn:upnp-org:serviceId:althue1/BulbModelID
          lamp_hex_value:
            source: urn:upnp-org:serviceId:althue1/LampHexValue
  rgbcontroller_plugin:
    extends: generic_switch
    capabilities:
      x_vera_rgbcontroller_plugin:
        attributes:
          device_type:
            source: urn:upnp-org:serviceId:RGBController1/DeviceType
          configured:
            source: urn:upnp-org:serviceId:RGBController1/Configured
            expr: "int(value) != 0"
          color:
            source: urn:upnp-org:serviceId:RGBController1/Color
          message:
            source: urn:upnp-org:serviceId:RGBController1/Message
        actions:
          start_animation:
            action: urn:upnp-org:serviceId:RGBController1/StartAnimationProgram
            parameters:
              programId:
                parameter: program_id
              programName:
                parameter: program_name
              programDuration:
                parameter: duration
              programSpeed:
                parameter: speed
          stop_animation:
            action: urn:upnp-org:serviceId:RGBController1/StopAnimationProgram
            arguments: {}
  plugin_yamaha_rx_http:
    extends: generic_device
    capabilities:
      power_switch:
        attributes:
          state:
        actions:
          'on':
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetPower
            parameters:
              Zone: '1'
              Power: 'On'
          'off':
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetPower
            parameters:
              Zone: '1'
              Power: Standby
      x_vera_plugin_yamaha_rx_http:
        attributes:
          model:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/ModelName
          zones:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/ZoneCount
          connected:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Connected
            expr: "int(value) != 0"
          main_power:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/MainZonePower
            expr: value != 'Standby'
          main_input:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/MainZoneInput
          main_volume:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/MainZoneVolume
            expr: "value ?# null"
          main_mute:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/MainZoneMute
            expr: value != 'Off'
          zone2_power:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone2Power
            expr: value != 'Standby'
          zone2_input:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone2Input
          zone2_volume:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone2Volume
            expr: "value ?# null"
          zone2_mute:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone2Mute
            expr: value != 'Off'
          zone3_power:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone3Power
            expr: value != 'Standby'
          zone3_input:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone3Input
          zone3_volume:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone3Volume
            expr: "value ?# null"
          zone3_mute:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone3Mute
            expr: value != 'Off'
          zone4_power:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone4Power
            expr: value != 'Standby'
          zone4_input:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone4Input
          zone4_volume:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone4Volume
            expr: "value ?# null"
          zone4_mute:
            source: urn:a-lurker-com:serviceId:YamahaRxHTTP1/Zone4Mute
            expr: value != 'Off'
        actions:
          set_power:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetPower
            parameters:
              Zone:
                parameter: zone
              Power:
                expr: 'parameters.state ? ''On'' : ''Standby'''
          set_scene:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetScene
            parameters:
              Zone:
                parameter: zone
              SceneNumber:
                parameter: scene
          set_input:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetInput
            parameters:
              Zone:
                parameter: zone
              Input:
                parameter: input
          set_volume:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetVolume
            parameters:
              Zone:
                parameter: zone
              Volume:
                parameter: level
          set_volume_up_down:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetVolumeUpDown
            parameters:
              Zone:
                parameter: zone
              Step:
                parameter: step
          set_mute:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetMute
            parameters:
              Zone:
                parameter: zone
              Mute:
                expr: 'parameters.mute ? ''On'' : ''Off'''
          play_control:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/PlayControl
            parameters:
              Source:
                parameter: source
              Mode:
                parameter: mode
          select_preset:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SelectPreset
            parameters:
              Source:
                parameter: source
              Preset:
                parameter: preset
          set_party_mode:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SetPartyMode
            parameters:
              LetsParty:
                expr: 'parameters.enabled ? ''On'' : ''Off'''
          send_remote_code:
            action: urn:a-lurker-com:serviceId:YamahaRxHTTP1/SendRemoteCode
            parameters:
              RemoteCode:
                parameter: code
  plugin_gc100:
    # the work is done in a child device IrTransmitter1
    extends: generic_device
    capabilities: {}
  ir_transmitter:
    # related to GC100 but not a part of it; GC100 plugin uses this standard device/service */
    extends: generic_device
    capabilities:
      x_vera_ir_transmitter:
        attributes:
          status:
            source: urn:micasaverde-com:serviceId:IrTransmitter1/Status
            expr: 'isnull( value ) ? null : bool( value )'
        actions:
          send_pronto:
            action: urn:micasaverde-com:serviceId:IrTransmitter1/SendProntoCode
            parameters:
              ProntoCode:
                parameter: code
  vera_everspring_eh403:
    # See note in devicemapping below
    extends:
      - generic_switch
      - security_sensor

  vera_system_object:
    capabilities:
      x_vera_sys:
        actions:
          runlua:
            action: urn:micasaverde-com:serviceId:HomeAutomationGateway1/RunLua
            device: 0
            parameters:
              Code:
                parameter: lua
          reload:
            action: urn:micasaverde-com:serviceId:HomeAutomationGateway1/Reload
            device: 0
      sys_system:
        attributes:
          state: false
        actions: {}

devicemapping:
  - match: "*;hidden=1"
    class: false
  - match: "*;device_type=urn:schemas-micasaverde-com:device:BluetoothNetwork:1"
    class: false
  - match: "*;device_type=urn:schemas-micasaverde-com:device:ZigbeeNetwork:1"
    class: false
  - match: "*;name=_Scene Controller"
    class: false
  - match: "*;urn:micasaverde-com:serviceId:ZWaveDevice1/ManufacturerInfo=96,18,1"
    # Strange Everspring EH-403 motion-sensor light that identifies as binary light but forces SecuritySensor1
    # states; it also comes up with Armed missing until set, so this entry works around that inconsistency
    # (which causes missing attribute alerts from rules that attempt to use it). Forcing our native service
    # effectively "stubs" the value to null in that capability's attribute until it arrives.
    class: vera_everspring_eh403
    type: Light
    primary_attribute: power_switch.state
  - match: "*;device_type=urn:schemas-upnp-org:device:DimmableRGBLight:1;device_json=D_DimmableRGBALTHue1.json"
    class: althue_plugin_dimmable_rgb
    type: Light
    primary_attribute: power_switch.state
  - match: "*;device_type=urn:schemas-upnp-org:device:DimmableLight:1;device_json=D_DimmableALTHue1.json"
    class: althue_plugin_dimmable
    type: Light
    primary_attribute: power_switch.state
  - match: "*;device_type=urn:schemas-upnp-org:device:DimmableLight:1;pnp=/^(5101)$/"
    class: fibaro_dimmer_scenecontrol
    type: Light
    primary_attribute: power_switch.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:WindowCovering:1;pnp=/^(3222)$/"
    # Fibaro window covering control with double/triple tap reporting
    class: fibaro_cover_scenecontrol
    type: Cover
    primary_attribute: cover.state
  -
    # iBlinds 2.0 window covering -- louvers where 0(closed /)->50(open --)->100(closed \); see cover_iblinds2 class
    match: "*;urn:micasaverde-com:serviceId:ZWaveDevice1/ManufacturerInfo=647,3,13"
    class: cover_iblinds2
    type: Cover
    primary_attribute: cover.state
  -
    match: "*;device_type=urn:schemas-upnp-org:device:BinaryLight:1"
    class: generic_switch
    type: Switch
    primary_attribute: power_switch.state
  - match: "*;device_type=/^urn:schemas-upnp-org:device:DimmableRGBLight:/"
    class: rgb_dimmer
    type: Light
    primary_attribute: power_switch.state
  - match: "*;device_type=/urn:schemas-upnp-org:device:DimmableLight:/"
    class: generic_dimmer
    type: Light
    primary_attribute: power_switch.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:ZWaveNetwork:1"
    class: vera_zwave_net
    type: Entity
    primary_attribute: zwave_network.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:Sonos:1"
    class: sonos_plugin_zone
    type: MediaPlayer
    primary_attribute: av_transport.state
  - match: "*;device_type=urn:schemas-toggledbits-com:device:DelayLightTimer:1"
    class: delaylight_plugin_timer
    type: Entity
    primary_attribute: x_vera_plugin_delaylight_timer.timing
  - match: "*;device_type=urn:schemas-toggledbits-com:device:Reactor:1"
    class: reactor_plugin
    type: Entity
  - match: "*;device_type=urn:schemas-micasaverde-com:device:HouseModes:1"
    class: housemodes_plugin
    type: Entity
    primary_state: x_vera_plugin_housemodes.house_mode
  - match: "*;device_type=urn:schemas-upnp-org:service:VSwitch:1"
    class: generic_switch
    type: Switch
    primary_attribute: power_switch.state
  - match: "*;device_type=/^urn:schemas-rboer-com:device:HarmonyDevice/"
    class: harmony_plugin_device
    type: Entity
  - match: "*;device_type=/^urn:schemas-rboer-com:device:Harmony/"
    # N.B.: HarmonyDevice mapping MUST precede this mapping
    class: harmony_plugin
    type: Entity
  - match: "*;device_type=urn:bochicchio-com:device:VeraTelegram:1"
    class: telegram_plugin
    type: Entity
  - match: "*;device_type=urn:schemas-upnp-org:device:althue:1"
    class: althue_plugin
    type: Entity
  - match: "*;device_type=urn:schemas-upnp-org:device:RGBController:1"
    plugin_dev: vosmont
    plugin_id: 6686
    plugin_url: https://github.com/vosmont/Vera-Plugin-RGBController
    class: rgbcontroller_plugin
    type: Switch
    primary_attribute: power_switch.state
  - description: Yamaha-RX-HTTP Plugin
    plugin_info:
      vera_id:
      author: a-lurker
      github: "https://github.com/a-lurker/Vera-Plugin-Yamaha-RX-HTTP/blob/master/Luup_device/D_YamahaRxHTTP1.xml"
    match: "*;device_type=urn:schemas-a-lurker-com:device:YamahaRxHTTP:1"
    class: plugin_yamaha_rx_http
    type: Entity
  - match: "*;impl_file=I_GC100.xml"
    class: plugin_gc100
    type: Entity
    plugin_info:
      vera_id: 4
      author: mcvflorin
  - match: "*;device_type=urn:schemas-micasaverde-com:device:IrTransmitter:1"
    class: ir_transmitter
    type: Entity
  - match: "*;device_type=urn:schemas-micasaverde-com:device:Siren:1"
    class: siren
    type: Entity
  - match: "*;device_type=urn:schemas-micasaverde-com:device:DoorSensor:1"
    class: door_sensor
    type: SecuritySensor
    primary_attribute: door_sensor.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:MotionSensor:1"
    class: motion_sensor
    type: SecuritySensor
    primary_attribute: motion_sensor.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:FloodSensor:1"
    class: leak_detector
    type: SecuritySensor
    primary_attribute: binary_sensor.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:FreezeSensor:1"
    class: security_sensor
    type: SecuritySensor
    primary_attribute: binary_sensor.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:SmokeSensor:1"
    class: smoke_detector
    type: SecuritySensor
    primary_attribute: smoke_detector.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:WindowCovering:1"
    class: cover
    type: Cover
    primary_attribute: cover.state
  - match: "*;device_type=urn:schemas-micasaverde-com:device:TemperatureSensor:1"
    class: temperature_sensor
    type: ValueSensor
    primary_attribute: temperature_sensor.value
  - match: "*;device_json=D_UVSensor1.json"
    # Horrible, but the whole thing is going away anyway, so...
    class: uv_sensor
    type: ValueSensor
    primary_attribute: uv_sensor.value
  - match: "*;device_type=urn:schemas-micasaverde-com:device:GenericSensor:1"
    class: generic_sensor
    type: ValueSensor
    primary_attribute: value_sensor.value
  - match: "*;device_type=urn:schemas-micasaverde-com:device:HumiditySensor:1"
    class: humidity_sensor
    type: ValueSensor
    primary_attribute: humidity_sensor.value
  - match: "*;device_type=urn:schemas-micasaverde-com:device:LightSensor:1"
    class: light_sensor
    type: ValueSensor
    primary_attribute: light_sensor.value
  - match: "*;device_type=urn:schemas-micasaverde-com:device:DoorLock:1"
    class: lock
    type: Lock
    primary_attribute: lock.state
  - match: "*;device_type=urn:schemas-upnp-org:device:Heater:1"
    # Generic heating unit
    class: heatonly_thermostat
    type: Thermostat
    primary_attribute: hvac_control.state
  - match: "*;device_type=urn:schemas-upnp-org:device:HVAC_ZoneThermostat:1"
    # Generic zone thermostat
    class: generic_thermostat
    type: Thermostat
    primary_attribute: hvac_control.state
  - match: "*;device_type=/^urn:schemas-micasaverde-com:device:SceneController/"
    class: scene_controller
    type: Entity
  - match: "*;category_num=3"
    class: generic_switch
    type: Switch
    primary_attribute: power_switch.state
  - match: "*;category_num=2;subcategory_num=4"
    class: rgb_dimmer
    type: Light
    primary_attribute: power_switch.state
  - match: "*;category_num=2"
    class: generic_dimmer
    type: Light
    primary_attribute: power_switch.state
  - match: "*;category_num=4;subcategory_num=8"
    class: binary_sensor
    type: BinarySensor
    primary_attribute: binary_sensor.state
  - match: "*;category_num=4"
    class: security_sensor
    type: SecuritySensor
    primary_attribute: binary_sensor.state
  - match: "*;category_num=7"
    class: lock
    type: Lock
    primary_attribute: lock.state
  - match: "*;category_num=8"
    class: cover
    type: Cover
    primary_attribute: cover.state
  - match: "*;category_num=12"
    class: generic_sensor
    type: ValueSensor
    primary_attribute: value_sensor.value
  - match: "*;category_num=16"
    class: humidity_sensor
    type: ValueSensor
    primary_attribute: humidity_sensor.value
  - match: "*;category_num=17"
    class: temperature_sensor
    type: ValueSensor
    primary_attribute: temperature_sensor.value
  - match: "*;category_num=18"
    class: light_sensor
    type: ValueSensor
    primary_attribute: light_sensor.value
  - match: "*;category_num=28"
    class: uv_sensor
    type: ValueSensor
    primary_attribute: uv_sensor.value
  - match: "*;category_num=33"
    class: flow_sensor
    type: ValueSensor
    primary_attribute: value_sensor.value
  - match: "*;category_num=44"
    class: voltage_sensor
    type: ValueSensor
    primary_attribute: value_sensor.value

    # ****** THESE MUST BE LAST; INSERT NEW ENTRIES ABOVE THIS ******

  - match: system
    class: vera_system_object
  - match: "*"
    # default mapping for any device that doesn't otherwise match
    class: generic_device
    type: Entity

extensions:
  - state: urn:micasaverde-com:serviceId:HaDevice1/BatteryLevel
    extend:
      battery_power:
        attributes:
          level:
            source: urn:micasaverde-com:serviceId:HaDevice1/BatteryLevel
            expr: (value ?# 0) / 100
          since:
            source: urn:micasaverde-com:serviceId:HaDevice1/BatteryDate
            expr: int(value ?# 0) * 1000
  - state: urn:micasaverde-com:serviceId:EnergyMetering1/Watts
    extend:
      power_sensor:
        attributes:
          value:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/Watts
            expr: "value ?# null"
          units: "W"
      energy_sensor:
        attributes:
          value:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/KWH
            expr: "value ?# null"
          units: "KWh"
      voltage_sensor:
        attributes:
          value:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/Volts
            expr: "value ?# null"
          units: "V"
      current_sensor:
        attributes:
          value:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/Amps
            expr: "value ?# null"
          units: "A"
      x_vera_energy:
        attributes:
          watts:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/Watts
          amps:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/Amps
          volts:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/Volts
          power_factor:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/PowerFactor
          kwh:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/KWH
          day_kwh:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/DayKWH
          week_kwh:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/WeekKWH
          month_kwh:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/MonthKWH
          year_kwh:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/YearKWH
          life_kwh:
            source: urn:micasaverde-com:serviceId:EnergyMetering1/LifeKWH
        actions:
          resetkwh:
            action: urn:micasaverde-com:serviceId:EnergyMetering1/ResetKWH
  - expr: source.id_parent == 1
    extend:
      zwave_device:
        attributes:
          failed:
            source: urn:micasaverde-com:serviceId:HaDevice1/CommFailure
            expr: 'isnull( value ) ? null : ( int(value) != 0 )'
          node_id:
            _comment: This is not sent on updates, so keep value if not found
            expr: >
              isnull( source.altid ) ? entity.attributes.zwave_device.node_id : int(source.altid)
            handle_null: true
          capabilities:
            source: urn:micasaverde-com:serviceId:ZWaveDevice1/Capabilities
          manufacturer_info:
            source: urn:micasaverde-com:serviceId:ZWaveDevice1/ManufacturerInfo
          version_info:
            source: urn:micasaverde-com:serviceId:ZWaveDevice1/VersionInfo
        actions:
          poll:  # 2021-09-16 deprecated; see system_capabilities
            action: "urn:micasaverde-com:serviceId:HaDevice1/Poll"
          refresh:
            action: "urn:micasaverde-com:serviceId:HaDevice1/Poll"
          reconfigure:
            action: "urn:micasaverde-com:serviceId:HaDevice1/Reconfigure"
          reset_meters:
            action: "urn:micasaverde-com:serviceId:ZWaveNetwork1/SendData"
            device: 0
            parameters:
              Node:
                expr: "entity.attributes.zwave_device.node_id"
              Data: "x32 5"
          set_config:
            action: "urn:micasaverde-com:serviceId:ZWaveNetwork1/SendData"
            device: 0
            parameters:
              Node:
                expr: "entity.attributes.zwave_device.node_id"
              Data:  # 0x70 4 param size value
                expr: >
                  'x70 4 ' + str( parameters.parameter ) + ' ' +
                  str( parameters.size ) + ' ' +
                  str( parameters.value & 255 ) + ' ' +
                  ( parameters.size > 1 ? str((parameters.value>>8)&255) : '') + ' ' +
                  ( parameters.size > 2 ? str((parameters.value>>16)&255) : '' ) + ' ' +
                  ( parameters.size > 2 ? str((parameters.value>>24)&255) : '' )
          update_neighbors:
            action: "urn:micasaverde-com:serviceId:ZWaveNetwork1/UpdateNeighbors"
            device: 0
            parameters:
              Device:
                deref: entity.attributes.x_vera_device.device_number

filter_states:
  "urn:toggledbits-com:serviceId:ReactorSensor/cdata": true
  "urn:toggledbits-com:serviceId:ReactorSensor/cstate": true
  "urn:toggledbits-com:serviceId:SiteSensor1/LogCapture": true
  "urn:upnp-org:serviceId:AVTransport/AVTransportURIMetaData": true
  "urn:upnp-org:serviceId:AVTransport1/AVTransportURIMetaData": true
  "urn:upnp-org:serviceId:ContentDirectory/Queue": true
  "urn:upnp-org:serviceId:ContentDirectory1/Queue": true
  "urn:upnp-org:serviceId:ZoneGroupTopology": true
  "urn:upnp-org:serviceId:ZoneGroupTopology1": true
  "urn:micasaverde-com:serviceId:ZWaveDevice1/Neighbors": true
