Skip to content

Commit

Permalink
Update HueLight.js
Browse files Browse the repository at this point in the history
- Add support for Hampton Bay fan modules, see dresden-elektronik/deconz-rest-plugin#932;
- Use `state.lift` and `state.tilt`for window covering devices;
- Don't sound siren on warning devices on _Identify_.
  • Loading branch information
ebaauw committed May 31, 2020
1 parent fb60041 commit d23ba05
Showing 1 changed file with 111 additions and 38 deletions.
149 changes: 111 additions & 38 deletions lib/HueLight.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,15 +432,15 @@ function HueLight (accessory, id, obj, type = 'light') {
this.service.getCharacteristic(Characteristic.TargetPosition)
.on('set', this.setPosition.bind(this))
.setProps({ minStep: 5 })
this.checkPosition(this.obj.state.bri)
this.checkLift(this.obj.state.lift)
this.service.getCharacteristic(Characteristic.HoldPosition)
.on('set', this.setHoldPosition.bind(this))
.setValue(false)
if (this.config.sat) {
if (this.config.tilt) {
this.service.getCharacteristic(Characteristic.TargetHorizontalTiltAngle)
.on('set', this.setTilt.bind(this))
.setProps({ minStep: 5 })
this.checkTilt(this.obj.state.sat)
this.checkTilt(this.obj.state.tilt)
}
} else if (!this.config.on) { // Warning device
this.service = new Service.Outlet(this.name, this.subtype)
Expand Down Expand Up @@ -567,6 +567,12 @@ function HueLight (accessory, id, obj, type = 'light') {
this.service.getCharacteristic(my.Characteristics.Resource)
.updateValue(this.resource)
}
if (this.config.speed) {
this.fanService = new Service.Fan(this.name, this.subtype)
this.fanService.getCharacteristic(Characteristic.RotationSpeed)
.on('set', this.setSpeed.bind(this))
this.checkSpeed(this.obj.state.speed)
}
}

// Store configuration to this.config.
Expand All @@ -581,6 +587,7 @@ HueLight.prototype.setConfig = function () {
bri: this.obj.state.bri !== undefined,
ct: this.obj.state.ct !== undefined,
xy: this.obj.state.xy !== undefined,
speed: this.obj.state.speed !== undefined,
colorloop: this.obj.state.effect !== undefined,
wallSwitch: false,
outlet: this.bridge.outlet[this.type + 's'][this.id],
Expand All @@ -595,9 +602,9 @@ HueLight.prototype.setConfig = function () {
this.config.windowCovering = false
} else if (this.obj.type === 'Window covering device') {
this.config.windowCovering = true
this.config.sat = this.obj.state.sat !== undefined
this.config.ct = false
this.config.xy = false
this.config.lift = this.obj.state.lift !== undefined
this.config.tilt = this.obj.state.tilt !== undefined
this.config.bri = false
} else if (this.type === 'light') {
this.config.wallSwitch = this.bridge.platform.config.wallSwitch ||
this.bridge.wallswitch[this.id]
Expand Down Expand Up @@ -765,10 +772,6 @@ HueLight.prototype.checkState = function (state, event) {
break
// jshint +W106
case 'bri':
if (this.config.windowCovering) {
this.checkPosition(state.bri)
break
}
this.checkBri(state.bri)
break
case 'colormode':
Expand All @@ -786,6 +789,7 @@ HueLight.prototype.checkState = function (state, event) {
case 'mode':
break
case 'lift':
this.checkLift(state.lift)
break
case 'on':
if (this.config.valve) {
Expand All @@ -800,15 +804,15 @@ HueLight.prototype.checkState = function (state, event) {
this.checkReachable(state.reachable)
break
case 'sat':
if (this.config.windowCovering) {
this.checkTilt(state.sat)
break
}
this.checkSat(state.sat)
break
case 'scene':
break
case 'speed':
this.checkSpeed(state.speed)
break
case 'tilt':
this.checkTilt(state.tilt)
break
case 'x':
break
Expand Down Expand Up @@ -1174,18 +1178,18 @@ HueLight.prototype.checkXY = function (xy) {
}
}

HueLight.prototype.checkPosition = function (bri) {
if (!this.config.windowCovering || !this.config.bri) {
HueLight.prototype.checkLift = function (lift) {
if (!this.config.windowCovering || !this.config.lift) {
return
}
if (this.obj.state.bri !== bri) {
if (this.obj.state.lift !== lift) {
this.log.debug(
'%s: %s bri (position) changed from %s to %s', this.name, this.type,
this.obj.state.bri, bri
'%s: %s lift changed from %s to %s', this.name, this.type,
this.obj.state.lift, lift
)
this.obj.state.bri = bri
this.obj.state.lift = lift
}
let hkPosition = 100 - Math.round(this.obj.state.bri * 100.0 / 254.0)
let hkPosition = 100 - this.obj.state.lift
hkPosition = 5 * Math.round(hkPosition / 5.0) // round to multiple of 5
if (this.hk.currentPosition !== hkPosition) {
if (this.hk.currentPosition !== undefined) {
Expand All @@ -1205,23 +1209,22 @@ HueLight.prototype.checkPosition = function (bri) {
}
}

HueLight.prototype.checkTilt = function (sat) {
if (!this.config.windowCovering || !this.config.sat) {
HueLight.prototype.checkTilt = function (tilt) {
if (!this.config.windowCovering || !this.config.tilt) {
return
}
if (this.obj.state.sat !== sat) {
if (this.obj.state.tilt !== tilt) {
this.log.debug(
'%s: %s sat (tilt) changed from %s to %s', this.name, this.type,
this.obj.state.sat, sat
'%s: %s tilt changed from %s to %s', this.name, this.type,
this.obj.state.tilt, tilt
)
this.obj.state.sat = sat
this.obj.state.tilt = tilt
}
let hkTilt = Math.round(this.obj.state.sat * 180.0 / 254.0) - 90
hkTilt = 5 * Math.round(hkTilt / 5.0) // round to multiple of 5
const hkTilt = Math.round(this.obj.state.tilt * 1.80) - 90.0
if (this.hk.currentTilt !== hkTilt) {
if (this.hk.currentTilt !== undefined) {
this.log.info(
'%s: set homekit current tilt from %s%% to %s%%', this.name,
'%s: set homekit current tilt from %s° to %s°', this.name,
this.hk.currentTilt, hkTilt
)
}
Expand All @@ -1234,12 +1237,59 @@ HueLight.prototype.checkTilt = function (sat) {
}
}

HueLight.prototype.checkSpeed = function (speed) {
if (!this.config.speed) {
return
}
if (this.obj.state.speed !== speed) {
this.log.debug(
'%s: %s speed changed from %s to %s', this.name, this.type,
this.obj.state.speed, speed
)
this.obj.state.speed = speed
if (this.obj.state.speed > 4) {
this.log.warn(
'%s: %s speed %d: not supported', this.name, this.type,
this.obj.state.speed
)
return
}
const hkFanOn = speed !== 0
const hkFanSpeed = speed * 25
if (this.hk.fanOn !== hkFanOn) {
if (this.hk.fanOn !== undefined) {
this.log.info(
'%s: set homekit fan on from %s to %s', this.name,
this.hk.fanOn, hkFanOn
)
}
this.hk.fanOn = hkFanOn
this.fanService.getCharacteristic(Characteristic.On)
.updateValue(this.hk.fanOn)
}
if (this.hk.fanSpeed !== hkFanSpeed) {
this.log.info(
'%s: set homekit rotation speed from %s%% to %s%%', this.name,
this.hk.fanSpeed, hkFanSpeed
)
this.hk.fanSpeed = hkFanSpeed
this.fanService.getCharacteristic(Characteristic.RotationSpeed)
.setProps({
minValue: 0,
maxValue: 100,
minStep: 25
})
.updateValue(this.hk.fanSpeed)
}
}
}

// ===== Homekit Events ========================================================

HueLight.prototype.identify = function (callback) {
this.log.debug('%s: %s: config: %j', this.bridge.name, this.resource, this.config)
this.log.info('%s: identify', this.name)
if (this.config.valve) {
if (this.config.valve || this.config.windowCovering || !this.config.on) {
return callback()
}
let alert = 'select'
Expand Down Expand Up @@ -1574,9 +1624,9 @@ HueLight.prototype.setPosition = function (position, callback) {
)
const oldPosition = this.hk.targetPosition
this.hk.targetPosition = position
const newBri = Math.round((100 - this.hk.targetPosition) * 254.0 / 100.0)
this.put({ bri: newBri }).then(() => {
this.obj.state.bri = newBri
const newLift = 100 - this.hk.targetPosition
this.put({ lift: newLift }).then(() => {
this.obj.state.lift = newLift
const positionState = this.hk.targetPosition > this.hk.currentPosition
? Characteristic.PositionState.INCREASING
: Characteristic.PositionState.DECREASING
Expand Down Expand Up @@ -1606,21 +1656,44 @@ HueLight.prototype.setTilt = function (tilt, callback) {
return callback()
}
this.log.info(
'%s: homekit target tilt changed from %s° to %s°', this.name,
'%s: homekit tilt angle changed from %s° to %s°', this.name,
this.hk.targetTilt, tilt
)
const oldTilt = this.hk.targetTilt
this.hk.targetTilt = tilt
const newSat = Math.round((90 + this.hk.targetTilt) * 254.0 / 180.0)
this.put({ sat: newSat }).then(() => {
this.obj.state.sat = newSat
const newTilt = Math.round((90 + this.hk.targetTilt) / 1.80)
this.put({ tilt: newTilt }).then(() => {
this.obj.state.tilt = newTilt
callback()
}).catch((error) => {
this.hk.targetTilt = oldTilt
callback(error)
})
}

HueLight.prototype.setSpeed = function (speed, callback) {
if (speed === this.hk.fanSpeed) {
return callback()
}
this.log.info(
'%s: homekit rotation speed changed from %s%% to %s%%', this.name,
this.hk.fanSpeed, speed
)
const oldFanSpeed = this.hk.fanSpeed
this.hk.fanSpeed = speed
const newSpeed = Math.floor(this.hk.fanSpeed / 25)
this.put({ speed: newSpeed }).then(() => {
this.obj.state.speed = newSpeed
callback()
this.hk.fanOn = this.obj.state.speed !== 0
this.fanService.getCharacteristic(Characteristic.On)
.updateValue(this.hk.fanOn)
}).catch((error) => {
this.hk.fanSpeed = oldFanSpeed
callback(error)
})
}

HueLight.prototype.getRemainingDuration = function (callback) {
let remaining = this.hk.autoInActive - moment().unix()
remaining = remaining > 0 ? remaining : 0
Expand Down

0 comments on commit d23ba05

Please sign in to comment.