homebridge-yoto 0.0.37 → 0.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/accessory.js +64 -38
- package/lib/platform.js +44 -16
- package/package.json +1 -1
package/lib/accessory.js
CHANGED
|
@@ -92,8 +92,8 @@ export class YotoPlayerAccessory {
|
|
|
92
92
|
/** @type {Service | undefined} */ bluetoothService
|
|
93
93
|
/** @type {Service | undefined} */ dayMaxVolumeService
|
|
94
94
|
/** @type {Service | undefined} */ nightMaxVolumeService
|
|
95
|
-
// Volume state for mute/unmute (0-
|
|
96
|
-
/** @type {number} */ #lastNonZeroVolume =
|
|
95
|
+
// Volume state for mute/unmute (0-100 percent)
|
|
96
|
+
/** @type {number} */ #lastNonZeroVolume = 50
|
|
97
97
|
// Nightlight color state for restore-on-ON
|
|
98
98
|
/** @type {string} */ #lastDayColor = '0xffffff'
|
|
99
99
|
/** @type {string} */ #lastNightColor = '0xffffff'
|
|
@@ -325,7 +325,7 @@ export class YotoPlayerAccessory {
|
|
|
325
325
|
.getCharacteristic(Characteristic.Brightness)
|
|
326
326
|
.setProps({
|
|
327
327
|
minValue: 0,
|
|
328
|
-
maxValue:
|
|
328
|
+
maxValue: 100,
|
|
329
329
|
minStep: 1,
|
|
330
330
|
})
|
|
331
331
|
.onGet(this.getVolume.bind(this))
|
|
@@ -598,7 +598,7 @@ export class YotoPlayerAccessory {
|
|
|
598
598
|
|
|
599
599
|
dayService
|
|
600
600
|
.getCharacteristic(Characteristic.Brightness)
|
|
601
|
-
.setProps({ minValue: 0, maxValue:
|
|
601
|
+
.setProps({ minValue: 0, maxValue: 100, minStep: 1 })
|
|
602
602
|
.onGet(this.getDayMaxVolume.bind(this))
|
|
603
603
|
.onSet(this.setDayMaxVolume.bind(this))
|
|
604
604
|
|
|
@@ -622,7 +622,7 @@ export class YotoPlayerAccessory {
|
|
|
622
622
|
|
|
623
623
|
nightService
|
|
624
624
|
.getCharacteristic(Characteristic.Brightness)
|
|
625
|
-
.setProps({ minValue: 0, maxValue:
|
|
625
|
+
.setProps({ minValue: 0, maxValue: 100, minStep: 1 })
|
|
626
626
|
.onGet(this.getNightMaxVolume.bind(this))
|
|
627
627
|
.onSet(this.setNightMaxVolume.bind(this))
|
|
628
628
|
|
|
@@ -917,16 +917,23 @@ export class YotoPlayerAccessory {
|
|
|
917
917
|
}
|
|
918
918
|
|
|
919
919
|
/**
|
|
920
|
-
* Get volume level (0-16 steps)
|
|
920
|
+
* Get volume level as percentage (mapped from 0-16 steps)
|
|
921
921
|
* @returns {Promise<CharacteristicValue>}
|
|
922
922
|
*/
|
|
923
923
|
async getVolume () {
|
|
924
|
-
this.#
|
|
925
|
-
|
|
924
|
+
const volumeSteps = this.#deviceModel.status.volume
|
|
925
|
+
const normalizedSteps = Number.isFinite(volumeSteps) ? volumeSteps : 0
|
|
926
|
+
const clampedSteps = Math.max(0, Math.min(normalizedSteps, 16))
|
|
927
|
+
const percent = Math.round((clampedSteps / 16) * 100)
|
|
928
|
+
this.#log.debug(
|
|
929
|
+
LOG_PREFIX.ACCESSORY,
|
|
930
|
+
`[${this.#device.name}] Get volume rawSteps=${volumeSteps} steps=${clampedSteps} percent=${percent}`
|
|
931
|
+
)
|
|
932
|
+
return percent
|
|
926
933
|
}
|
|
927
934
|
|
|
928
935
|
/**
|
|
929
|
-
* Set volume level (0-16 steps)
|
|
936
|
+
* Set volume level as percentage (mapped to 0-16 steps)
|
|
930
937
|
* @param {CharacteristicValue} value
|
|
931
938
|
* @returns {Promise<void>}
|
|
932
939
|
*/
|
|
@@ -934,25 +941,28 @@ export class YotoPlayerAccessory {
|
|
|
934
941
|
const deviceModel = this.#deviceModel
|
|
935
942
|
this.#log.debug(LOG_PREFIX.ACCESSORY, `[${this.#device.name}] Set volume:`, value)
|
|
936
943
|
|
|
937
|
-
const
|
|
938
|
-
if (!Number.isFinite(
|
|
944
|
+
const requestedPercent = typeof value === 'number' ? value : Number(value)
|
|
945
|
+
if (!Number.isFinite(requestedPercent)) {
|
|
939
946
|
throw new this.#platform.api.hap.HapStatusError(
|
|
940
947
|
this.#platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST
|
|
941
948
|
)
|
|
942
949
|
}
|
|
943
950
|
|
|
951
|
+
const normalizedPercent = Math.max(0, Math.min(Math.round(requestedPercent), 100))
|
|
952
|
+
const requestedSteps = Math.round((normalizedPercent / 100) * 16)
|
|
944
953
|
const maxVolumeSteps = Number.isFinite(deviceModel.status.maxVolume)
|
|
945
954
|
? deviceModel.status.maxVolume
|
|
946
955
|
: 16
|
|
947
956
|
const steps = Math.max(0, Math.min(Math.round(requestedSteps), maxVolumeSteps))
|
|
957
|
+
const resultPercent = Math.round((steps / 16) * 100)
|
|
948
958
|
this.#log.debug(
|
|
949
959
|
LOG_PREFIX.ACCESSORY,
|
|
950
|
-
`[${this.#device.name}] Set volume raw=${value}
|
|
960
|
+
`[${this.#device.name}] Set volume raw=${value} normalizedPercent=${normalizedPercent} requestedSteps=${requestedSteps} -> steps=${steps} percent=${resultPercent} (maxSteps=${maxVolumeSteps})`
|
|
951
961
|
)
|
|
952
962
|
|
|
953
963
|
// Track last non-zero volume for unmute
|
|
954
964
|
if (steps > 0) {
|
|
955
|
-
this.#lastNonZeroVolume = steps
|
|
965
|
+
this.#lastNonZeroVolume = Math.round((steps / 16) * 100)
|
|
956
966
|
}
|
|
957
967
|
|
|
958
968
|
try {
|
|
@@ -964,10 +974,11 @@ export class YotoPlayerAccessory {
|
|
|
964
974
|
.getCharacteristic(Characteristic.On)
|
|
965
975
|
.updateValue(steps > 0)
|
|
966
976
|
|
|
967
|
-
if (steps !== requestedSteps) {
|
|
977
|
+
if (steps !== requestedSteps || normalizedPercent !== requestedPercent) {
|
|
978
|
+
const clampedPercent = Math.round((steps / 16) * 100)
|
|
968
979
|
this.volumeService
|
|
969
980
|
.getCharacteristic(Characteristic.Brightness)
|
|
970
|
-
.updateValue(
|
|
981
|
+
.updateValue(clampedPercent)
|
|
971
982
|
}
|
|
972
983
|
}
|
|
973
984
|
} catch (error) {
|
|
@@ -1555,67 +1566,79 @@ export class YotoPlayerAccessory {
|
|
|
1555
1566
|
// ==================== Volume Limit Lightbulb Getters/Setters ====================
|
|
1556
1567
|
|
|
1557
1568
|
/**
|
|
1558
|
-
* Get day max volume limit
|
|
1569
|
+
* Get day max volume limit as percentage (mapped from 0-16 steps)
|
|
1559
1570
|
* @returns {Promise<CharacteristicValue>}
|
|
1560
1571
|
*/
|
|
1561
1572
|
async getDayMaxVolume () {
|
|
1562
1573
|
const limit = this.#deviceModel.config.maxVolumeLimit
|
|
1574
|
+
const steps = Number.isFinite(limit) ? limit : 16
|
|
1575
|
+
const clampedSteps = Math.max(0, Math.min(steps, 16))
|
|
1576
|
+
const percent = Math.round((clampedSteps / 16) * 100)
|
|
1563
1577
|
this.#log.debug(
|
|
1564
1578
|
LOG_PREFIX.ACCESSORY,
|
|
1565
|
-
`[${this.#device.name}] Get day max volume limit
|
|
1579
|
+
`[${this.#device.name}] Get day max volume limit rawSteps=${limit} steps=${clampedSteps} percent=${percent}`
|
|
1566
1580
|
)
|
|
1567
|
-
return
|
|
1581
|
+
return percent
|
|
1568
1582
|
}
|
|
1569
1583
|
|
|
1570
1584
|
/**
|
|
1571
|
-
* Set day max volume limit
|
|
1585
|
+
* Set day max volume limit as percentage (mapped to 0-16 steps)
|
|
1572
1586
|
* @param {CharacteristicValue} value
|
|
1573
1587
|
*/
|
|
1574
1588
|
async setDayMaxVolume (value) {
|
|
1575
|
-
const
|
|
1576
|
-
if (!Number.isFinite(
|
|
1589
|
+
const requestedPercent = typeof value === 'number' ? value : Number(value)
|
|
1590
|
+
if (!Number.isFinite(requestedPercent)) {
|
|
1577
1591
|
throw new this.#platform.api.hap.HapStatusError(
|
|
1578
1592
|
this.#platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST
|
|
1579
1593
|
)
|
|
1580
1594
|
}
|
|
1581
1595
|
|
|
1582
|
-
const
|
|
1596
|
+
const normalizedPercent = Math.max(0, Math.min(Math.round(requestedPercent), 100))
|
|
1597
|
+
const requestedSteps = Math.round((normalizedPercent / 100) * 16)
|
|
1598
|
+
const limit = Math.max(0, Math.min(Math.round(requestedSteps), 16))
|
|
1599
|
+
const limitPercent = Math.round((limit / 16) * 100)
|
|
1583
1600
|
this.#log.debug(
|
|
1584
1601
|
LOG_PREFIX.ACCESSORY,
|
|
1585
|
-
`[${this.#device.name}] Set day max volume limit raw=${value}
|
|
1602
|
+
`[${this.#device.name}] Set day max volume limit raw=${value} normalizedPercent=${normalizedPercent} requestedSteps=${requestedSteps} -> steps=${limit} percent=${limitPercent}`
|
|
1586
1603
|
)
|
|
1587
1604
|
await this.#deviceModel.updateConfig({ maxVolumeLimit: limit })
|
|
1588
1605
|
}
|
|
1589
1606
|
|
|
1590
1607
|
/**
|
|
1591
|
-
* Get night max volume limit
|
|
1608
|
+
* Get night max volume limit as percentage (mapped from 0-16 steps)
|
|
1592
1609
|
* @returns {Promise<CharacteristicValue>}
|
|
1593
1610
|
*/
|
|
1594
1611
|
async getNightMaxVolume () {
|
|
1595
1612
|
const limit = this.#deviceModel.config.nightMaxVolumeLimit
|
|
1613
|
+
const steps = Number.isFinite(limit) ? limit : 10
|
|
1614
|
+
const clampedSteps = Math.max(0, Math.min(steps, 16))
|
|
1615
|
+
const percent = Math.round((clampedSteps / 16) * 100)
|
|
1596
1616
|
this.#log.debug(
|
|
1597
1617
|
LOG_PREFIX.ACCESSORY,
|
|
1598
|
-
`[${this.#device.name}] Get night max volume limit
|
|
1618
|
+
`[${this.#device.name}] Get night max volume limit rawSteps=${limit} steps=${clampedSteps} percent=${percent}`
|
|
1599
1619
|
)
|
|
1600
|
-
return
|
|
1620
|
+
return percent
|
|
1601
1621
|
}
|
|
1602
1622
|
|
|
1603
1623
|
/**
|
|
1604
|
-
* Set night max volume limit
|
|
1624
|
+
* Set night max volume limit as percentage (mapped to 0-16 steps)
|
|
1605
1625
|
* @param {CharacteristicValue} value
|
|
1606
1626
|
*/
|
|
1607
1627
|
async setNightMaxVolume (value) {
|
|
1608
|
-
const
|
|
1609
|
-
if (!Number.isFinite(
|
|
1628
|
+
const requestedPercent = typeof value === 'number' ? value : Number(value)
|
|
1629
|
+
if (!Number.isFinite(requestedPercent)) {
|
|
1610
1630
|
throw new this.#platform.api.hap.HapStatusError(
|
|
1611
1631
|
this.#platform.api.hap.HAPStatus.INVALID_VALUE_IN_REQUEST
|
|
1612
1632
|
)
|
|
1613
1633
|
}
|
|
1614
1634
|
|
|
1615
|
-
const
|
|
1635
|
+
const normalizedPercent = Math.max(0, Math.min(Math.round(requestedPercent), 100))
|
|
1636
|
+
const requestedSteps = Math.round((normalizedPercent / 100) * 16)
|
|
1637
|
+
const limit = Math.max(0, Math.min(Math.round(requestedSteps), 16))
|
|
1638
|
+
const limitPercent = Math.round((limit / 16) * 100)
|
|
1616
1639
|
this.#log.debug(
|
|
1617
1640
|
LOG_PREFIX.ACCESSORY,
|
|
1618
|
-
`[${this.#device.name}] Set night max volume limit raw=${value}
|
|
1641
|
+
`[${this.#device.name}] Set night max volume limit raw=${value} normalizedPercent=${normalizedPercent} requestedSteps=${requestedSteps} -> steps=${limit} percent=${limitPercent}`
|
|
1619
1642
|
)
|
|
1620
1643
|
await this.#deviceModel.updateConfig({ nightMaxVolumeLimit: limit })
|
|
1621
1644
|
}
|
|
@@ -1645,18 +1668,19 @@ export class YotoPlayerAccessory {
|
|
|
1645
1668
|
|
|
1646
1669
|
const { Characteristic } = this.#platform
|
|
1647
1670
|
if (volumeSteps > 0) {
|
|
1648
|
-
this.#lastNonZeroVolume = volumeSteps
|
|
1671
|
+
this.#lastNonZeroVolume = Math.round((volumeSteps / 16) * 100)
|
|
1649
1672
|
}
|
|
1650
1673
|
|
|
1651
1674
|
const normalizedVolume = Number.isFinite(volumeSteps) ? volumeSteps : 0
|
|
1652
1675
|
const clampedVolume = Math.max(0, Math.min(normalizedVolume, 16))
|
|
1676
|
+
const percent = Math.round((clampedVolume / 16) * 100)
|
|
1653
1677
|
this.#log.debug(
|
|
1654
1678
|
LOG_PREFIX.ACCESSORY,
|
|
1655
|
-
`[${this.#device.name}] Update volume characteristic
|
|
1679
|
+
`[${this.#device.name}] Update volume characteristic rawSteps=${volumeSteps} steps=${clampedVolume} percent=${percent}`
|
|
1656
1680
|
)
|
|
1657
1681
|
this.volumeService
|
|
1658
1682
|
.getCharacteristic(Characteristic.Brightness)
|
|
1659
|
-
.updateValue(
|
|
1683
|
+
.updateValue(percent)
|
|
1660
1684
|
}
|
|
1661
1685
|
|
|
1662
1686
|
/**
|
|
@@ -1920,25 +1944,27 @@ export class YotoPlayerAccessory {
|
|
|
1920
1944
|
if (this.dayMaxVolumeService) {
|
|
1921
1945
|
const limit = Number.isFinite(config.maxVolumeLimit) ? config.maxVolumeLimit : 16
|
|
1922
1946
|
const clampedLimit = Math.max(0, Math.min(limit, 16))
|
|
1947
|
+
const percent = Math.round((clampedLimit / 16) * 100)
|
|
1923
1948
|
this.#log.debug(
|
|
1924
1949
|
LOG_PREFIX.ACCESSORY,
|
|
1925
|
-
`[${this.#device.name}] Update day max volume characteristic
|
|
1950
|
+
`[${this.#device.name}] Update day max volume characteristic rawSteps=${limit} steps=${clampedLimit} percent=${percent}`
|
|
1926
1951
|
)
|
|
1927
1952
|
this.dayMaxVolumeService
|
|
1928
1953
|
.getCharacteristic(Characteristic.Brightness)
|
|
1929
|
-
.updateValue(
|
|
1954
|
+
.updateValue(percent)
|
|
1930
1955
|
}
|
|
1931
1956
|
|
|
1932
1957
|
if (this.nightMaxVolumeService) {
|
|
1933
1958
|
const limit = Number.isFinite(config.nightMaxVolumeLimit) ? config.nightMaxVolumeLimit : 10
|
|
1934
1959
|
const clampedLimit = Math.max(0, Math.min(limit, 16))
|
|
1960
|
+
const percent = Math.round((clampedLimit / 16) * 100)
|
|
1935
1961
|
this.#log.debug(
|
|
1936
1962
|
LOG_PREFIX.ACCESSORY,
|
|
1937
|
-
`[${this.#device.name}] Update night max volume characteristic
|
|
1963
|
+
`[${this.#device.name}] Update night max volume characteristic rawSteps=${limit} steps=${clampedLimit} percent=${percent}`
|
|
1938
1964
|
)
|
|
1939
1965
|
this.nightMaxVolumeService
|
|
1940
1966
|
.getCharacteristic(Characteristic.Brightness)
|
|
1941
|
-
.updateValue(
|
|
1967
|
+
.updateValue(percent)
|
|
1942
1968
|
}
|
|
1943
1969
|
}
|
|
1944
1970
|
|
package/lib/platform.js
CHANGED
|
@@ -188,68 +188,96 @@ export class YotoPlatform {
|
|
|
188
188
|
this.log.info(`Device offline: ${deviceId}${reason}`)
|
|
189
189
|
})
|
|
190
190
|
|
|
191
|
+
const getDeviceLabel = (deviceId) => {
|
|
192
|
+
const deviceName = this.yotoAccount?.getDevice(deviceId)?.device?.name
|
|
193
|
+
return deviceName || deviceId
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const formatLegacyStatusFields = (message) => {
|
|
197
|
+
const status = message?.status
|
|
198
|
+
if (!status || typeof status !== 'object') return ''
|
|
199
|
+
const fields = Object.keys(status)
|
|
200
|
+
if (!fields.length) return ''
|
|
201
|
+
const preview = fields.slice(0, 8).join(', ')
|
|
202
|
+
const suffix = fields.length > 8 ? `, +${fields.length - 8} more` : ''
|
|
203
|
+
return ` fields: ${preview}${suffix}`
|
|
204
|
+
}
|
|
205
|
+
|
|
191
206
|
this.yotoAccount.on('statusUpdate', ({ deviceId, source, changedFields }) => {
|
|
207
|
+
const label = getDeviceLabel(deviceId)
|
|
192
208
|
const fields = Array.from(changedFields).join(', ')
|
|
193
|
-
this.log.debug(`Status update [${
|
|
209
|
+
this.log.debug(`Status update [${label} ${source}]: ${fields}`)
|
|
194
210
|
})
|
|
195
211
|
|
|
196
212
|
this.yotoAccount.on('configUpdate', ({ deviceId, changedFields }) => {
|
|
213
|
+
const label = getDeviceLabel(deviceId)
|
|
197
214
|
const fields = Array.from(changedFields).join(', ')
|
|
198
|
-
this.log.debug(`Config update [${
|
|
215
|
+
this.log.debug(`Config update [${label}]: ${fields}`)
|
|
199
216
|
})
|
|
200
217
|
|
|
201
218
|
this.yotoAccount.on('playbackUpdate', ({ deviceId, changedFields }) => {
|
|
219
|
+
const label = getDeviceLabel(deviceId)
|
|
202
220
|
const fields = Array.from(changedFields).join(', ')
|
|
203
|
-
this.log.debug(`Playback update [${
|
|
221
|
+
this.log.debug(`Playback update [${label}]: ${fields}`)
|
|
204
222
|
})
|
|
205
223
|
|
|
206
224
|
this.yotoAccount.on('mqttConnect', ({ deviceId }) => {
|
|
207
|
-
const
|
|
208
|
-
const label = deviceName ? `${deviceName} (${deviceId})` : deviceId
|
|
225
|
+
const label = getDeviceLabel(deviceId)
|
|
209
226
|
this.log.debug(`MQTT connected: ${label}`)
|
|
210
227
|
})
|
|
211
228
|
|
|
212
229
|
this.yotoAccount.on('mqttDisconnect', ({ deviceId, metadata }) => {
|
|
230
|
+
const label = getDeviceLabel(deviceId)
|
|
213
231
|
const reasonCode = metadata?.packet?.reasonCode
|
|
214
232
|
const reason = typeof reasonCode === 'number' ? ` (code ${reasonCode})` : ''
|
|
215
|
-
this.log.warn(`MQTT disconnected: ${
|
|
233
|
+
this.log.warn(`MQTT disconnected: ${label}${reason}`)
|
|
216
234
|
})
|
|
217
235
|
|
|
218
236
|
this.yotoAccount.on('mqttClose', ({ deviceId, metadata }) => {
|
|
237
|
+
const label = getDeviceLabel(deviceId)
|
|
219
238
|
const reason = metadata?.reason ? ` (${metadata.reason})` : ''
|
|
220
|
-
this.log.debug(`MQTT closed: ${
|
|
239
|
+
this.log.debug(`MQTT closed: ${label}${reason}`)
|
|
221
240
|
})
|
|
222
241
|
|
|
223
242
|
this.yotoAccount.on('mqttReconnect', ({ deviceId }) => {
|
|
224
|
-
|
|
243
|
+
const label = getDeviceLabel(deviceId)
|
|
244
|
+
this.log.debug(`MQTT reconnecting: ${label}`)
|
|
225
245
|
})
|
|
226
246
|
|
|
227
247
|
this.yotoAccount.on('mqttOffline', ({ deviceId }) => {
|
|
228
|
-
|
|
248
|
+
const label = getDeviceLabel(deviceId)
|
|
249
|
+
this.log.debug(`MQTT offline: ${label}`)
|
|
229
250
|
})
|
|
230
251
|
|
|
231
252
|
this.yotoAccount.on('mqttEnd', ({ deviceId }) => {
|
|
232
|
-
|
|
253
|
+
const label = getDeviceLabel(deviceId)
|
|
254
|
+
this.log.debug(`MQTT ended: ${label}`)
|
|
233
255
|
})
|
|
234
256
|
|
|
235
257
|
this.yotoAccount.on('mqttStatus', ({ deviceId, topic }) => {
|
|
236
|
-
|
|
258
|
+
const label = getDeviceLabel(deviceId)
|
|
259
|
+
this.log.debug(`MQTT status [${label}]: ${topic}`)
|
|
237
260
|
})
|
|
238
261
|
|
|
239
262
|
this.yotoAccount.on('mqttEvents', ({ deviceId, topic }) => {
|
|
240
|
-
|
|
263
|
+
const label = getDeviceLabel(deviceId)
|
|
264
|
+
this.log.debug(`MQTT events [${label}]: ${topic}`)
|
|
241
265
|
})
|
|
242
266
|
|
|
243
|
-
this.yotoAccount.on('mqttStatusLegacy', ({ deviceId, topic }) => {
|
|
244
|
-
|
|
267
|
+
this.yotoAccount.on('mqttStatusLegacy', ({ deviceId, topic, message }) => {
|
|
268
|
+
const label = getDeviceLabel(deviceId)
|
|
269
|
+
const fields = formatLegacyStatusFields(message)
|
|
270
|
+
this.log.debug(`MQTT legacy status [${label}]: ${topic}${fields}`)
|
|
245
271
|
})
|
|
246
272
|
|
|
247
273
|
this.yotoAccount.on('mqttResponse', ({ deviceId, topic }) => {
|
|
248
|
-
|
|
274
|
+
const label = getDeviceLabel(deviceId)
|
|
275
|
+
this.log.debug(`MQTT response [${label}]: ${topic}`)
|
|
249
276
|
})
|
|
250
277
|
|
|
251
278
|
this.yotoAccount.on('mqttUnknown', ({ deviceId, topic }) => {
|
|
252
|
-
|
|
279
|
+
const label = getDeviceLabel(deviceId)
|
|
280
|
+
this.log.debug(`MQTT unknown [${label}]: ${topic}`)
|
|
253
281
|
})
|
|
254
282
|
|
|
255
283
|
// Start the account (discovers devices, creates device models, starts MQTT)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "homebridge-yoto",
|
|
3
3
|
"description": "Control your Yoto players through Apple HomeKit with real-time MQTT updates",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.38",
|
|
5
5
|
"author": "Bret Comnes <bcomnes@gmail.com> (https://bret.io)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/bcomnes/homebridge-yoto/issues"
|