@homebridge-plugins/homebridge-wemo 7.0.0

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +809 -0
  2. package/LICENSE +21 -0
  3. package/README.md +66 -0
  4. package/config.schema.json +814 -0
  5. package/eslint.config.js +50 -0
  6. package/lib/connection/http.js +174 -0
  7. package/lib/connection/upnp.js +155 -0
  8. package/lib/device/coffee.js +167 -0
  9. package/lib/device/crockpot.js +380 -0
  10. package/lib/device/dimmer.js +280 -0
  11. package/lib/device/heater.js +416 -0
  12. package/lib/device/humidifier.js +379 -0
  13. package/lib/device/index.js +39 -0
  14. package/lib/device/insight.js +353 -0
  15. package/lib/device/lightswitch.js +154 -0
  16. package/lib/device/link-bulb.js +467 -0
  17. package/lib/device/link-hub.js +63 -0
  18. package/lib/device/maker-garage.js +426 -0
  19. package/lib/device/maker-switch.js +202 -0
  20. package/lib/device/motion.js +148 -0
  21. package/lib/device/outlet.js +148 -0
  22. package/lib/device/purifier.js +468 -0
  23. package/lib/device/simulation/purifier-insight.js +357 -0
  24. package/lib/device/simulation/purifier.js +159 -0
  25. package/lib/device/simulation/switch-insight.js +315 -0
  26. package/lib/device/simulation/switch.js +154 -0
  27. package/lib/fakegato/LICENSE +21 -0
  28. package/lib/fakegato/fakegato-history.js +814 -0
  29. package/lib/fakegato/fakegato-storage.js +108 -0
  30. package/lib/fakegato/fakegato-timer.js +125 -0
  31. package/lib/fakegato/uuid.js +27 -0
  32. package/lib/homebridge-ui/public/index.html +315 -0
  33. package/lib/homebridge-ui/server.js +10 -0
  34. package/lib/index.js +8 -0
  35. package/lib/platform.js +1423 -0
  36. package/lib/utils/colour.js +135 -0
  37. package/lib/utils/constants.js +129 -0
  38. package/lib/utils/eve-chars.js +130 -0
  39. package/lib/utils/functions.js +52 -0
  40. package/lib/utils/lang-en.js +125 -0
  41. package/package.json +70 -0
