Skip to content

Commit

Permalink
Adaptive Lighting support #335
Browse files Browse the repository at this point in the history
  • Loading branch information
Shaquu committed Jun 17, 2024
1 parent 853545b commit 5039a13
Show file tree
Hide file tree
Showing 14 changed files with 173 additions and 84 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

- Removed vulnerable module 'ip' [#545](https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues/545)

### Added

- Adaptive Lighting support [#335](https://github.com/NRCHKB/node-red-contrib-homekit-bridged/issues/335)

### Changed

- Updated hap-nodejs [0.11.1 to 0.12.2](https://github.com/homebridge/HAP-NodeJS/blob/latest/CHANGELOG.md) (features
and bug fixes)
- Dependencies upgrade
- Node `10`, `12` and `16` no longer supported
- Updated GitHub Actions

## [1.6.1] - 2024-02-19

Expand Down
41 changes: 40 additions & 1 deletion build/nodes/service.html
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,25 @@
</div>
</div>

<div id="adaptive-lightning-configuration" style="display: none; border: 1px solid var(--red-ui-secondary-border-color); padding: 12px 12px 0 12px; margin-bottom: 12px;">
<label>&nbsp;&nbsp;<i class="fa fa-cog"></i> Adaptive Lightning Configuration</label>
<div class="form-row">
<label for="node-input-adaptiveLightingOptionsEnable"><i class="fa fa-toggle-on"></i> Enable</label>
<input type="checkbox" id="node-input-adaptiveLightingOptionsEnable">
</div>
<div class="form-row">
<label for="node-input-adaptiveLightingOptionsMode"><i class="fa fa-hand-o-up"></i> Mode</label>
<select id="node-input-adaptiveLightingOptionsMode">
<option value="0" selected="selected">AUTOMATIC</option>
<option value="1">MANUAL</option>
</select>
</div>
<div class="form-row">
<label for="node-input-adaptiveLightingOptionsCustomTemperatureAdjustment"><i class="fa fa-thermometer-quarter"></i> Custom Temperature Adjustment</label>
<input type="text" id="node-input-adaptiveLightingOptionsCustomTemperatureAdjustment">
</div>
</div>

<div class="form-row">
<label for="node-input-characteristicProperties"><i class="fa fa-wrench"></i> Characteristic Properties</label>
<input type="text" id="node-input-characteristicProperties" style="width: 70%">
Expand Down Expand Up @@ -474,7 +493,16 @@ <h2 id="toc_8">Characteristic Properties</h2>
},
outputs: {
value: 2,
}
},
adaptiveLightingOptionsEnable: {
value: false,
},
adaptiveLightingOptionsMode: {
value: 0,
},
adaptiveLightingOptionsCustomTemperatureAdjustment: {
value: undefined,
},
},
inputs: 1,
outputs: 2,
Expand Down Expand Up @@ -581,6 +609,7 @@ <h2 id="toc_8">Characteristic Properties</h2>
})

let cameraConfiguration = $('#camera-configuration')
let adaptiveLightningConfiguration = $('#adaptive-lightning-configuration')

selectServiceName
.find('option')
Expand All @@ -601,6 +630,16 @@ <h2 id="toc_8">Characteristic Properties</h2>
})
.change()

selectServiceName
.change(function () {
if (this.value === 'Lightbulb') {
adaptiveLightningConfiguration.fadeIn('fast')
} else {
adaptiveLightningConfiguration.fadeOut('fast')
}
})
.change()

