OpenHab - Ambient Lights widget
Please read Liability Disclaimer and License Agreement CAREFULLY
For the Ambient lights device (check links below) I have created a OpenHab Widget to be able to control the device with ease.
Ambient light with APA102 and MQTT
Ambient Light Sensor Controller Software
Ambient Light Sensor Controller Software
The MQTT topics are listed below, they are
ambient/CL - Left lamp Color in HSB format
ambient/CR - Right lamp Color in HSB format
ambient/LG - Set gain for color sensor from 1 to 60
ambient/LB - Brightness 0 to 31 as per APA102 datasheet
ambient/LM - 0 = user color, 1 = color from sensor
ambient/LE - 0 = none, 1 = rainbow 2...
ambient/LP - LED strip power
ambient/SV - Sensor reading for Volts
ambient/SI - Sensor reading for Current
ambient/SW - Sensor reading for Power
ambient/SE - Sensor reading for Energy
They are linked to an OpenHab thing defined as per below
UID: mqtt:topic:MyMQTT:AmbientLight
label: Ambient Light
thingTypeUID: mqtt:topic
configuration: {}
bridgeUID: mqtt:broker:MyMQTT
channels:
- id: LeftColor
channelTypeUID: mqtt:colorHSB
label: Left Color
description: ""
configuration:
commandTopic: ambient/CL
stateTopic: ambient/CL
colorMode: HSB
- id: RightColor
channelTypeUID: mqtt:colorHSB
label: Right Color
description: ""
configuration:
commandTopic: ambient/CR
stateTopic: ambient/CR
- id: SensorGain
channelTypeUID: mqtt:number
label: Sensor Gain
description: ""
configuration:
commandTopic: ambient/LG
min: 1
stateTopic: ambient/LG
max: 60
- id: AmbientBrightness
channelTypeUID: mqtt:number
label: Ambient Brightness
description: ""
configuration:
commandTopic: ambient/LB
min: 0
stateTopic: ambient/LB
max: 31
- id: AmbientMode
channelTypeUID: mqtt:switch
label: Ambient Mode
description: ""
configuration:
commandTopic: ambient/LM
stateTopic: ambient/LM
off: "0"
on: "1"
- id: AmbientEffect
channelTypeUID: mqtt:number
label: Ambient Effect
description: ""
configuration:
commandTopic: ambient/LE
min: 0
stateTopic: ambient/LE
max: 10
- id: AmbientPower
channelTypeUID: mqtt:switch
label: Ambient Light Power
description: ""
configuration:
commandTopic: ambient/LP
stateTopic: ambient/LP
off: "0"
on: "1"
- id: AmbientVolts
channelTypeUID: mqtt:number
label: Ambient Volts
description: ""
configuration:
stateTopic: ambient/SV
- id: AmbientAmps
channelTypeUID: mqtt:number
label: Ambient Amps
description: ""
configuration:
stateTopic: ambient/SI
- id: AmbientWats
channelTypeUID: mqtt:number
label: Ambient Wats
description: ""
configuration:
stateTopic: ambient/SW
- id: AmbientEnergy
channelTypeUID: mqtt:number
label: Ambient Energy
description: ""
configuration:
stateTopic: ambient/SE
The OpenHab Widget is presented in the images below:
The code for the OpenHab Ambient Ligt Widget is
uid: RGB_Lamp
tags: []
props:
parameters:
- description: Header text
label: Header
name: header
required: false
type: TEXT
- context: item
description: Color
label: Color Item Left
name: colorL
required: true
type: TEXT
- context: item
description: Color
label: Color Item Right
name: colorR
required: true
type: TEXT
- context: item
description: Brightness
label: Brightness
name: brightness
required: true
type: TEXT
- context: item
description: Sensitivity
label: Sensor Sensitivity
name: sensitivity
required: true
type: TEXT
- context: item
description: Color Mode
label: Color Mode
name: colorMode
required: true
type: TEXT
- context: item
description: Light Effect
label: Light Effect
name: lightEffect
required: true
type: TEXT
- context: item
description: Power ON/OFF
label: Power Switch
name: lampPower
required: true
type: TEXT
- context: item
description: Supply Voltage
label: Supply Voltage
name: supplyVoltage
required: true
type: TEXT
- context: item
description: Supply Current
label: Supply Current
name: supplyCurrent
required: true
type: TEXT
- context: item
description: Supply Power
label: Supply Power
name: supplyPower
required: true
type: TEXT
- context: item
description: Supply Energy
label: Supply Energy
name: supplyEnergy
required: true
type: TEXT
parameterGroups: []
timestamp: Nov 20, 2023, 7:00:58 PM
component: f7-card
config: {}
slots:
default:
- component: f7-card-content
config:
class:
- display-flex
- flex-direction-column
- justify-content-flex-start
- align-items-center
style:
--f7-card-margin-horizontal: 5px
--f7-card-margin-vertical: 10px
height: auto
slots:
default:
- component: f7-row
config:
style:
margin-top: 2px
height: auto
position: absolute
slots:
default:
- component: f7-block-header
slots:
default:
- component: Label
config:
text: =props.header
- component: f7-block
config:
class:
- no-padding
style:
height: auto
margin-top: 30px
width: 100%
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
animation: f7-fade-in 300ms
slots:
default:
- component: f7-row
config:
class:
- text-align-center
style:
flex-wrap: nowrap
height: 75px
white-space: nowrap
slots:
default:
- component: f7-icon
config:
f7: bolt
inline: true
size: 24
style:
color: '=(items[props.supplyVoltage].state < 4.5) ? "red" : (items[props.supplyVoltage].state < 4.8 ) ? "yellow" : "green"'
- component: Label
config:
style:
font-size: var(--server-normal-font-size)
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
text: =items[props.supplyVoltage].state + 'V'
- component: oh-trend
config:
style:
height: 100%
max-width: 75%
trendGradient:
- green
- yellow
- red
trendItem: =props.supplyVoltage
- component: f7-row
config:
class:
- text-align-center
style:
flex-wrap: nowrap
height: 75px
white-space: nowrap
slots:
default:
- component: f7-icon
config:
f7: bolt_badge_a
inline: true
size: 24
style:
color: '=(items[props.supplyCurrent].state < 10) ? "green" : (items[props.supplyCurrent].state < 12 ) ? "yellow" : "red"'
- component: Label
config:
style:
font-size: var(--server-normal-font-size)
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
text: =items[props.supplyCurrent].state + 'A'
- component: oh-trend
config:
style:
height: 100%
max-width: 75%
trendGradient:
- green
- yellow
- red
trendItem: =props.supplyCurrent
- component: f7-row
config:
class:
- text-align-center
style:
flex-wrap: nowrap
height: 75px
white-space: nowrap
slots:
default:
- component: f7-icon
config:
f7: bolt_circle
inline: true
size: 24
style:
color: '=(items[props.supplyPower].state < 40) ? "green" : (items[props.supplyPower].state < 50 ) ? "yellow" : "red"'
- component: Label
config:
style:
font-size: var(--server-normal-font-size)
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
text: =items[props.supplyPower].state + 'W'
- component: oh-trend
config:
style:
height: 100%
max-width: 75%
trendGradient:
- green
- yellow
- red
trendItem: =props.supplyPower
- component: f7-row
config:
class:
- justify-content-space-between
style:
flex-wrap: nowrap
height: 75px
white-space: nowrap
slots:
default:
- component: f7-icon
config:
f7: bolt_circle_fill
inline: true
size: 24
style:
color: green
- component: Label
config:
style:
font-size: var(--server-normal-font-size)
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
text: =items[props.supplyEnergy].state + 'Wh'
- component: oh-trend
config:
style:
height: 100%
max-width: 75%
trendGradient:
- green
- yellow
- red
trendItem: =props.supplyEnergy
- component: f7-block
config:
class:
- display-flex
- flex-direction-column
- justify-content-flex-end
style:
animation: f7-fade-in 300ms
height: auto
visible: '=items[props.colorMode].state != "ON" ? false : true'
slots:
default:
- component: f7-row
config:
class:
- display-flex
- justify-content-space-between
- align-items-center
style:
height: auto
margin: 2px
width: calc(100% + 20px)
slots:
default:
- component: f7-icon
config:
f7: waveform_path
size: 30
style:
color: var(--f7-block-header-text-color)
- component: Label
config:
style:
color: var(--f7-block-header-text-color)
text: =items[props.sensitivity].state
- component: f7-row
config:
class:
- display-flex
- justify-content-center
- align-items-center
style:
height: auto
width: 100%
margin: 2px
slots:
default:
- component: oh-slider
config:
color: white
item: =props.sensitivity
label: true
max: =60
min: =1
style:
--f7-range-bar-active-bg-color: rgba(246,246,0,0.5)
--f7-range-bar-bg-color: linear-gradient(to right, rgba(169,169,169,0.8), rgba(246,158,81,0))
--f7-range-bar-border-radius: 8px
--f7-range-bar-size: 16px
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-knob-size: 20px
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
- component: f7-block
config:
class:
- display-flex
- flex-direction-column
- justify-content-flex-end
style:
animation: f7-fade-in 300ms
height: auto
margin: 2px
slots:
default:
- component: f7-row
config:
class:
- display-flex
- justify-content-space-between
- align-items-center
style:
height: auto
margin: 2px
width: calc(100% + 20px)
slots:
default:
- component: f7-icon
config:
f7: sun_min
size: 30
style:
color: var(--f7-block-header-text-color)
- component: Label
config:
style:
color: var(--f7-block-header-text-color)
text: =items[props.brightness].state
- component: f7-row
config:
class:
- display-flex
- justify-content-center
- align-items-center
style:
height: auto
width: 100%
margin: 2px
slots:
default:
- component: oh-slider
config:
color: white
item: =props.brightness
label: true
max: =31
min: =1
style:
--f7-range-bar-active-bg-color: rgba(246,246,0,0.5)
--f7-range-bar-bg-color: linear-gradient(to right, rgba(169,169,169,0.8), rgba(246,158,81,0))
--f7-range-bar-border-radius: 8px
--f7-range-bar-size: 16px
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
--f7-range-knob-size: 20px
--f7-range-label-text-color: black
width: 100%
z-index: 99 !important
- component: f7-block
config:
style:
animation: f7-fade-in 500ms
visible: '=items[props.colorMode].state != "ON" ? true : false'
slots:
default:
- component: f7-segmented
config:
class:
- display-flex
- justify-content-space-between
style:
--f7-segmented-strong-bg-color: transparent
height: 120px
margin: 2px
slots:
default:
- component: oh-colorpicker
config:
item: =props.colorL
modules:
- hsb-sliders
- component: oh-colorpicker
config:
item: =props.colorR
modules:
- hsb-sliders
- component: f7-block
config:
class:
- display-flex
- justify-content-center
- align-items-center
style:
height: 100%
width: 100%
margin: 2px
visible: '=items[props.colorMode].state != "ON" ? true : false'
slots:
default:
- component: oh-button
config:
action: options
actionItem: =props.lightEffect
actionOptions: 0=Fix Color,1=Fluid Rainbow,2=Snow,3=Pulse,4=Flashing,5=Fading,6=Color Wipe,7=Theater Chase,8=Breath,9=Wave
fill: false
iconF7: paintbrush
outline: true
round: true
text: Effect
textColor: white
tooltip: Select light effect
tooltip-trigger: hover
- component: f7-block
config:
class:
- display-flex
- justify-content-space-between
- align-items-center
style:
margin-top: 2px
width: calc(100% - 10px)
position: relative
slots:
default:
- component: f7-block
config:
class:
- display-flex
- justify-content-center
- align-items-center
- no-padding
- no-margin
style:
position: absolute
background: white
border-radius: 50%
border-top: '=items[props.lampPower].state == "ON" ? "none" : "2px solid #ddd"'
box-shadow: "inset 0px 1px 2px #eee"
height: 40px
width: 40px
margin: 2px
left: 0px
bottom: -35px
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
background: '=items[props.lampPower].state == "ON" ? "rgba(124, 252, 0, 0.5)" : "transparent"'
border-radius: 50%
box-shadow: '=items[props.lampPower].state == "ON" ? "0 0 20px #fff, 0px 0px 30px rgba(0,255,0,0.5)" : "none"'
height: 100%
position: absolute
transform: '=items[props.lampPower].state =="ON" ? "scale(1,1)" : "scale(0,0)"'
transition: transform 0.2s
width: 100%
- component: f7-block
config:
style:
background: rgba(255,255,255,0.8)
border-radius: 50%
height: calc(100% - 10px)
position: absolute
width: calc(100% - 10px)
- component: oh-link
config:
action: toggle
actionCommand: '=items[props.lampPower].state == "ON" ? "OFF" : "ON"'
actionItem: =props.lampPower
iconColor: '=items[props.lampPower].state == "ON" ? "green" : "red"'
iconF7: power
iconOnly: true
iconSize: 12
style:
backdrop-filter: opacity(88%)
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
border: solid 2pt white
border-radius: 50%
box-shadow: 0px 3px 8px
color: "#a7a7a7"
height: calc(100% - 10px)
text-align: center
width: calc(100% - 10px)
z-index: 99 !important
- component: f7-block
config:
class:
- display-flex
- justify-content-center
- align-items-center
- no-padding
- no-margin
style:
position: absolute
background: white
border-radius: 50%
border-top: '=items[props.colorMode].state == "OFF" ? "none" : "2px solid #ddd"'
box-shadow: "inset 0px 1px 2px #eee"
height: 40px
width: 40px
margin: 2px
right: 10px
bottom: -35px
slots:
default:
- component: f7-block
config:
class:
- no-margin
style:
background: '=items[props.colorMode].state == "OFF" ? "linear-gradient(135deg, red, orange, yellow, green, blue)" : "transparent"'
border-radius: 50%
box-shadow: '=items[props.colorMode].state == "OFF" ? "0 0 15px #fff, -7px -7px 15px rgba(255,0,0,0.5), 7px -7px 15px rgba(255,255,0,0.5), 7px 7px 15px rgba(0,255,0,0.5), -7px 7px 15px rgba(255,255,0,0.5)" : "none"'
height: 100%
position: absolute
transform: '=items[props.colorMode].state == "OFF" ? "rotate(360deg) scale(1,1)" : "rotate(0deg) scale(0,0)"'
transition: transform 0.2s
width: 100%
- component: f7-block
config:
style:
background: rgba(255,255,255,0.8)
border-radius: 50%
height: calc(100% - 10px)
position: absolute
width: calc(100% - 10px)
- component: oh-link
config:
action: command
actionCommand: OFF
actionItem: =props.colorMode
class:
- nextSlide
iconF7: hand_draw_fill
iconOnly: true
iconSize: 17
style:
backdrop-filter: opacity(88%)
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
border: solid 2pt white
border-radius: 50%
box-shadow: 0px 3px 8px
color: "#a7a7a7"
display: '=items[props.colorMode].state == "ON" ? "block" : "none"'
height: calc(100% - 10px)
text-align: center
width: calc(100% - 10px)
- component: oh-link
config:
action: command
actionCommand: ON
actionItem: =props.colorMode
class:
- previousSlide
iconF7: light_max
iconOnly: true
iconSize: 17
style:
backdrop-filter: opacity(88%)
background-color: "#f7f7f7"
background-image: "linear-gradient(135deg, #f7f7f7, #e7e7e7)"
border: solid 2pt white
border-radius: 50%
box-shadow: 0px 3px 8px
color: "#a7a7a7"
display: '=items[props.colorMode].state == "OFF" ? "block" : "none"'
height: calc(100% - 10px)
text-align: center
width: calc(100% - 10px)
- component: f7-card-footer
slots:
default:
- component: Label
config:
style:
color: '=items[props.lampPower].state == "ON" ? "green" : "red"'
margin-left: 50%
position: absolute
text: = 'Power ' + items[props.lampPower].state + '/' + items[props.colorMode].state
Comments powered by CComment