@@ -0,0 +1,135 @@
1
+ function hs2rgb(h, s) {
2
+ /*
3
+ Credit:
4
+ https://github.com/WickyNilliams/pure-color
5
+ */
6
+ h = Number.parseInt(h, 10) / 60
7
+ s = Number.parseInt(s, 10) / 100
8
+ const f = h - Math.floor(h)
9
+ const p = 255 * (1 - s)
10
+ const q = 255 * (1 - s * f)
11
+ const t = 255 * (1 - s * (1 - f))
12
+ let rgb
13
+ switch (Math.floor(h) % 6) {
14
+ case 0:
15
+ rgb = [255, t, p]
16
+ break
17
+ case 1:
18
+ rgb = [q, 255, p]
19
+ break
20
+ case 2:
21
+ rgb = [p, 255, t]
22
+ break
23
+ case 3:
24
+ rgb = [p, q, 255]
25
+ break
26
+ case 4:
27
+ rgb = [t, p, 255]
28
+ break
29
+ case 5:
30
+ rgb = [255, p, q]
31
+ break
32
+ default:
33
+ return []
34
+ }
35
+ if (rgb[0] === 255 && rgb[1] <= 25 && rgb[2] <= 25) {
36
+ rgb[1] = 0
37
+ rgb[2] = 0
38
+ }
39
+ return [Math.round(rgb[0]), Math.round(rgb[1]), Math.round(rgb[2])]
40
+ }
41
+
42
+ function rgb2hs(r, g, b) {
43
+ /*
44
+ Credit:
45
+ https://github.com/WickyNilliams/pure-color
46
+ */
47
+ r = Number.parseInt(r, 10)
48
+ g = Number.parseInt(g, 10)
49
+ b = Number.parseInt(b, 10)
50
+ const min = Math.min(r, g, b)
51
+ const max = Math.max(r, g, b)
52
+ const delta = max - min
53
+ let h
54
+ let s
55
+ if (max === 0) {
56
+ s = 0
57
+ } else {
58
+ s = (delta / max) * 100
59
+ }
60
+ if (max === min) {
61
+ h = 0
62
+ } else if (r === max) {
63
+ h = (g - b) / delta
64
+ } else if (g === max) {
65
+ h = 2 + (b - r) / delta
66
+ } else if (b === max) {
67
+ h = 4 + (r - g) / delta
68
+ }
69
+ h = Math.min(h * 60, 360)
70
+
71
+ if (h < 0) {
72
+ h += 360
73
+ }
74
+ return [Math.round(h), Math.round(s)]
75
+ }
76
+
77
+ function rgb2xy(r, g, b) {
78
+ const redC = r / 255
79
+ const greenC = g / 255
80
+ const blueC = b / 255
81
+ const redN = redC > 0.04045 ? ((redC + 0.055) / (1.0 + 0.055)) ** 2.4 : redC / 12.92
82
+ const greenN = greenC > 0.04045 ? ((greenC + 0.055) / (1.0 + 0.055)) ** 2.4 : greenC / 12.92
83
+ const blueN = blueC > 0.04045 ? ((blueC + 0.055) / (1.0 + 0.055)) ** 2.4 : blueC / 12.92
84
+ const X = redN * 0.664511 + greenN * 0.154324 + blueN * 0.162028
85
+ const Y = redN * 0.283881 + greenN * 0.668433 + blueN * 0.047685
86
+ const Z = redN * 0.000088 + greenN * 0.07231 + blueN * 0.986039
87
+ const x = X / (X + Y + Z)
88
+ const y = Y / (X + Y + Z)
89
+ return [x, y]
90
+ }
91
+
92
+ function xy2rgb(x, y) {
93
+ const z = 1 - x - y
94
+ const X = x / y
95
+ const Z = z / y
96
+ let red = X * 1.656492 - 1 * 0.354851 - Z * 0.255038
97
+ let green = -X * 0.707196 + 1 * 1.655397 + Z * 0.036152
98
+ let blue = X * 0.051713 - 1 * 0.121364 + Z * 1.01153
99
+ if (red > blue && red > green && red > 1) {
100
+ green /= red
101
+ blue /= red
102
+ red = 1
103
+ } else if (green > blue && green > red && green > 1) {
104
+ red /= green
105
+ blue /= green
106
+ green = 1
107
+ } else if (blue > red && blue > green && blue > 1.0) {
108
+ red /= blue
109
+ green /= blue
110
+ blue = 1.0
111
+ }
112
+ red = red <= 0.0031308 ? 12.92 * red : (1.0 + 0.055) * red ** (1.0 / 2.4) - 0.055
113
+ green = green <= 0.0031308 ? 12.92 * green : (1.0 + 0.055) * green ** (1.0 / 2.4) - 0.055
114
+ blue = blue <= 0.0031308 ? 12.92 * blue : (1.0 + 0.055) * blue ** (1.0 / 2.4) - 0.055
115
+ red = Math.abs(Math.round(red * 255))
116
+ green = Math.abs(Math.round(green * 255))
117
+ blue = Math.abs(Math.round(blue * 255))
118
+ if (Number.isNaN(red)) {
119
+ red = 0
120
+ }
121
+ if (Number.isNaN(green)) {
122
+ green = 0
123
+ }
124
+ if (Number.isNaN(blue)) {
125
+ blue = 0
126
+ }
127
+ return [red, green, blue]
128
+ }
129
+
130
+ export {
131
+ hs2rgb,
132
+ rgb2hs,
133
+ rgb2xy,
134
+ xy2rgb,
135
+ }
@@ -0,0 +1,129 @@
1
+ export default {
2
+ defaultConfig: {
3
+ name: 'Wemo',
4
+ mode: 'auto',
5
+ hideConnectionErrors: false,
6
+ disablePlugin: false,
7
+ discoveryInterval: 30,
8
+ pollingInterval: 30,
9
+ upnpInterval: 300,
10
+ disableUPNP: false,
11
+ disableDeviceLogging: false,
12
+ removeByName: '',
13
+ wemoClient: {
14
+ callback_url: '',
15
+ listen_interface: '',
16
+ port: 0,
17
+ discover_opts: {
18
+ interfaces: '',
19
+ explicitSocketBind: true,
20
+ },
21
+ },
22
+ makerTypes: [],
23
+ wemoInsights: [],
24
+ wemoLights: [],
25
+ wemoLinks: [],
26
+ wemoMotions: [],
27
+ wemoOthers: [],
28
+ wemoOutlets: [],
29
+ platform: 'Wemo',
30
+ },
31
+
32
+ defaultValues: {
33
+ adaptiveLightingShift: 0,
34
+ brightnessStep: 1,
35
+ discoveryInterval: 30,
36
+ makerTimer: 20,
37
+ noMotionTimer: 60,
38
+ pollingInterval: 30,
39
+ port: 0,
40
+ showAs: 'default',
41
+ timeDiff: 1,
42
+ transitionTime: 0,
43
+ upnpInterval: 300,
44
+ wattDiff: 1,
45
+ },
46
+
47
+ minValues: {
48
+ adaptiveLightingShift: -1,
49
+ discoveryInterval: 15,
50
+ brightnessStep: 1,
51
+ makerTimer: 1,
52
+ noMotionTimer: 0,
53
+ pollingInterval: 15,
54
+ port: 0,
55
+ timeDiff: 1,
56
+ transitionTime: 0,
57
+ upnpInterval: 60,
58
+ wattDiff: 1,
59
+ },
60
+
61
+ allowed: {
62
+ mode: ['auto', 'semi', 'manual'],
63
+ makerTypes: [
64
+ 'label',
65
+ 'serialNumber',
66
+ 'ignoreDevice',
67
+ 'makerType',
68
+ 'makerTimer',
69
+ 'reversePolarity',
70
+ 'manualIP',
71
+ 'listenerType',
72
+ ],
73
+ wemoInsights: [
74
+ 'label',
75
+ 'serialNumber',
76
+ 'ignoreDevice',
77
+ 'showTodayTC',
78
+ 'wattDiff',
79
+ 'timeDiff',
80
+ 'showAs',
81
+ 'outletInUseTrue',
82
+ 'manualIP',
83
+ 'listenerType',
84
+ ],
85
+ wemoLights: [
86
+ 'label',
87
+ 'serialNumber',
88
+ 'ignoreDevice',
89
+ 'enableColourControl',
90
+ 'adaptiveLightingShift',
91
+ 'brightnessStep',
92
+ 'transitionTime',
93
+ 'manualIP',
94
+ 'listenerType',
95
+ ],
96
+ wemoLinks: ['label', 'serialNumber', 'ignoreDevice', 'manualIP', 'listenerType'],
97
+ wemoMotions: [
98
+ 'label',
99
+ 'serialNumber',
100
+ 'ignoreDevice',
101
+ 'noMotionTimer',
102
+ 'manualIP',
103
+ ],
104
+ wemoOthers: [
105
+ 'label',
106
+ 'serialNumber',
107
+ 'ignoreDevice',
108
+ 'manualIP',
109
+ 'listenerType',
110
+ ],
111
+ wemoOutlets: [
112
+ 'label',
113
+ 'serialNumber',
114
+ 'ignoreDevice',
115
+ 'showAs',
116
+ 'manualIP',
117
+ 'listenerType',
118
+ ],
119
+ listenerType: ['default', 'http'],
120
+ showAs: ['default', 'switch', 'purifier'],
121
+ },
122
+
123
+ portsToScan: [49153, 49152, 49154, 49155, 49151, 49156, 49157, 49158, 49159],
124
+ servicesToSubscribe: [
125
+ 'urn:Belkin:service:basicevent:1',
126
+ 'urn:Belkin:service:insight:1',
127
+ 'urn:Belkin:service:bridge:1',
128
+ ],
129
+ }
@@ -0,0 +1,130 @@
1
+ import { inherits } from 'node:util'
2
+
3
+ export default class {
4
+ constructor(api) {
5
+ this.hapServ = api.hap.Service
6
+ this.hapChar = api.hap.Characteristic
7
+ this.uuids = {
8
+ currentConsumption: 'E863F10D-079E-48FF-8F27-9C2605A29F52',
9
+ totalConsumption: 'E863F10C-079E-48FF-8F27-9C2605A29F52',
10
+ voltage: 'E863F10A-079E-48FF-8F27-9C2605A29F52',
11
+ electricCurrent: 'E863F126-079E-48FF-8F27-9C2605A29F52',
12
+ resetTotal: 'E863F112-079E-48FF-8F27-9C2605A29F52',
13
+ lastActivation: 'E863F11A-079E-48FF-8F27-9C2605A29F52',
14
+ openDuration: 'E863F118-079E-48FF-8F27-9C2605A29F52',
15
+ closedDuration: 'E863F119-079E-48FF-8F27-9C2605A29F52',
16
+ timesOpened: 'E863F129-079E-48FF-8F27-9C2605A29F52',
17
+ }
18
+ const self = this
19
+ this.CurrentConsumption = function CurrentConsumption() {
20
+ self.hapChar.call(this, 'Current Consumption', self.uuids.currentConsumption)
21
+ this.setProps({
22
+ format: api.hap.Formats.UINT16,
23
+ unit: 'W',
24
+ maxValue: 100000,
25
+ minValue: 0,
26
+ minStep: 1,
27
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
28
+ })
29
+ this.value = this.getDefaultValue()
30
+ }
31
+ this.TotalConsumption = function TotalConsumption() {
32
+ self.hapChar.call(this, 'Total Consumption', self.uuids.totalConsumption)
33
+ this.setProps({
34
+ format: api.hap.Formats.FLOAT,
35
+ unit: 'kWh',
36
+ maxValue: 100000000000,
37
+ minValue: 0,
38
+ minStep: 0.01,
39
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
40
+ })
41
+ this.value = this.getDefaultValue()
42
+ }
43
+ this.Voltage = function Voltage() {
44
+ self.hapChar.call(this, 'Voltage', self.uuids.voltage)
45
+ this.setProps({
46
+ format: api.hap.Formats.FLOAT,
47
+ unit: 'V',
48
+ maxValue: 100000000000,
49
+ minValue: 0,
50
+ minStep: 1,
51
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
52
+ })
53
+ this.value = this.getDefaultValue()
54
+ }
55
+ this.ElectricCurrent = function ElectricCurrent() {
56
+ self.hapChar.call(this, 'Electric Current', self.uuids.electricCurrent)
57
+ this.setProps({
58
+ format: api.hap.Formats.FLOAT,
59
+ unit: 'A',
60
+ maxValue: 100000000000,
61
+ minValue: 0,
62
+ minStep: 0.1,
63
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
64
+ })
65
+ this.value = this.getDefaultValue()
66
+ }
67
+ this.ResetTotal = function ResetTotal() {
68
+ self.hapChar.call(this, 'Reset Total', self.uuids.resetTotal)
69
+ this.setProps({
70
+ format: api.hap.Formats.UINT32,
71
+ unit: api.hap.Units.seconds,
72
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY, api.hap.Perms.PAIRED_WRITE],
73
+ })
74
+ this.value = this.getDefaultValue()
75
+ }
76
+ this.LastActivation = function LastActivation() {
77
+ self.hapChar.call(this, 'Last Activation', self.uuids.lastActivation)
78
+ this.setProps({
79
+ format: api.hap.Formats.UINT32,
80
+ unit: api.hap.Units.SECONDS,
81
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
82
+ })
83
+ this.value = this.getDefaultValue()
84
+ }
85
+ this.OpenDuration = function OpenDuration() {
86
+ self.hapChar.call(this, 'Open Duration', self.uuids.openDuration)
87
+ this.setProps({
88
+ format: api.hap.Formats.UINT32,
89
+ unit: api.hap.Units.SECONDS,
90
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY, api.hap.Perms.PAIRED_WRITE],
91
+ })
92
+ this.value = this.getDefaultValue()
93
+ }
94
+ this.ClosedDuration = function ClosedDuration() {
95
+ self.hapChar.call(this, 'Closed Duration', self.uuids.closedDuration)
96
+ this.setProps({
97
+ format: api.hap.Formats.UINT32,
98
+ unit: api.hap.Units.SECONDS,
99
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY, api.hap.Perms.PAIRED_WRITE],
100
+ })
101
+ this.value = this.getDefaultValue()
102
+ }
103
+ this.TimesOpened = function TimesOpened() {
104
+ self.hapChar.call(this, 'Times Opened', self.uuids.timesOpened)
105
+ this.setProps({
106
+ format: api.hap.Formats.UINT32,
107
+ perms: [api.hap.Perms.PAIRED_READ, api.hap.Perms.NOTIFY],
108
+ })
109
+ this.value = this.getDefaultValue()
110
+ }
111
+ inherits(this.CurrentConsumption, this.hapChar)
112
+ inherits(this.TotalConsumption, this.hapChar)
113
+ inherits(this.Voltage, this.hapChar)
114
+ inherits(this.ElectricCurrent, this.hapChar)
115
+ inherits(this.LastActivation, this.hapChar)
116
+ inherits(this.ResetTotal, this.hapChar)
117
+ inherits(this.OpenDuration, this.hapChar)
118
+ inherits(this.ClosedDuration, this.hapChar)
119
+ inherits(this.TimesOpened, this.hapChar)
120
+ this.CurrentConsumption.UUID = this.uuids.currentConsumption
121
+ this.TotalConsumption.UUID = this.uuids.totalConsumption
122
+ this.Voltage.UUID = this.uuids.voltage
123
+ this.ElectricCurrent.UUID = this.uuids.electricCurrent
124
+ this.LastActivation.UUID = this.uuids.lastActivation
125
+ this.ResetTotal.UUID = this.uuids.resetTotal
126
+ this.OpenDuration.UUID = this.uuids.openDuration
127
+ this.ClosedDuration.UUID = this.uuids.closedDuration
128
+ this.TimesOpened.UUID = this.uuids.timesOpened
129
+ }
130
+ }
@@ -0,0 +1,52 @@
1
+ function decodeXML(input) {
2
+ return input
3
+ .replace(/&lt;/g, '<')
4
+ .replace(/&gt;/g, '>')
5
+ .replace(/&quot;/g, '"')
6
+ .replace(/&#039;/g, '\'')
7
+ .replace(/&amp;/g, '&')
8
+ }
9
+
10
+ function generateRandomString(length) {
11
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
12
+ let nonce = ''
13
+ while (nonce.length < length) {
14
+ nonce += chars.charAt(Math.floor(Math.random() * chars.length))
15
+ }
16
+ return nonce
17
+ }
18
+
19
+ const hasProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
20
+
21
+ function parseError(err, hideStack = []) {
22
+ let toReturn = err.message
23
+ if (err?.stack?.length > 0 && !hideStack.includes(err.message)) {
24
+ const stack = err.stack.split('\n')
25
+ if (stack[1]) {
26
+ toReturn += stack[1].replace(' ', '')
27
+ }
28
+ }
29
+ return toReturn
30
+ }
31
+
32
+ function parseSerialNumber(input) {
33
+ return input
34
+ .toString()
35
+ .replace(/[\s'"]+/g, '')
36
+ .toUpperCase()
37
+ }
38
+
39
+ function sleep(ms) {
40
+ return new Promise((resolve) => {
41
+ setTimeout(resolve, ms)
42
+ })
43
+ }
44
+
45
+ export {
46
+ decodeXML,
47
+ generateRandomString,
48
+ hasProperty,
49
+ parseError,
50
+ parseSerialNumber,
51
+ sleep,
52
+ }
@@ -0,0 +1,125 @@
1
+ export default {
2
+ accNotFound: 'accessory not found',
3
+ accNotReady: 'has not been discovered yet so commands will fail',
4
+ alDisabled: 'adaptive lighting disabled due to significant colour change',
5
+ awaiting: 'The following devices have still not been initially found',
6
+ beta: 'You are using a beta version of the plugin - you will experience more logging than normal',
7
+ brand: 'Belkin Wemo',
8
+ brightnessFail: 'could not obtain updated brightness as',
9
+ cantCtl: 'sending update failed as',
10
+ cantUpd: 'receiving update failed as',
11
+ cfgDef: 'is not a valid number so using default of',
12
+ cfgDup: 'will be ignored since another entry with this ID already exists',
13
+ cfgIgn: 'is not configured correctly so ignoring',
14
+ cfgIgnItem: 'has an invalid entry which will be ignored',
15
+ cfgItem: 'Config entry',
16
+ cfgLow: 'is set too low so increasing to',
17
+ cfgRmv: 'is unused and can be removed',
18
+ cfgQts: 'should not have quotes around its entry',
19
+ complete: '✓ Setup complete',
20
+ connError: 'connection error',
21
+ curAir: 'current air quality',
22
+ curBright: 'current brightness',
23
+ curCCT: 'current cct',
24
+ curColour: 'current colour',
25
+ curCons: 'current consumption',
26
+ curCont: 'current contact',
27
+ curFilter: 'current filter level',
28
+ curHumi: 'current humidity',
29
+ curIon: 'current ionizer',
30
+ curOIU: 'current outlet-in-use',
31
+ curMode: 'current mode',
32
+ curState: 'current state',
33
+ curTemp: 'current temperature',
34
+ curTimer: 'current timer',
35
+ detectedNo: 'not detected',
36
+ detectedYes: 'detected',
37
+ devAdd: 'has been added to Homebridge',
38
+ devInitOpts: 'initialising with options',
39
+ devNotAdd: 'could not be added to Homebridge as',
40
+ devNotConf: 'could not be configured as',
41
+ devNotInit: 'could not be initialised as',
42
+ devNotRemove: 'could not be removed from Homebridge as',
43
+ devOffline: 'appears to be offline',
44
+ devRemove: 'has been removed from Homebridge',
45
+ disabling: 'Disabling plugin',
46
+ hbVersionFail: 'Your version of Homebridge is too low - please update to v1.6',
47
+ identify: 'identify button pressed',
48
+ incFail: 'failed to process incoming message as',
49
+ incKnown: 'incoming notification',
50
+ incUnknown: 'incoming notification from unknown accessory',
51
+ initSer: 'initialised with s/n',
52
+ initMac: 'and ip/port',
53
+ initialised: 'Plugin initialised. Setting up accessories...',
54
+ initialising: 'Initialising plugin',
55
+ insCons: 'consumption',
56
+ insOnTime: 'today ontime',
57
+ insTC: 'total consumption',
58
+ httpFail: 'http error (will be re-attempted)',
59
+ httpGood: 'http has been established',
60
+ labelAuto: 'auto',
61
+ labelClosed: 'closed',
62
+ labelClosing: 'closing',
63
+ labelEco: 'eco',
64
+ labelExc: 'excellent',
65
+ labelFair: 'fair',
66
+ labelFP: 'frost-protect',
67
+ labelHigh: 'high',
68
+ labelLow: 'low',
69
+ labelMax: 'max',
70
+ labelMed: 'med',
71
+ labelMin: 'min',
72
+ labelPoor: 'poor',
73
+ labelOff: 'off',
74
+ labelOpen: 'open',
75
+ labelOpening: 'opening',
76
+ labelStopped: 'stopped',
77
+ labelWarm: 'warm',
78
+ listenerClosed: 'Listener server gracefully closed',
79
+ listenerError: 'Listener server error',
80
+ listenerPort: 'Listener server port',
81
+ makerClosed: 'is already closed so ignoring command',
82
+ makerClosing: 'is already closing so ignoring command',
83
+ makerNeedMMode: 'must be set to momentary mode to work as a garage door',
84
+ makerOpen: 'is already open so ignoring command',
85
+ makerOpening: 'is already opening so ignoring command',
86
+ makerTrigExt: 'triggered externally',
87
+ modelLED: 'LED Bulb (Via Link)',
88
+ motionNo: 'clear',
89
+ motionSensor: 'motion sensor',
90
+ motionYes: 'motion detected',
91
+ noInterface: 'Unable to find interface',
92
+ noPort: 'could not find correct port for device',
93
+ noService: 'device does not have this service',
94
+ noServices: 'device does not have any upnp services',
95
+ noSockets: 'NodeSSDP error [no sockets], if this continues to happen try restarting Homebridge',
96
+ notConfigured: 'Plugin has not been configured',
97
+ proEr: 'could not be processed as',
98
+ purifyNo: 'not purifying',
99
+ purifyYes: 'purifying',
100
+ rduErr: 'http polling failed as',
101
+ recUpd: 'receiving update',
102
+ repError: 'reported error',
103
+ senUpd: 'sending update',
104
+ ssdpFail: 'SSDP search failed as',
105
+ ssdpStopped: 'SSDP client gracefully stopped',
106
+ stoppedSubs: 'existing upnp subscriptions have been stopped',
107
+ subError: 'subscription error, retrying in 10 seconds',
108
+ subInit: 'initial subscription for service',
109
+ subPending: 'subscription still pending',
110
+ subscribeError: 'could not subscribe as',
111
+ tarHumi: 'target humidity',
112
+ tarState: 'target state',
113
+ tarTemp: 'target temperature',
114
+ timeout: 'a connection timeout occurred',
115
+ timeoutUnreach: 'a connection timeout occurred (EHOSTUNREACH)',
116
+ timerComplete: 'timer complete',
117
+ timerStarted: 'timer started',
118
+ timerStopped: 'timer stopped',
119
+ unsubFail: 'unsubscribe failed',
120
+ unsupported: 'is unsupported but feel free to create a GitHub issue',
121
+ upnpFail: 'upnp error (will be re-attempted)',
122
+ upnpGood: 'upnp has been established',
123
+ viaAL: 'via adaptive lighting',
124
+ welcome: 'This plugin has been made with ♥ by bwp91, please consider a ☆ on GitHub if you are finding it useful!',
125
+ }
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@homebridge-plugins/homebridge-wemo",
3
+ "alias": "Wemo",
4
+ "type": "module",
5
+ "version": "7.0.0",
6
+ "description": "Homebridge plugin to integrate Wemo devices into HomeKit.",
7
+ "author": {
8
+ "name": "bwp91",
9
+ "email": "bwp91@icloud.com"
10
+ },
11
+ "license": "MIT",
12
+ "funding": [
13
+ {
14
+ "type": "github",
15
+ "url": "https://github.com/sponsors/bwp91"
16
+ },
17
+ {
18
+ "type": "kofi",
19
+ "url": "https://ko-fi.com/bwp91"
20
+ },
21
+ {
22
+ "type": "patreon",
23
+ "url": "https://www.patreon.com/bwp91"
24
+ },
25
+ {
26
+ "type": "paypal",
27
+ "url": "https://www.paypal.me/BenPotter"
28
+ }
29
+ ],
30
+ "homepage": "https://github.com/homebridge-plugins/homebridge-wemo",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/homebridge-plugins/homebridge-wemo.git"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/homebridge-plugins/homebridge-wemo/issues"
37
+ },
38
+ "keywords": [
39
+ "homebridge",
40
+ "homebridge-plugin",
41
+ "hoobs",
42
+ "hoobs-plugin",
43
+ "homekit",
44
+ "siri",
45
+ "wemo",
46
+ "belkin"
47
+ ],
48
+ "main": "lib/index.js",
49
+ "engines": {
50
+ "homebridge": "^1.6.0 || ^2.0.0-beta.0",
51
+ "node": "^18.20.7 || ^20.19.0 || ^22.14.0"
52
+ },
53
+ "scripts": {
54
+ "lint": "eslint . --fix",
55
+ "rebuild": "rm -rf package-lock.json && rm -rf node_modules && npm install"
56
+ },
57
+ "dependencies": {
58
+ "@homebridge/plugin-ui-utils": "^2.0.1",
59
+ "axios": "^1.8.4",
60
+ "ip": "^2.0.1",
61
+ "node-ssdp": "^4.0.1",
62
+ "p-queue": "^8.1.0",
63
+ "xml2js": "^0.6.2",
64
+ "xmlbuilder": "^15.1.1"
65
+ },
66
+ "devDependencies": {
67
+ "@antfu/eslint-config": "^4.10.2",
68
+ "eslint": "^9.23.0"
69
+ }
70
+ }