Hi there - thought I might post up some quick lessons learned with my Daikin integration, if it helps same anyone time in future with similar requirements/issues. I have recently moved on to OH3, and decided to take the plunge and move all my config from text files to the UI based config, and moved from sitemaps to OH3 UI. As part of this journey, also got around to extending the items I am controlling on the unit, beyond the basic on/off & temp…
At the same time, I decided to upgrade the Daikin wireless control firmware to the latest version, after all, what could go wrong? (Yes - I do normally know better than that!!)
First things first, my setup is as follows:
- 1 * BRP072A42 wifi adaptor in a ‘Standalone’ split-system
- 3 * BRP072A42 wifi adaptors in a ‘Multi-Zone’ split-system (3 internal units, one external)
- OpenHAB 3.1.0 (Stable)
- Daikin Binding (3.1.0)
- BRP072A42 Firmware version 3.4.3
Note that the 3 way split system has some limitations, which don’t matter whether you are using the remotes, or the OpenHAB binding - They can all be in either Heat or Cool mode, but not different (but a unit can be in “Fan-only” mode whilst others are in heat or cool). The system will pickup the mode from the ‘Master’ indoor unit (Set on the outdoor unit) if there are differences. In my to-do list, I will setup something with groups and/or rules to control this, but for now, just need to use OpenHAB like I would a remote.
So, firstly - The integration issues that arose after moving the config into OpenHAB UI, and upgrading the firmware;
- After a lot of reading, I had convinced myself that this was related to tokens being required after the firmware upgrade, and went down that rabbit hole for a long time
- When using the browser to test, I would get an error message from the adapter such as: Access to dkac-lvng.local was denied You don’t have authorization to view this page
- After lots of wasted time, found (via a browser) that whilst the new firmware would not allow me to browse to the hostname or FQDN (http://dkac-lvng.local/common/basic_info), the IP Address worked fine (http://192.168.xx.xx/common/basic_info)
- Once I changed the hostname to an IP address in the OpenHAB binding, it also worked just fine
- It IS a firmware issue within the adapter, NOT a name resolution or OpenHAB Daikin binding issue !!
Moving on from there, I decided to leverage the great work done by @maxmaximax with the Daikin UI widget (see: Daikin Aircon / HVAC ) I had to make a few modifications as follows:
- Fan speed & swing are not supported by the wifi adapter/heatpump combo’s I have (Nothing to do with OpenHAB binding). I have added some properties to be able to hide these unusable items.
- Some Operation modes are not supported. I took a shortcut here, and didn’t use properties to control their display - Just removed the other modes leaving the main modes used (heat, cool, fan. dehum)
Modified widget code follows:
uid: Daikin HVAC
tags: []
props:
parameters:
- description: Location (room) or device name
label: Title
name: title
required: false
type: TEXT
- context: item
description: Item for power channel
label: Power
name: itemPower
required: false
type: TEXT
- context: item
description: Item for indoor temperature channel
label: Indoor temperature
name: itemIndoorTemp
required: false
type: TEXT
- context: item
description: Item for outdoor temperature channel
label: Outdoor temperature
name: itemOutdoorTemp
required: false
type: TEXT
- context: item
description: Item for target temperature channel
label: Target temperature
name: itemTargetTemp
required: false
type: TEXT
- description: Set minimum target temperature (default = 0)
label: Minimum Temperature
name: MinimumTemperature
required: false
type: INTEGER
- description: Set maximum target temperature (default = 100)
label: Maximum Temperature
name: MaximumTemperature
required: false
type: INTEGER
- description: Set Target Temperature Stepsize (default = 1)
label: Target Temperature Stepsize
name: TemperatureStepsize
required: false
type: DECIMAL
- context: item
description: Item for operation mode channel
label: Operation mode
name: itemMode
required: false
type: TEXT
- description: Hide fan & swing buttons
label: Hide Fan & Swing Function
name: hideFanSwingFunction
required: false
type: BOOLEAN
- context: item
description: Item for fan speed channel
label: Fan speed
name: itemFanSpeed
required: false
type: TEXT
- context: item
description: Item for swing channel
label: Swing mode
name: itemSwing
required: false
type: TEXT
- description: Hide timer button and options
label: Hide Timer Function
name: hideTimerFunction
required: false
type: BOOLEAN
- context: item
description: Switch item for timer
label: Switch Timer ON/OFF
name: itemTimerSwitch
required: false
type: TEXT
advanced: true
- context: item
description: Item for timer duration
label: Timer Duration
name: itemTimerDuration
required: false
type: TEXT
advanced: true
- description: Timer minimum duration
label: Timer minimum
name: TimerMinimum
required: false
type: DECIMAL
advanced: true
- description: Timer maximum duration
label: Timer maximum
name: TimerMaximum
required: false
type: DECIMAL
advanced: true
- description: Timer step
label: Timer step
name: TimerStep
required: false
type: DECIMAL
advanced: true
- description: Timer scale steps
label: Timer scale steps
name: TimerScaleSteps
required: false
type: DECIMAL
advanced: true
- description: Timer scale sub steps
label: Timer scale sub steps
name: TimerScaleSubSteps
required: false
type: DECIMAL
advanced: true
- description: Hide solarplant power
label: Hide Solarplant AC power measurement
name: hideSolarplant
required: false
type: BOOLEAN
- context: item
description: AC Power item for solarplant
label: Solarplant AC Power
name: itemSolarplantACPower
required: false
type: TEXT
advanced: true
parameterGroups: []
timestamp: Oct 27, 2021, 9:49:29 PM
component: f7-card
config:
title: =props.title
outline: true
class:
- no-padding
slots:
default:
- component: f7-row
config:
class:
- margin-top-half
- margin-left-half
- margin-right-half
- margin-bottom
slots:
default:
- component: f7-col
config:
width: "50"
large: "33"
slots:
default:
- component: f7-segmented
config:
class:
- segmented-strong
style:
--f7-segmented-strong-padding: 0px
--f7-segmented-strong-between-buttons: 5px
--f7-segmented-strong-button-font-weight: 300
--f7-segmented-strong-bg-color: transparent
--f7-segmented-strong-button-hover-bg-color: rgba(var(--f7-theme-color-rgb), 0.07)
--f7-button-fill-hover-bg-color: var(--f7-theme-color)
--f7-button-border-radius: 4px
--f7-button-padding-vertical: 0px
--f7-button-padding-horizontal: 0px
slots:
default:
- component: oh-button
config:
outline: true
class:
- padding-top-half
- display-flex
- flex-direction-column
text: ON/OFF
action: toggle
actionItem: =props.itemPower
actionCommand: ON
actionCommandAlt: OFF
icon-f7: power
iconSize: 15
fill: "=(items[props.itemPower].state === 'ON') ? true : false"
style:
--f7-button-border-width: 1px
--f7-button-border-color: var(--f7-card-outline-border-color)
height: auto
font-size: 8px
- component: oh-button
config:
visible: =!props.hideTimerFunction
text: TIMER
action: toggle
actionItem: =props.itemTimerSwitch
actionCommand: ON
actionCommandAlt: OFF
iconF7: timer
iconSize: 15px
fill: "=(items.ac_timer_on_off.state === 'ON') ? true : false"
outline: false
class:
- display-flex
- flex-direction-column
- padding-top-half
style:
--f7-button-border-width: 1px
--f7-button-border-color: var(--f7-card-outline-border-color)
font-size: 8px
height: auto
- component: f7-col
config:
width: "33"
slots:
default:
- component: f7-row
config:
class:
- padding-right-half
slots:
default:
- component: f7-col
config:
width: "25"
slots:
default:
- component: f7-icon
config:
class:
- float-right
f7: house
size: 15
color: var(--f7-theme-color)
- component: f7-col
config:
width: "75"
slots:
default:
- component: Label
config:
class:
- float-right
text: =items[props.itemIndoorTemp].displayState
style:
white-space: nowrap
overflow: hidden
text-overflow: elipsis
font-size: 12px
- component: f7-row
config:
class:
- padding-right-half
slots:
default:
- component: f7-col
config:
width: "25"
slots:
default:
- component: f7-icon
config:
class:
- float-right
f7: tree
size: 15
color: var(--f7-theme-color)
- component: f7-col
config:
width: "75"
slots:
default:
- component: Label
config:
class:
- float-right
text: =items[props.itemOutdoorTemp].displayState
style:
white-space: nowrap
overflow: hidden
text-overflow: elipsis
font-size: 12px
- component: f7-row
config:
visible: =!props.hideSolarplant
class:
- padding-right-half
slots:
default:
- component: f7-col
config:
width: "25"
slots:
default:
- component: f7-icon
config:
class:
- float-right
f7: sun_max
size: 15
color: var(--f7-theme-color)
- component: f7-col
config:
width: "75"
slots:
default:
- component: Label
config:
class:
- float-right
text: =items[props.itemSolarplantACPower].state
style:
white-space: nowrap
overflow: hidden
text-overflow: elipsis
font-size: 12px
- component: f7-row
config:
class:
- justify-content-center
slots:
default:
- component: oh-knob
config:
item: =props.itemTargetTemp
min: =props.MinimumTemperature
max: =props.MaximumTemperature
stepSize: =props.TemperatureStepsize
secondaryColor: var(--f7-card-outline-border-color)
primaryColor: var(--f7-theme-color)
responsive: false
strokeWidth: "12"
size: 150
- component: f7-segmented
config:
visible: true
class:
- margin-left-half
- margin-right-half
- margin-top
- margin-bottom-half
style:
--f7-button-font-size: 8px
--f7-button-text-color: "=themeOptions.dark === 'light' ? 'black' : 'white'"
--f7-button-border-radius: 4px
--f7-button-outline-border-width: 1px
--f7-button-font-weight: 300
--f7-button-padding-vertical: 0px
--f7-button-padding-horizontal: 0px
slots:
default:
- component: oh-repeater
config:
sourceType: array
for: modeRow
in:
- icon: arrow_2_squarepath
command: AUTO
text: AUTOMATIC
- icon: thermometer_snowflake
command: COLD
text: Cool
- icon: thermometer_sun
command: HEAT
text: Heat
- icon: drop_fill
command: DEHUMIDIFIER
text: Dry
- icon: wind
command: FAN
text: Fan Only
fragment: true
slots:
default:
- component: oh-button
config:
iconF7: =loop.modeRow.icon
iconSize: 15px
fill: "=(items[props.itemMode].state === loop.modeRow.command) ? true : false"
outline: true
class:
- display-flex
- flex-direction-column
- padding-top-half
style:
--f7-button-border-color: var(--f7-card-outline-border-color)
height: auto
text: =loop.modeRow.text
action: command
actionItem: =props.itemMode
actionCommand: =loop.modeRow.command
- component: oh-button
config:
visible: =!props.hideFanSwingFunction
iconF7: ellipsis_vertical
iconSize: 15px
action: variable
actionVariable: options
actionVariableValue: "=vars.options || vars.options === undefined ? false : true"
fill: "=vars.options || vars.options === undefined ? false : true"
outline: true
class:
- display-flex
- flex-direction-column
style:
--f7-button-border-color: var(--f7-card-outline-border-color)
height: auto
width: 50%
- component: f7-segmented
config:
visible: =vars.options === false
class:
- margin-left-half
- margin-right-half
- margin-top
- margin-bottom-half
style:
--f7-button-font-size: 8px
--f7-button-text-color: "=themeOptions.dark === 'light' ? 'black' : 'white'"
--f7-button-border-radius: 4px
--f7-button-outline-border-width: 1px
--f7-button-font-weight: 300
--f7-button-padding-vertical: 0px
--f7-button-padding-horizontal: 0px
slots:
default:
- component: oh-repeater
config:
sourceType: array
for: optionsRow
in:
- icon: wind ellipsis_vertical
option: fanspeed
- icon: move ellipsis_vertical
option: swing
fragment: true
slots:
default:
- component: oh-button
config:
iconF7: =loop.optionsRow.icon
iconSize: 15px
fill: "=vars[loop.optionsRow.option] || vars[loop.optionsRow.option] === undefined ? false : true"
outline: true
class:
- display-flex
- flex-direction-column
style:
--f7-button-border-color: var(--f7-card-outline-border-color)
height: auto
action: variable
actionVariable: =loop.optionsRow.option
actionVariableValue: "=vars[loop.optionsRow.option] || vars[loop.optionsRow.option] === undefined ? false : true"
- component: oh-button
config:
visible: =!props.hideTimerFunction
action: variable
actionVariable: timer_menu
actionVariableValue: "=vars.timer_menu || vars.timer_menu === undefined ? false : true"
fill: "=vars.timer_menu || vars.timer_menu === undefined ? false : true"
iconF7: timer ellipsis_vertical
iconSize: 15px
outline: true
style:
--f7-button-border-color: var(--f7-card-outline-border-color)
- component: f7-segmented
config:
visible: "=vars.fanspeed === false && vars.options === false ? true : false"
class:
- margin-left-half
- margin-right-half
- margin-top
- margin-bottom-half
style:
--f7-button-text-color: "=themeOptions.dark === 'light' ? 'black' : 'white'"
--f7-button-border-radius: 4px
--f7-button-outline-border-width: 1px
--f7-button-font-weight: 300
--f7-button-padding-vertical: 0px
--f7-button-padding-horizontal: 0px
slots:
default:
- component: oh-repeater
config:
sourceType: array
for: fanspeedRow
in:
- icon: arrow_2_squarepath
command: AUTO
- command: LEVEL_1
text: 1
- command: LEVEL_2
text: 2
- command: LEVEL_3
text: 3
- command: LEVEL_4
text: 4
- command: LEVEL_5
text: 5
fragment: true
slots:
default:
- component: oh-button
config:
iconF7: =loop.fanspeedRow.icon
iconSize: 15px
fill: "=(items[props.itemFanSpeed].state === loop.fanspeedRow.command) ? true : false"
outline: true
class:
- display-flex
- flex-direction-column
style:
--f7-button-border-color: var(--f7-card-outline-border-color)
height: auto
text: =loop.fanspeedRow.text
action: command
actionItem: =props.itemFanSpeed
actionCommand: =loop.fanspeedRow.command
- component: f7-segmented
config:
visible: "=vars.swing === false && vars.options === false ? true : false"
class:
- margin-left-half
- margin-right-half
- margin-top
- margin-bottom-half
style:
--f7-button-text-color: "=themeOptions.dark === 'light' ? 'black' : 'white'"
--f7-button-border-radius: 4px
--f7-button-outline-border-width: 1px
--f7-button-font-weight: 300
--f7-button-padding-vertical: 0px
--f7-button-padding-horizontal: 0px
slots:
default:
- component: oh-repeater
config:
sourceType: array
for: swingRow
in:
- command: STOPPED
text: Off
- icon: resize_v
command: VERTICAL
- icon: resize_h
command: HORIZONTAL
- icon: view_3d
command: VERTICAL_AND_HORIZONTAL
fragment: true
slots:
default:
- component: oh-button
config:
iconF7: =loop.swingRow.icon
iconSize: 15px
fill: "=(items[props.itemSwing].state === loop.swingRow.command) ? true : false"
outline: true
class:
- display-flex
- flex-direction-column
style:
--f7-button-border-color: var(--f7-card-outline-border-color)
height: auto
text: =loop.swingRow.text
action: command
actionItem: =props.itemSwing
actionCommand: =loop.swingRow.command
- component: f7-row
config:
visible: "=vars.timer_menu === false && vars.options === false && !props.hideTimerFunction === true ? true : false"
class:
- margin-left-half
- margin-right-half
- margin-bottom-half
slots:
default:
- component: f7-col
slots:
default:
- component: oh-slider-card
config:
outline: true
item: =props.itemTimerDuration
min: =props.TimerMinimum
max: =props.TimerMaximum
step: =props.TimerStep
scaleSteps: =props.TimerScaleSteps
scaleSubSteps: =props.TimerScaleSubSteps
scale: true
unit: min
label: true
From there, I have jammed all 4 heatpumps into a swiper card, which allow me to easily move between the widgets, while limiting the screen real-estate used.
component: oh-swiper-card
config:
title: Heat Pumps
scrollbar: true
slots:
default:
- component: widget:Daikin HVAC
config:
title: Living Heat Pump
itemPower: LivingHeatPump_Power
itemIndoorTemp: LivingHeatPump_IndoorTemperature
itemOutdoorTemp: LivingHeatPump_OutdoorTemperature
itemTargetTemp: LivingHeatPump_SetPoint
MinimumTemperature: 16
MaximumTemperature: 30
itemMode: LivingHeatPump_Mode
hideFanSwingFunction: true
hideTimerFunction: true
TemperatureStepsize: 1
hideSolarplant: true
- component: widget:Daikin HVAC
config:
title: Lounge Heat Pump
itemPower: LoungeHeatPump_Power
itemIndoorTemp: LoungeHeatPump_IndoorTemperature
itemOutdoorTemp: LoungeHeatPump_OutdoorTemperature
itemTargetTemp: LoungeHeatPump_SetPoint
MinimumTemperature: 16
MaximumTemperature: 30
TemperatureStepsize: 1
itemMode: LoungeHeatPump_Mode
hideFanSwingFunction: true
hideTimerFunction: true
hideSolarplant: true
- component: widget:Daikin HVAC
config:
title: Rumpus Heat Pump
itemPower: RumpusHeatPump_Power
itemIndoorTemp: RumpusHeatPump_IndoorTemperature
itemOutdoorTemp: RumpusHeatPump_OutdoorTemperature
itemTargetTemp: RumpusHeatPump_SetPoint
MinimumTemperature: 16
TemperatureStepsize: 1
hideFanSwingFunction: true
hideTimerFunction: true
hideSolarplant: true
itemMode: RumpusHeatPump_Mode
MaximumTemperature: 30
- component: widget:Daikin HVAC
config:
title: Bedroom 1 Heat Pump
itemPower: Bedroom1HeatPump_Power
itemIndoorTemp: Bedroom1HeatPump_IndoorTemperature
itemOutdoorTemp: Bedroom1HeatPump_OutdoorTemperature
itemTargetTemp: Bedroom1HeatPump_SetPoint
MinimumTemperature: 16
MaximumTemperature: 30
TemperatureStepsize: 1
itemMode: Bedroom1HeatPump_Mode
hideFanSwingFunction: true
hideTimerFunction: true
hideSolarplant: true
Only issue with using the swiper card, is occasionally on the mobile, you can grab the temp ‘circle’ and unintentionally set the room temp to 'Bake" instead of moving between widgets. Pretty rare, and very happy with the result overall.
Pretty much the same as the orignal posted by @maxmaximax, with the surplus items removed,
and incorporated into the swiper card. Note the outdoor temperature is not showing when the unit is off - A limitation of the heatpump, not the OpenHAB binding. I could modify the widget to hide this item when the unit is off, but bigger things to move onto now !!
Hope this is of use to someone, and thanks to those in the community who originally shared their work, and gave the inspiration/starting point to help get me to this result. As well as the UI widget, this also includes the Daikin Binding author/maintainers - This binding has been rock-solid in my installation since OH2.x (Other than my self-induced ‘external’ issue described above!!). Cheers