$('#node-input-characteristicProperties').typedInput({
type: 'json',
types: ['json'],
Expand Down
41 changes: 40 additions & 1 deletion build/nodes/service2.html
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,25 @@
</div>
</div>

<div id="adaptive-lightning-configuration" style="display: none; border: 1px solid var(--red-ui-secondary-border-color); padding: 12px 12px 0 12px; margin-bottom: 12px;">
<label>&nbsp;&nbsp;<i class="fa fa-cog"></i> Adaptive Lightning Configuration</label>
<div class="form-row">
<label for="node-input-adaptiveLightingOptionsEnable"><i class="fa fa-toggle-on"></i> Enable</label>
<input type="checkbox" id="node-input-adaptiveLightingOptionsEnable">
</div>
<div class="form-row">
<label for="node-input-adaptiveLightingOptionsMode"><i class="fa fa-hand-o-up"></i> Mode</label>
<select id="node-input-adaptiveLightingOptionsMode">
<option value="0" selected="selected">AUTOMATIC</option>
<option value="1">MANUAL</option>
</select>
</div>
<div class="form-row">
<label for="node-input-adaptiveLightingOptionsCustomTemperatureAdjustment"><i class="fa fa-thermometer-quarter"></i> Custom Temperature Adjustment</label>
<input type="text" id="node-input-adaptiveLightingOptionsCustomTemperatureAdjustment">
</div>
</div>

<div class="form-row">
<label for="node-input-characteristicProperties"><i class="fa fa-wrench"></i> Characteristic Properties</label>
<input type="text" id="node-input-characteristicProperties" style="width: 70%">
Expand Down Expand Up @@ -484,7 +503,16 @@ <h2 id="toc_8">Characteristic Properties</h2>
},
outputs: {
value: 1,
}
},
adaptiveLightingOptionsEnable: {
value: false,
},
adaptiveLightingOptionsMode: {
value: 0,
},
adaptiveLightingOptionsCustomTemperatureAdjustment: {
value: undefined,
},
},
inputs: 1,
outputs: 1,
Expand Down Expand Up @@ -583,6 +611,7 @@ <h2 id="toc_8">Characteristic Properties</h2>
})

let cameraConfiguration = $('#camera-configuration')
let adaptiveLightningConfiguration = $('#adaptive-lightning-configuration')

selectServiceName
.find('option')
Expand All @@ -603,6 +632,16 @@ <h2 id="toc_8">Characteristic Properties</h2>
})
.change()

selectServiceName
.change(function () {
if (this.value === 'Lightbulb') {
adaptiveLightningConfiguration.fadeIn('fast')
} else {
adaptiveLightningConfiguration.fadeOut('fast')
}
})
.change()

