@sebbo2002/pyatv-mqtt-bridge 8.1.1-develop.1 → 8.1.1-develop.2
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/README.md +7 -7
- package/dist/bin/cli.cjs.map +1 -1
- package/dist/bin/cli.js +1 -1
- package/dist/bin/cli.js.map +1 -1
- package/dist/{chunk-UHWFNSNC.js → chunk-WNLLGDC3.js} +1 -1
- package/dist/chunk-WNLLGDC3.js.map +1 -0
- package/dist/lib/index.cjs.map +1 -1
- package/dist/lib/index.d.cts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.js +1 -1
- package/package.json +72 -68
- package/dist/chunk-UHWFNSNC.js.map +0 -1
package/README.md
CHANGED
|
@@ -44,13 +44,13 @@ You can also use the provided Docker container to run `pyatv-mqtt-bridge` within
|
|
|
44
44
|
|
|
45
45
|
3. Start pyatv
|
|
46
46
|
|
|
47
|
-
-
|
|
47
|
+
- By command line :
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
50
|
pyatv-mqtt-bridge /home/eve/pyatv-mqtt-bridge.json
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
-
|
|
53
|
+
- or use the Docker container :
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
56
|
docker run -d --restart=always --name=pyatv-mqtt-bridge \
|
|
@@ -58,7 +58,7 @@ docker run -d --restart=always --name=pyatv-mqtt-bridge \
|
|
|
58
58
|
sebbo2002/pyatv-mqtt-bridge
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
-
|
|
61
|
+
- or just run the Docker container from the [`docker-compose.yml`](docker-compose.yml) file with :
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
64
|
docker-compose up -d
|
|
@@ -76,13 +76,13 @@ pip3 install pyatv
|
|
|
76
76
|
|
|
77
77
|
You just need to add the `--debug` option.
|
|
78
78
|
|
|
79
|
-
-
|
|
79
|
+
- In command line :
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
82
|
pyatv-mqtt-bridge --debug /home/eve/pyatv-mqtt-bridge.json
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
-
-
|
|
85
|
+
- or while using the Docker container :
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
88
|
docker run -d --restart=always --name=pyatv-mqtt-bridge \
|
|
@@ -91,7 +91,7 @@ docker run -d --restart=always --name=pyatv-mqtt-bridge \
|
|
|
91
91
|
pyatv-mqtt-bridge --debug /app/config.json
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
-
|
|
94
|
+
- or while using the [`docker-compose.yml`](docker-compose.yml) file :
|
|
95
95
|
|
|
96
96
|
```yaml
|
|
97
97
|
command: pyatv-mqtt-bridge --debug /app/config.json
|
|
@@ -107,7 +107,7 @@ command: pyatv-mqtt-bridge --debug /app/config.json
|
|
|
107
107
|
|
|
108
108
|
To execute a command send any message to the topic `$device/$command`. `$device` is the configured topic of the device
|
|
109
109
|
and `$command` is a command from [this list](https://github.com/sebbo2002/node-pyatv/blob/develop/src/lib/types.ts#L49).
|
|
110
|
-
Example: `/home/living/appletv/menu`. To launch an app, send it's unique id (e.g. `com.google.ios.youtube`) to the topic
|
|
110
|
+
Example: `/home/living/appletv/menu`. To launch an app, send it's unique id (e.g. `com.google.ios.youtube`) to the topic
|
|
111
111
|
`$device/launch`
|
|
112
112
|
|
|
113
113
|
#### How to check the current Apple TV power state and other status information ?
|
package/dist/bin/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/cli.ts","../../src/lib/index.ts"],"sourcesContent":["#!/usr/bin/env node\n'use strict';\n\nimport {existsSync, readFileSync} from 'fs';\nimport {resolve} from 'path';\nimport PyAtvMqttBridge from '../lib/index.js';\nimport {type LogParam} from '../lib/types.js';\n\nconsole.log('# pyatv-mqtt-bridge');\nconsole.log('----------------------------');\n\nconst debug = process.argv.indexOf('--debug') > -1;\nconst configPath = resolve(process.cwd(), process.argv[process.argv.length - 1]);\nif (!existsSync(configPath)) {\n console.log('Usage: pyatv-mqtt-bridge [--debug] ~/pyatv-mqtt-bridge-config.json');\n process.exit(1);\n}\n\nlet config;\ntry {\n config = JSON.parse(readFileSync(configPath, 'utf8'));\n}\ncatch (err) {\n console.log('Unable to parse configuration file:');\n console.log(err);\n console.log('\\nHave you removed the comments?\\n');\n process.exit(1);\n}\n\ntry {\n if (debug) {\n Object.assign(config, {\n log: (msg: LogParam) => {\n let string = `[${msg.level}]`;\n if (msg.host) {\n string += `[${msg.host}]`;\n }\n string += ' ';\n if (msg.message) {\n string += msg.message;\n }\n if (msg.message && msg.error) {\n string += ': ';\n }\n if (msg.error && msg.error.stack) {\n string += msg.error.stack;\n }\n if (msg.error) {\n string += msg.error.toString();\n }\n\n console.log(string);\n }\n });\n }\n\n new PyAtvMqttBridge(config);\n} catch (err) {\n console.log('Unable to start bridge:');\n console.log(err);\n}\n","'use strict';\n\nimport type {Config, ConfigDevice, LogParam} from './types.js';\nimport {connect, MqttClient} from 'mqtt';\nimport pyatv, {NodePyATVDeviceEvent, NodePyATVKeys} from '@sebbo2002/node-pyatv';\n\nexport default class PyAtvMqttBridge {\n private mqttClient: MqttClient | null = null;\n private readonly options: Config;\n private readonly teardown: Array<() => Promise<void>> = [];\n\n constructor(options: Config) {\n if (!options.broker) {\n throw new Error('options.broker is not set!');\n }\n if (!Array.isArray(options.devices) || !options.devices.length) {\n throw new Error('options.devices is not set!');\n }\n if (options.devices.find(d => typeof d.topic !== 'string')) {\n throw new Error('options.devices.topic is not set!');\n }\n if (options.devices.find(d => typeof d.host !== 'string')) {\n throw new Error('options.devices.host is not set!');\n }\n if (options.devices.find(d => typeof d.name !== 'string')) {\n throw new Error('options.devices.name is not set!');\n }\n\n this.options = options;\n this.teardown = [];\n\n this.start().catch(err => {\n this.log({\n level: 'error',\n host: null,\n message: 'Unable to start bridge',\n error: err\n });\n });\n }\n\n private log(msg: LogParam) {\n if (this.options.log) {\n try {\n this.options.log.apply(this, [msg]);\n } catch (err) {\n console.log('Unable to call custom log function:');\n console.log(err);\n }\n }\n }\n\n private async start() {\n const errorListener = (error: Error) => this.log({\n level: 'error',\n host: null,\n message: 'MQTT error',\n error\n });\n\n // this.mqttClient = connect(this.options.broker);\n if (typeof this.options.broker === 'string') {\n this.mqttClient = connect(this.options.broker);\n } else {\n this.mqttClient = connect(this.options.broker);\n }\n\n this.mqttClient.on('error', errorListener);\n this.teardown.unshift(async () => {\n if (this.mqttClient) {\n this.mqttClient.off('error', errorListener);\n await new Promise(resolve => {\n if (this.mqttClient) {\n this.mqttClient.end(false, () => resolve(undefined));\n }\n });\n }\n });\n\n await Promise.all(\n this.options.devices.map(device => this.startDevice(device))\n );\n }\n\n private async startDevice(device: ConfigDevice) {\n this.log({\n level: 'info',\n host: device.host,\n message: 'Setup device…'\n });\n\n const atv = pyatv.device(Object.assign({}, device, {\n debug: (message: string) => this.log({\n level: 'info',\n host: device.host,\n message\n })\n }));\n\n\n /* MQTT <-- PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.publish(device.topic + '/host', device.host, {retain: true});\n this.mqttClient.publish(device.topic + '/name', device.name, {retain: true});\n this.mqttClient.publish(device.topic + '/id', device.id || '', {retain: true});\n }\n\n const updateListener = (event: NodePyATVDeviceEvent | Error) => {\n if(event instanceof NodePyATVDeviceEvent) {\n this.log({\n level: 'info',\n host: device.host,\n message: JSON.stringify(event)\n });\n\n if (this.mqttClient) {\n const value = event.value === null ? '' : String(event.value);\n this.mqttClient.publish(device.topic + '/' + event.key, value, {retain: true});\n }\n }\n };\n const errorListener = (error: Error | NodePyATVDeviceEvent) => {\n if (error instanceof Error) {\n this.log({\n level: 'error',\n host: device.host,\n message: 'Push Error',\n error\n });\n }\n };\n\n atv.on('update', updateListener);\n atv.on('error', errorListener);\n this.teardown.unshift(async () => {\n atv.off('update', updateListener);\n atv.off('error', errorListener);\n });\n\n\n /* MQTT --> PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.subscribe(device.topic + '/+');\n this.teardown.unshift(() => {\n return new Promise((resolve, reject) => {\n if(this.mqttClient) {\n this.mqttClient.unsubscribe(device.topic + '/+', error => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n }\n });\n });\n\n this.mqttClient.on('message', (topic, body) => {\n if (device.topic + '/launch' === topic) {\n const id = body.toString();\n atv.launchApp(id).catch(error => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to launch app \"${id}\"`,\n error\n });\n });\n return;\n }\n\n const key = Object\n .keys(NodePyATVKeys)\n .find(key => device.topic + '/' + key === topic) as NodePyATVKeys | undefined;\n\n if(key) {\n atv.pressKey(key).catch(error => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to press key \"${key}\"`,\n error\n });\n });\n }\n });\n }\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.teardown);\n }\n}\n"],"mappings":"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","names":["import_fs","import_path","import_mqtt","import_node_pyatv","PyAtvMqttBridge","options","d","err","msg","errorListener","error","resolve","device","atv","pyatv","message","updateListener","event","value","reject","topic","body","id","key","debug","configPath","config","err","msg","string","PyAtvMqttBridge"]}
|
|
1
|
+
{"version":3,"sources":["../../src/bin/cli.ts","../../src/lib/index.ts"],"sourcesContent":["#!/usr/bin/env node\n'use strict';\n\nimport { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'path';\nimport PyAtvMqttBridge from '../lib/index.js';\nimport { type LogParam } from '../lib/types.js';\n\nconsole.log('# pyatv-mqtt-bridge');\nconsole.log('----------------------------');\n\nconst debug = process.argv.indexOf('--debug') > -1;\nconst configPath = resolve(\n process.cwd(),\n process.argv[process.argv.length - 1],\n);\nif (!existsSync(configPath)) {\n console.log(\n 'Usage: pyatv-mqtt-bridge [--debug] ~/pyatv-mqtt-bridge-config.json',\n );\n process.exit(1);\n}\n\nlet config;\ntry {\n config = JSON.parse(readFileSync(configPath, 'utf8'));\n} catch (err) {\n console.log('Unable to parse configuration file:');\n console.log(err);\n console.log('\\nHave you removed the comments?\\n');\n process.exit(1);\n}\n\ntry {\n if (debug) {\n Object.assign(config, {\n log: (msg: LogParam) => {\n let string = `[${msg.level}]`;\n if (msg.host) {\n string += `[${msg.host}]`;\n }\n string += ' ';\n if (msg.message) {\n string += msg.message;\n }\n if (msg.message && msg.error) {\n string += ': ';\n }\n if (msg.error && msg.error.stack) {\n string += msg.error.stack;\n }\n if (msg.error) {\n string += msg.error.toString();\n }\n\n console.log(string);\n },\n });\n }\n\n new PyAtvMqttBridge(config);\n} catch (err) {\n console.log('Unable to start bridge:');\n console.log(err);\n}\n","'use strict';\n\nimport type { Config, ConfigDevice, LogParam } from './types.js';\nimport { connect, MqttClient } from 'mqtt';\nimport pyatv, {\n NodePyATVDeviceEvent,\n NodePyATVKeys,\n} from '@sebbo2002/node-pyatv';\n\nexport default class PyAtvMqttBridge {\n private mqttClient: MqttClient | null = null;\n private readonly options: Config;\n private readonly teardown: Array<() => Promise<void>> = [];\n\n constructor(options: Config) {\n if (!options.broker) {\n throw new Error('options.broker is not set!');\n }\n if (!Array.isArray(options.devices) || !options.devices.length) {\n throw new Error('options.devices is not set!');\n }\n if (options.devices.find((d) => typeof d.topic !== 'string')) {\n throw new Error('options.devices.topic is not set!');\n }\n if (options.devices.find((d) => typeof d.host !== 'string')) {\n throw new Error('options.devices.host is not set!');\n }\n if (options.devices.find((d) => typeof d.name !== 'string')) {\n throw new Error('options.devices.name is not set!');\n }\n\n this.options = options;\n this.teardown = [];\n\n this.start().catch((err) => {\n this.log({\n level: 'error',\n host: null,\n message: 'Unable to start bridge',\n error: err,\n });\n });\n }\n\n private log(msg: LogParam) {\n if (this.options.log) {\n try {\n this.options.log.apply(this, [msg]);\n } catch (err) {\n console.log('Unable to call custom log function:');\n console.log(err);\n }\n }\n }\n\n private async start() {\n const errorListener = (error: Error) =>\n this.log({\n level: 'error',\n host: null,\n message: 'MQTT error',\n error,\n });\n\n // this.mqttClient = connect(this.options.broker);\n if (typeof this.options.broker === 'string') {\n this.mqttClient = connect(this.options.broker);\n } else {\n this.mqttClient = connect(this.options.broker);\n }\n\n this.mqttClient.on('error', errorListener);\n this.teardown.unshift(async () => {\n if (this.mqttClient) {\n this.mqttClient.off('error', errorListener);\n await new Promise((resolve) => {\n if (this.mqttClient) {\n this.mqttClient.end(false, () => resolve(undefined));\n }\n });\n }\n });\n\n await Promise.all(\n this.options.devices.map((device) => this.startDevice(device)),\n );\n }\n\n private async startDevice(device: ConfigDevice) {\n this.log({\n level: 'info',\n host: device.host,\n message: 'Setup device…',\n });\n\n const atv = pyatv.device(\n Object.assign({}, device, {\n debug: (message: string) =>\n this.log({\n level: 'info',\n host: device.host,\n message,\n }),\n }),\n );\n\n /* MQTT <-- PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.publish(device.topic + '/host', device.host, {\n retain: true,\n });\n this.mqttClient.publish(device.topic + '/name', device.name, {\n retain: true,\n });\n this.mqttClient.publish(device.topic + '/id', device.id || '', {\n retain: true,\n });\n }\n\n const updateListener = (event: NodePyATVDeviceEvent | Error) => {\n if (event instanceof NodePyATVDeviceEvent) {\n this.log({\n level: 'info',\n host: device.host,\n message: JSON.stringify(event),\n });\n\n if (this.mqttClient) {\n const value =\n event.value === null ? '' : String(event.value);\n this.mqttClient.publish(\n device.topic + '/' + event.key,\n value,\n { retain: true },\n );\n }\n }\n };\n const errorListener = (error: Error | NodePyATVDeviceEvent) => {\n if (error instanceof Error) {\n this.log({\n level: 'error',\n host: device.host,\n message: 'Push Error',\n error,\n });\n }\n };\n\n atv.on('update', updateListener);\n atv.on('error', errorListener);\n this.teardown.unshift(async () => {\n atv.off('update', updateListener);\n atv.off('error', errorListener);\n });\n\n /* MQTT --> PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.subscribe(device.topic + '/+');\n this.teardown.unshift(() => {\n return new Promise((resolve, reject) => {\n if (this.mqttClient) {\n this.mqttClient.unsubscribe(\n device.topic + '/+',\n (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n },\n );\n }\n });\n });\n\n this.mqttClient.on('message', (topic, body) => {\n if (device.topic + '/launch' === topic) {\n const id = body.toString();\n atv.launchApp(id).catch((error) => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to launch app \"${id}\"`,\n error,\n });\n });\n return;\n }\n\n const key = Object.keys(NodePyATVKeys).find(\n (key) => device.topic + '/' + key === topic,\n ) as NodePyATVKeys | undefined;\n\n if (key) {\n atv.pressKey(key).catch((error) => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to press key \"${key}\"`,\n error,\n });\n });\n }\n });\n }\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.teardown);\n }\n}\n"],"mappings":"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","names":["import_fs","import_path","import_mqtt","import_node_pyatv","PyAtvMqttBridge","options","d","err","msg","errorListener","error","resolve","device","atv","pyatv","message","updateListener","event","value","reject","topic","body","id","key","debug","configPath","config","err","msg","string","PyAtvMqttBridge"]}
|
package/dist/bin/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{a as t}from"../chunk-
|
|
2
|
+
import{a as t}from"../chunk-WNLLGDC3.js";import{existsSync as c,readFileSync as n}from"fs";import{resolve as i}from"path";console.log("# pyatv-mqtt-bridge");console.log("----------------------------");var l=process.argv.indexOf("--debug")>-1,s=i(process.cwd(),process.argv[process.argv.length-1]);c(s)||(console.log("Usage: pyatv-mqtt-bridge [--debug] ~/pyatv-mqtt-bridge-config.json"),process.exit(1));var r;try{r=JSON.parse(n(s,"utf8"))}catch(o){console.log("Unable to parse configuration file:"),console.log(o),console.log(`
|
|
3
3
|
Have you removed the comments?
|
|
4
4
|
`),process.exit(1)}try{l&&Object.assign(r,{log:o=>{let e=`[${o.level}]`;o.host&&(e+=`[${o.host}]`),e+=" ",o.message&&(e+=o.message),o.message&&o.error&&(e+=": "),o.error&&o.error.stack&&(e+=o.error.stack),o.error&&(e+=o.error.toString()),console.log(e)}}),new t(r)}catch(o){console.log("Unable to start bridge:"),console.log(o)}
|
|
5
5
|
//# sourceMappingURL=cli.js.map
|
package/dist/bin/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/bin/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n'use strict';\n\nimport {existsSync, readFileSync} from 'fs';\nimport {resolve} from 'path';\nimport PyAtvMqttBridge from '../lib/index.js';\nimport {type LogParam} from '../lib/types.js';\n\nconsole.log('# pyatv-mqtt-bridge');\nconsole.log('----------------------------');\n\nconst debug = process.argv.indexOf('--debug') > -1;\nconst configPath = resolve(process.cwd()
|
|
1
|
+
{"version":3,"sources":["../../src/bin/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n'use strict';\n\nimport { existsSync, readFileSync } from 'fs';\nimport { resolve } from 'path';\nimport PyAtvMqttBridge from '../lib/index.js';\nimport { type LogParam } from '../lib/types.js';\n\nconsole.log('# pyatv-mqtt-bridge');\nconsole.log('----------------------------');\n\nconst debug = process.argv.indexOf('--debug') > -1;\nconst configPath = resolve(\n process.cwd(),\n process.argv[process.argv.length - 1],\n);\nif (!existsSync(configPath)) {\n console.log(\n 'Usage: pyatv-mqtt-bridge [--debug] ~/pyatv-mqtt-bridge-config.json',\n );\n process.exit(1);\n}\n\nlet config;\ntry {\n config = JSON.parse(readFileSync(configPath, 'utf8'));\n} catch (err) {\n console.log('Unable to parse configuration file:');\n console.log(err);\n console.log('\\nHave you removed the comments?\\n');\n process.exit(1);\n}\n\ntry {\n if (debug) {\n Object.assign(config, {\n log: (msg: LogParam) => {\n let string = `[${msg.level}]`;\n if (msg.host) {\n string += `[${msg.host}]`;\n }\n string += ' ';\n if (msg.message) {\n string += msg.message;\n }\n if (msg.message && msg.error) {\n string += ': ';\n }\n if (msg.error && msg.error.stack) {\n string += msg.error.stack;\n }\n if (msg.error) {\n string += msg.error.toString();\n }\n\n console.log(string);\n },\n });\n }\n\n new PyAtvMqttBridge(config);\n} catch (err) {\n console.log('Unable to start bridge:');\n console.log(err);\n}\n"],"mappings":";yCAGA,OAAS,cAAAA,EAAY,gBAAAC,MAAoB,KACzC,OAAS,WAAAC,MAAe,OAIxB,QAAQ,IAAI,qBAAqB,EACjC,QAAQ,IAAI,8BAA8B,EAE1C,IAAMC,EAAQ,QAAQ,KAAK,QAAQ,SAAS,EAAI,GAC1CC,EAAaC,EACf,QAAQ,IAAI,EACZ,QAAQ,KAAK,QAAQ,KAAK,OAAS,CAAC,CACxC,EACKC,EAAWF,CAAU,IACtB,QAAQ,IACJ,oEACJ,EACA,QAAQ,KAAK,CAAC,GAGlB,IAAIG,EACJ,GAAI,CACAA,EAAS,KAAK,MAAMC,EAAaJ,EAAY,MAAM,CAAC,CACxD,OAASK,EAAK,CACV,QAAQ,IAAI,qCAAqC,EACjD,QAAQ,IAAIA,CAAG,EACf,QAAQ,IAAI;AAAA;AAAA,CAAoC,EAChD,QAAQ,KAAK,CAAC,CAClB,CAEA,GAAI,CACIN,GACA,OAAO,OAAOI,EAAQ,CAClB,IAAMG,GAAkB,CACpB,IAAIC,EAAS,IAAID,EAAI,KAAK,IACtBA,EAAI,OACJC,GAAU,IAAID,EAAI,IAAI,KAE1BC,GAAU,IACND,EAAI,UACJC,GAAUD,EAAI,SAEdA,EAAI,SAAWA,EAAI,QACnBC,GAAU,MAEVD,EAAI,OAASA,EAAI,MAAM,QACvBC,GAAUD,EAAI,MAAM,OAEpBA,EAAI,QACJC,GAAUD,EAAI,MAAM,SAAS,GAGjC,QAAQ,IAAIC,CAAM,CACtB,CACJ,CAAC,EAGL,IAAIC,EAAgBL,CAAM,CAC9B,OAASE,EAAK,CACV,QAAQ,IAAI,yBAAyB,EACrC,QAAQ,IAAIA,CAAG,CACnB","names":["existsSync","readFileSync","resolve","debug","configPath","resolve","existsSync","config","readFileSync","err","msg","string","PyAtvMqttBridge"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{connect as h}from"mqtt";import c,{NodePyATVDeviceEvent as p,NodePyATVKeys as m}from"@sebbo2002/node-pyatv";var n=class{mqttClient=null;options;teardown=[];constructor(t){if(!t.broker)throw new Error("options.broker is not set!");if(!Array.isArray(t.devices)||!t.devices.length)throw new Error("options.devices is not set!");if(t.devices.find(e=>typeof e.topic!="string"))throw new Error("options.devices.topic is not set!");if(t.devices.find(e=>typeof e.host!="string"))throw new Error("options.devices.host is not set!");if(t.devices.find(e=>typeof e.name!="string"))throw new Error("options.devices.name is not set!");this.options=t,this.teardown=[],this.start().catch(e=>{this.log({level:"error",host:null,message:"Unable to start bridge",error:e})})}log(t){if(this.options.log)try{this.options.log.apply(this,[t])}catch(e){console.log("Unable to call custom log function:"),console.log(e)}}async start(){let t=e=>this.log({level:"error",host:null,message:"MQTT error",error:e});typeof this.options.broker=="string"?this.mqttClient=h(this.options.broker):this.mqttClient=h(this.options.broker),this.mqttClient.on("error",t),this.teardown.unshift(async()=>{this.mqttClient&&(this.mqttClient.off("error",t),await new Promise(e=>{this.mqttClient&&this.mqttClient.end(!1,()=>e(void 0))}))}),await Promise.all(this.options.devices.map(e=>this.startDevice(e)))}async startDevice(t){this.log({level:"info",host:t.host,message:"Setup device\u2026"});let e=c.device(Object.assign({},t,{debug:s=>this.log({level:"info",host:t.host,message:s})}));this.mqttClient&&(this.mqttClient.publish(t.topic+"/host",t.host,{retain:!0}),this.mqttClient.publish(t.topic+"/name",t.name,{retain:!0}),this.mqttClient.publish(t.topic+"/id",t.id||"",{retain:!0}));let l=s=>{if(s instanceof p&&(this.log({level:"info",host:t.host,message:JSON.stringify(s)}),this.mqttClient)){let r=s.value===null?"":String(s.value);this.mqttClient.publish(t.topic+"/"+s.key,r,{retain:!0})}},a=s=>{s instanceof Error&&this.log({level:"error",host:t.host,message:"Push Error",error:s})};e.on("update",l),e.on("error",a),this.teardown.unshift(async()=>{e.off("update",l),e.off("error",a)}),this.mqttClient&&(this.mqttClient.subscribe(t.topic+"/+"),this.teardown.unshift(()=>new Promise((s,r)=>{this.mqttClient&&this.mqttClient.unsubscribe(t.topic+"/+",i=>{i?r(i):s()})})),this.mqttClient.on("message",(s,r)=>{if(t.topic+"/launch"===s){let o=r.toString();e.launchApp(o).catch(f=>{this.log({level:"error",host:t.host,message:`Unable to launch app "${o}"`,error:f})});return}let i=Object.keys(m).find(o=>t.topic+"/"+o===s);i&&e.pressKey(i).catch(o=>{this.log({level:"error",host:t.host,message:`Unable to press key "${i}"`,error:o})})}))}async stop(){await Promise.all(this.teardown)}};export{n as a};
|
|
2
|
-
//# sourceMappingURL=chunk-
|
|
2
|
+
//# sourceMappingURL=chunk-WNLLGDC3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/index.ts"],"sourcesContent":["'use strict';\n\nimport type { Config, ConfigDevice, LogParam } from './types.js';\nimport { connect, MqttClient } from 'mqtt';\nimport pyatv, {\n NodePyATVDeviceEvent,\n NodePyATVKeys,\n} from '@sebbo2002/node-pyatv';\n\nexport default class PyAtvMqttBridge {\n private mqttClient: MqttClient | null = null;\n private readonly options: Config;\n private readonly teardown: Array<() => Promise<void>> = [];\n\n constructor(options: Config) {\n if (!options.broker) {\n throw new Error('options.broker is not set!');\n }\n if (!Array.isArray(options.devices) || !options.devices.length) {\n throw new Error('options.devices is not set!');\n }\n if (options.devices.find((d) => typeof d.topic !== 'string')) {\n throw new Error('options.devices.topic is not set!');\n }\n if (options.devices.find((d) => typeof d.host !== 'string')) {\n throw new Error('options.devices.host is not set!');\n }\n if (options.devices.find((d) => typeof d.name !== 'string')) {\n throw new Error('options.devices.name is not set!');\n }\n\n this.options = options;\n this.teardown = [];\n\n this.start().catch((err) => {\n this.log({\n level: 'error',\n host: null,\n message: 'Unable to start bridge',\n error: err,\n });\n });\n }\n\n private log(msg: LogParam) {\n if (this.options.log) {\n try {\n this.options.log.apply(this, [msg]);\n } catch (err) {\n console.log('Unable to call custom log function:');\n console.log(err);\n }\n }\n }\n\n private async start() {\n const errorListener = (error: Error) =>\n this.log({\n level: 'error',\n host: null,\n message: 'MQTT error',\n error,\n });\n\n // this.mqttClient = connect(this.options.broker);\n if (typeof this.options.broker === 'string') {\n this.mqttClient = connect(this.options.broker);\n } else {\n this.mqttClient = connect(this.options.broker);\n }\n\n this.mqttClient.on('error', errorListener);\n this.teardown.unshift(async () => {\n if (this.mqttClient) {\n this.mqttClient.off('error', errorListener);\n await new Promise((resolve) => {\n if (this.mqttClient) {\n this.mqttClient.end(false, () => resolve(undefined));\n }\n });\n }\n });\n\n await Promise.all(\n this.options.devices.map((device) => this.startDevice(device)),\n );\n }\n\n private async startDevice(device: ConfigDevice) {\n this.log({\n level: 'info',\n host: device.host,\n message: 'Setup device…',\n });\n\n const atv = pyatv.device(\n Object.assign({}, device, {\n debug: (message: string) =>\n this.log({\n level: 'info',\n host: device.host,\n message,\n }),\n }),\n );\n\n /* MQTT <-- PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.publish(device.topic + '/host', device.host, {\n retain: true,\n });\n this.mqttClient.publish(device.topic + '/name', device.name, {\n retain: true,\n });\n this.mqttClient.publish(device.topic + '/id', device.id || '', {\n retain: true,\n });\n }\n\n const updateListener = (event: NodePyATVDeviceEvent | Error) => {\n if (event instanceof NodePyATVDeviceEvent) {\n this.log({\n level: 'info',\n host: device.host,\n message: JSON.stringify(event),\n });\n\n if (this.mqttClient) {\n const value =\n event.value === null ? '' : String(event.value);\n this.mqttClient.publish(\n device.topic + '/' + event.key,\n value,\n { retain: true },\n );\n }\n }\n };\n const errorListener = (error: Error | NodePyATVDeviceEvent) => {\n if (error instanceof Error) {\n this.log({\n level: 'error',\n host: device.host,\n message: 'Push Error',\n error,\n });\n }\n };\n\n atv.on('update', updateListener);\n atv.on('error', errorListener);\n this.teardown.unshift(async () => {\n atv.off('update', updateListener);\n atv.off('error', errorListener);\n });\n\n /* MQTT --> PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.subscribe(device.topic + '/+');\n this.teardown.unshift(() => {\n return new Promise((resolve, reject) => {\n if (this.mqttClient) {\n this.mqttClient.unsubscribe(\n device.topic + '/+',\n (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n },\n );\n }\n });\n });\n\n this.mqttClient.on('message', (topic, body) => {\n if (device.topic + '/launch' === topic) {\n const id = body.toString();\n atv.launchApp(id).catch((error) => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to launch app \"${id}\"`,\n error,\n });\n });\n return;\n }\n\n const key = Object.keys(NodePyATVKeys).find(\n (key) => device.topic + '/' + key === topic,\n ) as NodePyATVKeys | undefined;\n\n if (key) {\n atv.pressKey(key).catch((error) => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to press key \"${key}\"`,\n error,\n });\n });\n }\n });\n }\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.teardown);\n }\n}\n"],"mappings":"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","names":["connect","pyatv","NodePyATVDeviceEvent","NodePyATVKeys","PyAtvMqttBridge","options","d","err","msg","errorListener","error","resolve","device","atv","message","updateListener","event","value","reject","topic","body","id","key"]}
|
package/dist/lib/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/index.ts"],"sourcesContent":["'use strict';\n\nimport type {Config, ConfigDevice, LogParam} from './types.js';\nimport {connect, MqttClient} from 'mqtt';\nimport pyatv, {NodePyATVDeviceEvent, NodePyATVKeys} from '@sebbo2002/node-pyatv';\n\nexport default class PyAtvMqttBridge {\n private mqttClient: MqttClient | null = null;\n private readonly options: Config;\n private readonly teardown: Array<() => Promise<void>> = [];\n\n constructor(options: Config) {\n if (!options.broker) {\n throw new Error('options.broker is not set!');\n }\n if (!Array.isArray(options.devices) || !options.devices.length) {\n throw new Error('options.devices is not set!');\n }\n if (options.devices.find(d => typeof d.topic !== 'string')) {\n throw new Error('options.devices.topic is not set!');\n }\n if (options.devices.find(d => typeof d.host !== 'string')) {\n throw new Error('options.devices.host is not set!');\n }\n if (options.devices.find(d => typeof d.name !== 'string')) {\n throw new Error('options.devices.name is not set!');\n }\n\n this.options = options;\n this.teardown = [];\n\n this.start().catch(err => {\n this.log({\n level: 'error',\n host: null,\n message: 'Unable to start bridge',\n error: err\n });\n });\n }\n\n private log(msg: LogParam) {\n if (this.options.log) {\n try {\n this.options.log.apply(this, [msg]);\n } catch (err) {\n console.log('Unable to call custom log function:');\n console.log(err);\n }\n }\n }\n\n private async start() {\n const errorListener = (error: Error) => this.log({\n level: 'error',\n host: null,\n message: 'MQTT error',\n error\n });\n\n // this.mqttClient = connect(this.options.broker);\n if (typeof this.options.broker === 'string') {\n this.mqttClient = connect(this.options.broker);\n } else {\n this.mqttClient = connect(this.options.broker);\n }\n\n this.mqttClient.on('error', errorListener);\n this.teardown.unshift(async () => {\n if (this.mqttClient) {\n this.mqttClient.off('error', errorListener);\n await new Promise(resolve => {\n if (this.mqttClient) {\n this.mqttClient.end(false, () => resolve(undefined));\n }\n });\n }\n });\n\n await Promise.all(\n this.options.devices.map(device => this.startDevice(device))\n );\n }\n\n private async startDevice(device: ConfigDevice) {\n this.log({\n level: 'info',\n host: device.host,\n message: 'Setup device…'\n });\n\n const atv = pyatv.device(Object.assign({}, device, {\n debug: (message: string) => this.log({\n level: 'info',\n host: device.host,\n message\n })\n }));\n\n\n /* MQTT <-- PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.publish(device.topic + '/host', device.host, {retain: true});\n this.mqttClient.publish(device.topic + '/name', device.name, {retain: true});\n this.mqttClient.publish(device.topic + '/id', device.id || '', {retain: true});\n }\n\n const updateListener = (event: NodePyATVDeviceEvent | Error) => {\n if(event instanceof NodePyATVDeviceEvent) {\n this.log({\n level: 'info',\n host: device.host,\n message: JSON.stringify(event)\n });\n\n if (this.mqttClient) {\n const value = event.value === null ? '' : String(event.value);\n this.mqttClient.publish(device.topic + '/' + event.key, value, {retain: true});\n }\n }\n };\n const errorListener = (error: Error | NodePyATVDeviceEvent) => {\n if (error instanceof Error) {\n this.log({\n level: 'error',\n host: device.host,\n message: 'Push Error',\n error\n });\n }\n };\n\n atv.on('update', updateListener);\n atv.on('error', errorListener);\n this.teardown.unshift(async () => {\n atv.off('update', updateListener);\n atv.off('error', errorListener);\n });\n\n\n /* MQTT --> PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.subscribe(device.topic + '/+');\n this.teardown.unshift(() => {\n return new Promise((resolve, reject) => {\n if(this.mqttClient) {\n this.mqttClient.unsubscribe(device.topic + '/+', error => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n }\n });\n });\n\n this.mqttClient.on('message', (topic, body) => {\n if (device.topic + '/launch' === topic) {\n const id = body.toString();\n atv.launchApp(id).catch(error => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to launch app \"${id}\"`,\n error\n });\n });\n return;\n }\n\n const key = Object\n .keys(NodePyATVKeys)\n .find(key => device.topic + '/' + key === topic) as NodePyATVKeys | undefined;\n\n if(key) {\n atv.pressKey(key).catch(error => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to press key \"${key}\"`,\n error\n });\n });\n }\n });\n }\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.teardown);\n }\n}\n"],"mappings":"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","names":["lib_exports","__export","PyAtvMqttBridge","__toCommonJS","import_mqtt","import_node_pyatv","options","d","err","msg","errorListener","error","resolve","device","atv","pyatv","message","updateListener","event","value","reject","topic","body","id","key"]}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/index.ts"],"sourcesContent":["'use strict';\n\nimport type { Config, ConfigDevice, LogParam } from './types.js';\nimport { connect, MqttClient } from 'mqtt';\nimport pyatv, {\n NodePyATVDeviceEvent,\n NodePyATVKeys,\n} from '@sebbo2002/node-pyatv';\n\nexport default class PyAtvMqttBridge {\n private mqttClient: MqttClient | null = null;\n private readonly options: Config;\n private readonly teardown: Array<() => Promise<void>> = [];\n\n constructor(options: Config) {\n if (!options.broker) {\n throw new Error('options.broker is not set!');\n }\n if (!Array.isArray(options.devices) || !options.devices.length) {\n throw new Error('options.devices is not set!');\n }\n if (options.devices.find((d) => typeof d.topic !== 'string')) {\n throw new Error('options.devices.topic is not set!');\n }\n if (options.devices.find((d) => typeof d.host !== 'string')) {\n throw new Error('options.devices.host is not set!');\n }\n if (options.devices.find((d) => typeof d.name !== 'string')) {\n throw new Error('options.devices.name is not set!');\n }\n\n this.options = options;\n this.teardown = [];\n\n this.start().catch((err) => {\n this.log({\n level: 'error',\n host: null,\n message: 'Unable to start bridge',\n error: err,\n });\n });\n }\n\n private log(msg: LogParam) {\n if (this.options.log) {\n try {\n this.options.log.apply(this, [msg]);\n } catch (err) {\n console.log('Unable to call custom log function:');\n console.log(err);\n }\n }\n }\n\n private async start() {\n const errorListener = (error: Error) =>\n this.log({\n level: 'error',\n host: null,\n message: 'MQTT error',\n error,\n });\n\n // this.mqttClient = connect(this.options.broker);\n if (typeof this.options.broker === 'string') {\n this.mqttClient = connect(this.options.broker);\n } else {\n this.mqttClient = connect(this.options.broker);\n }\n\n this.mqttClient.on('error', errorListener);\n this.teardown.unshift(async () => {\n if (this.mqttClient) {\n this.mqttClient.off('error', errorListener);\n await new Promise((resolve) => {\n if (this.mqttClient) {\n this.mqttClient.end(false, () => resolve(undefined));\n }\n });\n }\n });\n\n await Promise.all(\n this.options.devices.map((device) => this.startDevice(device)),\n );\n }\n\n private async startDevice(device: ConfigDevice) {\n this.log({\n level: 'info',\n host: device.host,\n message: 'Setup device…',\n });\n\n const atv = pyatv.device(\n Object.assign({}, device, {\n debug: (message: string) =>\n this.log({\n level: 'info',\n host: device.host,\n message,\n }),\n }),\n );\n\n /* MQTT <-- PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.publish(device.topic + '/host', device.host, {\n retain: true,\n });\n this.mqttClient.publish(device.topic + '/name', device.name, {\n retain: true,\n });\n this.mqttClient.publish(device.topic + '/id', device.id || '', {\n retain: true,\n });\n }\n\n const updateListener = (event: NodePyATVDeviceEvent | Error) => {\n if (event instanceof NodePyATVDeviceEvent) {\n this.log({\n level: 'info',\n host: device.host,\n message: JSON.stringify(event),\n });\n\n if (this.mqttClient) {\n const value =\n event.value === null ? '' : String(event.value);\n this.mqttClient.publish(\n device.topic + '/' + event.key,\n value,\n { retain: true },\n );\n }\n }\n };\n const errorListener = (error: Error | NodePyATVDeviceEvent) => {\n if (error instanceof Error) {\n this.log({\n level: 'error',\n host: device.host,\n message: 'Push Error',\n error,\n });\n }\n };\n\n atv.on('update', updateListener);\n atv.on('error', errorListener);\n this.teardown.unshift(async () => {\n atv.off('update', updateListener);\n atv.off('error', errorListener);\n });\n\n /* MQTT --> PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.subscribe(device.topic + '/+');\n this.teardown.unshift(() => {\n return new Promise((resolve, reject) => {\n if (this.mqttClient) {\n this.mqttClient.unsubscribe(\n device.topic + '/+',\n (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n },\n );\n }\n });\n });\n\n this.mqttClient.on('message', (topic, body) => {\n if (device.topic + '/launch' === topic) {\n const id = body.toString();\n atv.launchApp(id).catch((error) => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to launch app \"${id}\"`,\n error,\n });\n });\n return;\n }\n\n const key = Object.keys(NodePyATVKeys).find(\n (key) => device.topic + '/' + key === topic,\n ) as NodePyATVKeys | undefined;\n\n if (key) {\n atv.pressKey(key).catch((error) => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to press key \"${key}\"`,\n error,\n });\n });\n }\n });\n }\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.teardown);\n }\n}\n"],"mappings":"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","names":["lib_exports","__export","PyAtvMqttBridge","__toCommonJS","import_mqtt","import_node_pyatv","options","d","err","msg","errorListener","error","resolve","device","atv","pyatv","message","updateListener","event","value","reject","topic","body","id","key"]}
|
package/dist/lib/index.d.cts
CHANGED
package/dist/lib/index.d.ts
CHANGED
package/dist/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a}from"../chunk-
|
|
1
|
+
import{a}from"../chunk-WNLLGDC3.js";export{a as default};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,70 +1,74 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
2
|
+
"author": "Sebastian Pekarek <mail@sebbo.net>",
|
|
3
|
+
"bin": {
|
|
4
|
+
"pyatv-mqtt-bridge": "./dist/bin/cli.js"
|
|
5
|
+
},
|
|
6
|
+
"bugs": {
|
|
7
|
+
"email": "peithosoreixookierah@e.sebbo.net",
|
|
8
|
+
"url": "https://github.com/sebbo2002/pyatv-mqtt-bridge/issues"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@sebbo2002/node-pyatv": "^8.1.2",
|
|
12
|
+
"mqtt": "^5.11.0"
|
|
13
|
+
},
|
|
14
|
+
"description": "Bridge which allows you to control your Apple TV via MQTT",
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@eslint/js": "^9.25.0",
|
|
17
|
+
"@qiwi/semantic-release-gh-pages-plugin": "^5.4.3",
|
|
18
|
+
"@sebbo2002/semantic-release-docker": "^5.0.4",
|
|
19
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
20
|
+
"@semantic-release/exec": "^7.0.3",
|
|
21
|
+
"@semantic-release/git": "^10.0.1",
|
|
22
|
+
"@semantic-release/github": "^11.0.1",
|
|
23
|
+
"@semantic-release/npm": "^12.0.1",
|
|
24
|
+
"@types/mocha": "^10.0.10",
|
|
25
|
+
"@types/node": "^22.14.0",
|
|
26
|
+
"@types/ws": "^8.18.1",
|
|
27
|
+
"c8": "^10.1.3",
|
|
28
|
+
"eslint": "^9.24.0",
|
|
29
|
+
"eslint-config-prettier": "^10.1.2",
|
|
30
|
+
"eslint-plugin-jsonc": "^2.20.0",
|
|
31
|
+
"eslint-plugin-perfectionist": "^4.12.3",
|
|
32
|
+
"esm": "^3.2.25",
|
|
33
|
+
"husky": "^9.1.7",
|
|
34
|
+
"license-checker": "^25.0.1",
|
|
35
|
+
"prettier": "^3.5.3",
|
|
36
|
+
"semantic-release": "^24.2.3",
|
|
37
|
+
"semantic-release-license": "^1.0.3",
|
|
38
|
+
"source-map-support": "^0.5.21",
|
|
39
|
+
"tsup": "^8.4.0",
|
|
40
|
+
"tsx": "^4.19.3",
|
|
41
|
+
"typedoc": "^0.28.2",
|
|
42
|
+
"typescript": "^5.8.3",
|
|
43
|
+
"typescript-eslint": "^8.29.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": "18 || 20 || >=22.0.0"
|
|
47
|
+
},
|
|
48
|
+
"exports": {
|
|
49
|
+
"import": "./dist/lib/index.js",
|
|
50
|
+
"require": "./dist/lib/index.cjs"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"/dist"
|
|
54
|
+
],
|
|
55
|
+
"homepage": "https://github.com/sebbo2002/pyatv-mqtt-bridge#readme",
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"main": "./dist/lib/index.cjs",
|
|
58
|
+
"module": "./dist/lib/index.js",
|
|
59
|
+
"name": "@sebbo2002/pyatv-mqtt-bridge",
|
|
60
|
+
"repository": {
|
|
61
|
+
"type": "git",
|
|
62
|
+
"url": "https://github.com/sebbo2002/pyatv-mqtt-bridge.git"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "tsup && cp ./dist/lib/index.d.ts ./dist/lib/index.d.cts",
|
|
66
|
+
"build-all": "./.github/workflows/build.sh",
|
|
67
|
+
"develop": "tsx src/bin/cli.ts",
|
|
68
|
+
"license-check": "license-checker --production --summary",
|
|
69
|
+
"lint": "npx eslint . --fix && npx prettier . --write",
|
|
70
|
+
"start": "node ./dist/bin/cli.js"
|
|
71
|
+
},
|
|
72
|
+
"type": "module",
|
|
73
|
+
"version": "8.1.1-develop.2"
|
|
70
74
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/index.ts"],"sourcesContent":["'use strict';\n\nimport type {Config, ConfigDevice, LogParam} from './types.js';\nimport {connect, MqttClient} from 'mqtt';\nimport pyatv, {NodePyATVDeviceEvent, NodePyATVKeys} from '@sebbo2002/node-pyatv';\n\nexport default class PyAtvMqttBridge {\n private mqttClient: MqttClient | null = null;\n private readonly options: Config;\n private readonly teardown: Array<() => Promise<void>> = [];\n\n constructor(options: Config) {\n if (!options.broker) {\n throw new Error('options.broker is not set!');\n }\n if (!Array.isArray(options.devices) || !options.devices.length) {\n throw new Error('options.devices is not set!');\n }\n if (options.devices.find(d => typeof d.topic !== 'string')) {\n throw new Error('options.devices.topic is not set!');\n }\n if (options.devices.find(d => typeof d.host !== 'string')) {\n throw new Error('options.devices.host is not set!');\n }\n if (options.devices.find(d => typeof d.name !== 'string')) {\n throw new Error('options.devices.name is not set!');\n }\n\n this.options = options;\n this.teardown = [];\n\n this.start().catch(err => {\n this.log({\n level: 'error',\n host: null,\n message: 'Unable to start bridge',\n error: err\n });\n });\n }\n\n private log(msg: LogParam) {\n if (this.options.log) {\n try {\n this.options.log.apply(this, [msg]);\n } catch (err) {\n console.log('Unable to call custom log function:');\n console.log(err);\n }\n }\n }\n\n private async start() {\n const errorListener = (error: Error) => this.log({\n level: 'error',\n host: null,\n message: 'MQTT error',\n error\n });\n\n // this.mqttClient = connect(this.options.broker);\n if (typeof this.options.broker === 'string') {\n this.mqttClient = connect(this.options.broker);\n } else {\n this.mqttClient = connect(this.options.broker);\n }\n\n this.mqttClient.on('error', errorListener);\n this.teardown.unshift(async () => {\n if (this.mqttClient) {\n this.mqttClient.off('error', errorListener);\n await new Promise(resolve => {\n if (this.mqttClient) {\n this.mqttClient.end(false, () => resolve(undefined));\n }\n });\n }\n });\n\n await Promise.all(\n this.options.devices.map(device => this.startDevice(device))\n );\n }\n\n private async startDevice(device: ConfigDevice) {\n this.log({\n level: 'info',\n host: device.host,\n message: 'Setup device…'\n });\n\n const atv = pyatv.device(Object.assign({}, device, {\n debug: (message: string) => this.log({\n level: 'info',\n host: device.host,\n message\n })\n }));\n\n\n /* MQTT <-- PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.publish(device.topic + '/host', device.host, {retain: true});\n this.mqttClient.publish(device.topic + '/name', device.name, {retain: true});\n this.mqttClient.publish(device.topic + '/id', device.id || '', {retain: true});\n }\n\n const updateListener = (event: NodePyATVDeviceEvent | Error) => {\n if(event instanceof NodePyATVDeviceEvent) {\n this.log({\n level: 'info',\n host: device.host,\n message: JSON.stringify(event)\n });\n\n if (this.mqttClient) {\n const value = event.value === null ? '' : String(event.value);\n this.mqttClient.publish(device.topic + '/' + event.key, value, {retain: true});\n }\n }\n };\n const errorListener = (error: Error | NodePyATVDeviceEvent) => {\n if (error instanceof Error) {\n this.log({\n level: 'error',\n host: device.host,\n message: 'Push Error',\n error\n });\n }\n };\n\n atv.on('update', updateListener);\n atv.on('error', errorListener);\n this.teardown.unshift(async () => {\n atv.off('update', updateListener);\n atv.off('error', errorListener);\n });\n\n\n /* MQTT --> PYATV */\n\n if (this.mqttClient) {\n this.mqttClient.subscribe(device.topic + '/+');\n this.teardown.unshift(() => {\n return new Promise((resolve, reject) => {\n if(this.mqttClient) {\n this.mqttClient.unsubscribe(device.topic + '/+', error => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n }\n });\n });\n\n this.mqttClient.on('message', (topic, body) => {\n if (device.topic + '/launch' === topic) {\n const id = body.toString();\n atv.launchApp(id).catch(error => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to launch app \"${id}\"`,\n error\n });\n });\n return;\n }\n\n const key = Object\n .keys(NodePyATVKeys)\n .find(key => device.topic + '/' + key === topic) as NodePyATVKeys | undefined;\n\n if(key) {\n atv.pressKey(key).catch(error => {\n this.log({\n level: 'error',\n host: device.host,\n message: `Unable to press key \"${key}\"`,\n error\n });\n });\n }\n });\n }\n }\n\n async stop(): Promise<void> {\n await Promise.all(this.teardown);\n }\n}\n"],"mappings":"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","names":["connect","pyatv","NodePyATVDeviceEvent","NodePyATVKeys","PyAtvMqttBridge","options","d","err","msg","errorListener","error","resolve","device","atv","message","updateListener","event","value","reject","topic","body","id","key"]}
|