$('#node-input-characteristicProperties').typedInput({
type: 'json',
types: ['json'],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-red-contrib-homekit-bridged",
"version": "1.7.0-dev.0",
"version": "1.7.0-dev.1",
"description": "Node-RED nodes to simulate Apple HomeKit devices.",
"main": "build/nodes/nrchkb.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/HAPHostNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { SemVer } from 'semver'
import semver from 'semver/preload'

import NRCHKBError from './NRCHKBError'
import HapCategories from './types/HapCategories'
import HapCategories from './types/hap-nodejs/HapCategories'
import HAPHostConfigType from './types/HAPHostConfigType'
import HAPHostNodeType from './types/HAPHostNodeType'
import HostType from './types/HostType'
Expand Down
2 changes: 1 addition & 1 deletion src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { NodeAPI } from 'node-red'

import { Storage } from './Storage'
import CustomCharacteristicType from './types/CustomCharacteristicType'
import HapCategories from './types/HapCategories'
import HapCategories from './types/hap-nodejs/HapCategories'
import HAPServiceConfigType from './types/HAPServiceConfigType'
import HAPServiceNodeType from './types/HAPServiceNodeType'

Expand Down
2 changes: 1 addition & 1 deletion src/lib/types/HAPHostConfigType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { MDNSAdvertiser } from 'hap-nodejs'
import { NodeDef } from 'node-red'
import { SemVer } from 'semver'

import HapCategories from './HapCategories'
import HapCategories from './hap-nodejs/HapCategories'

type HAPHostConfigType = NodeDef & {
bridgeName: string
Expand Down
28 changes: 5 additions & 23 deletions src/lib/types/HAPService2ConfigType.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
import { NodeDef } from 'node-red'

import CameraConfigType from './CameraConfigType'
import HAPServiceConfigType from './HAPServiceConfigType'

type HAPService2ConfigType = NodeDef & {
isParent: boolean
// hostType is number but browser js is passing it as string which may cause same comparison issues
// values are BRIDGE = 0, STANDALONE = 1
hostType: number
bridge: string
accessoryId: string
parentService: string
name: string
serviceName: string
topic: string
filter: boolean
manufacturer: string
model: string
serialNo: string
firmwareRev?: string
hardwareRev?: string
softwareRev?: string
characteristicProperties: string
waitForSetupMsg: boolean
useEventCallback: boolean
} & CameraConfigType
type HAPService2ConfigType = NodeDef &
HAPServiceConfigType & {
useEventCallback: boolean
}

export default HAPService2ConfigType
59 changes: 4 additions & 55 deletions src/lib/types/HAPService2NodeType.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,10 @@
import {
Accessory,
Characteristic,
CharacteristicChange,
CharacteristicGetCallback,
CharacteristicProps,
CharacteristicSetCallback,
CharacteristicValue,
Service,
} from 'hap-nodejs'
import { HAPConnection } from 'hap-nodejs/dist/lib/util/eventedhttp'
import { NodeAPI } from 'node-red'

import { NodeStatusUtils } from '../utils/NodeStatusUtils'
import HAPHostNodeType from './HAPHostNodeType'
import HAPService2ConfigType from './HAPService2ConfigType'
import HAPServiceNodeType from './HAPServiceNodeType'
import NodeType from './NodeType'
import PublishTimersType from './PublishTimersType'

type HAPService2NodeType = NodeType & {
config: HAPService2ConfigType
RED: NodeAPI
setupDone: boolean
configured: boolean
handleWaitForSetup: (msg: any) => any
onIdentify: (paired: boolean, callback: () => any) => void
hostNode: HAPHostNodeType
childNodes?: (HAPService2NodeType | HAPServiceNodeType)[]
service: Service
parentService: Service
parentNode?: HAPService2NodeType | HAPServiceNodeType
accessory: Accessory
characteristicProperties: { [key: string]: CharacteristicProps }
supported: string[]
publishTimers: PublishTimersType
topic_in: string
onCharacteristicGet: (
this: Characteristic,
callback: CharacteristicGetCallback,
context: any,
connection?: HAPConnection
) => void
onCharacteristicSet: (
this: Characteristic,
newValue: CharacteristicValue,
callback: CharacteristicSetCallback,
context: any,
connection?: HAPConnection
) => void
onCharacteristicChange: (
this: Characteristic,
change: CharacteristicChange
) => void
uniqueIdentifier: string
// Is Accessory reachable? On Linked Service it will be undefined. If is not true then NO_RESPONSE
reachable?: boolean
nodeStatusUtils: NodeStatusUtils
}
type HAPService2NodeType = NodeType &
HAPServiceNodeType & {
config: HAPService2ConfigType
}

export default HAPService2NodeType
5 changes: 5 additions & 0 deletions src/lib/types/HAPServiceConfigType.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AdaptiveLightingControllerMode } from 'hap-nodejs/dist/lib/controller/AdaptiveLightingController'
import { NodeDef } from 'node-red'

import CameraConfigType from './CameraConfigType'
Expand All @@ -22,6 +23,10 @@ type HAPServiceConfigType = NodeDef & {
softwareRev?: string
characteristicProperties: string
waitForSetupMsg: boolean
// If Service is a LightBulb, you can set AdaptiveLightingControllerMode.ts Lightning Mode
adaptiveLightingOptionsEnable?: boolean
adaptiveLightingOptionsMode?: AdaptiveLightingControllerMode
adaptiveLightingOptionsCustomTemperatureAdjustment?: number
} & CameraConfigType

export default HAPServiceConfigType
13 changes: 13 additions & 0 deletions src/lib/types/hap-nodejs/HapAdaptiveLightingControllerMode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
enum HapAdaptiveLightingControllerMode {
/**
* In automatic mode pretty much everything from setup to transition scheduling is done by the controller.
*/
AUTOMATIC = 1,
/**
* In manual mode setup is done by the controller but the actual transition must be done by the user.
* This is useful for lights which natively support transitions.
*/
MANUAL = 2,
}

export default HapAdaptiveLightingControllerMode
File renamed without changes.
28 changes: 28 additions & 0 deletions src/lib/utils/ServiceUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { logger } from '@nrchkb/logger'
import {
Accessory,
AdaptiveLightingController,
AdaptiveLightingControllerMode,
Characteristic,
CharacteristicChange,
CharacteristicGetCallback,
Expand Down Expand Up @@ -365,6 +367,32 @@ module.exports = function (node: HAPServiceNodeType) {
service = newService
} else {
service = accessory.addService(newService)

if (
serviceInformation.serviceName === 'Lightbulb' &&
serviceInformation.config.adaptiveLightingOptionsEnable
) {
try {
const adaptiveLightingController =
new AdaptiveLightingController(service, {
controllerMode:
serviceInformation.config
.adaptiveLightingOptionsMode ??
AdaptiveLightingControllerMode.AUTOMATIC,
customTemperatureAdjustment:
serviceInformation.config
.adaptiveLightingOptionsCustomTemperatureAdjustment,
})

accessory.configureController(
adaptiveLightingController
)
} catch (error) {
log.error(
`Failed to configure adaptive lightning due to ${error}`
)
}
}
}
} else {
// if a service with the same UUID and subtype was found it will
Expand Down
Loading

0 comments on commit 5039a13

Please sign in to comment.