mirror of
https://github.com/tsightler/ring-mqtt.git
synced 2025-09-26 21:01:12 +08:00
Release 5.0.0
This commit is contained in:
@@ -72,8 +72,8 @@ No variable is absolutely required, but, in practice, at least **MQTTHOST** will
|
||||
### Authentication
|
||||
Ring has made two factor authentication (2FA) mandatory thus the script now only supports this authentication method. Using 2FA requires acquiring a refresh token for your Ring account which can be done by running the included get-ring-token.js CLI tool which will prompt for the required account information and 2FA code, and then acquire the token and save it to the ring-state.json file where it will be updated automatically going forward. Below is an example of running this command, note that you must map the same persistent volume used for running the primary container image as well:
|
||||
|
||||
#### Primary Method
|
||||
Run the bundled ring-auth-cli utility directly via the Docker command line to acquire the token:
|
||||
#### Acquire a token for the Docker image
|
||||
Run the bundled get-ring-token.js utility directly via the Docker command line to acquire the token:
|
||||
```
|
||||
docker run -it --rm --mount type=bind,source=/etc/ring-mqtt,target=/data --entrypoint /app/ring-mqtt/get-ring-token.js tsightler/ring-mqtt
|
||||
```
|
||||
|
@@ -1,5 +1,5 @@
|
||||
## Standard Install
|
||||
Stanard installation is possible, however, this method is not regularly tested and this you will mostly on your own to solve any installation problems if you choose to use this method.
|
||||
Standard installation is possible, however, this method is not regularly tested and you will mostly on your own to solve any installation problems if you choose to use this method. Installing using this method is not complex, but it assumes you have basic Linux admin knowledge such as working with unit files, manually installing binary files and a basic understanding of permissions, etc. If you do not have this knowledge then I highly recommend using the Docker install method instead.
|
||||
|
||||
### Installation
|
||||
#### Pre-requisites
|
||||
@@ -19,7 +19,7 @@ chmod +x ring-mqtt.js
|
||||
npm install
|
||||
```
|
||||
|
||||
This will install all of the required node dependencies. Now edit the config.js file to configure your Ring refresh token and MQTT broker connection information and any other settings (see [Configuration Options](#configuration-options) below). Note that the user the script runs as will need permission to write the config.json file as updated refresh tokens are written back directly to this file when running via standard install.
|
||||
This will install all of the required node dependencies. Now edit the config.js file to configure your Ring refresh token and MQTT broker connection information and any other settings (see [Configuration Options](#configuration-options) below). Note that the user the script runs as will need permissions to write to the directory where ring-mqtt is installed as updated refresh tokens are written into a saved state file (ring-state.json) in this directory.
|
||||
|
||||
#### Configuration Options
|
||||
| Config Option | Description | Default |
|
||||
|
@@ -8,7 +8,7 @@ ExecStart=/usr/bin/node /opt/ring-mqtt/ring-mqtt.js
|
||||
Restart=always
|
||||
User=root
|
||||
Group=root
|
||||
Environment=PATH=/usr/bin/
|
||||
Environment=PATH=/usr/bin/:/usr/local/bin
|
||||
Environment=NODE_ENV=production
|
||||
Environment=DEBUG=ring-mqtt
|
||||
StandardOutput=file:/var/log/ring-mqtt.log
|
||||
|
66
ring-mqtt.js
66
ring-mqtt.js
@@ -438,57 +438,46 @@ const main = async(generatedToken) => {
|
||||
// If no refresh tokens were found, either exit or start Web UI for token generator
|
||||
if (!state.data.ring_token) {
|
||||
if (config.runMode === 'docker') {
|
||||
debug(colors.brightRed('No refresh token was found in state file, please generate a token with ring-auth-cli.js.'))
|
||||
debug(colors.brightRed('No refresh token was found in state file, generate a token using get-ring-token.js.'))
|
||||
process.exit(2)
|
||||
} else {
|
||||
debug(colors.brightRed('No refresh token was found in saved state file.'))
|
||||
debug(colors.brightRed('Use the web interface to generate a new token.'))
|
||||
if (config.runMode === 'standard') {
|
||||
debug(colors.brightRed('No refresh token was found in state file, generate a token using the Web UI.'))
|
||||
if (config.runMode === 'standard' && !tokenApp.listener) {
|
||||
tokenApp.start()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// There is at least one token in state file or config
|
||||
// Check if network is up before attempting to connect to Ring, wait if network is not ready
|
||||
// There is either web UI generated or saved state refresh token available
|
||||
// Wait for the network to be online and then attempt to connect to the Ring API using the token
|
||||
while (!(await isOnline())) {
|
||||
debug(colors.brightYellow('Network is offline, waiting 10 seconds to check again...'))
|
||||
await utils.sleep(10)
|
||||
}
|
||||
|
||||
// If there is a saved or generated refresh token, try to connect using it first
|
||||
if (state.data.ring_token) {
|
||||
const ringAuth = {
|
||||
refreshToken: state.data.ring_token,
|
||||
systemId: state.data.systemId,
|
||||
controlCenterDisplayName: (config.runMode === 'addon') ? 'ring-mqtt-addon' : 'ring-mqtt',
|
||||
...config.data.enable_cameras ? {
|
||||
cameraStatusPollingSeconds: 20,
|
||||
cameraDingsPollingSeconds: 2
|
||||
} : {},
|
||||
...config.data.enable_modes ? {
|
||||
locationModePollingSeconds: 20
|
||||
} : {},
|
||||
...(!(config.data.location_ids === undefined || config.data.location_ids == 0)) ? {
|
||||
locationIds: config.data.location_ids
|
||||
} : {},
|
||||
}
|
||||
|
||||
const tokenSource = generatedToken ? "generated" : "saved"
|
||||
debug(`Attempting connection to Ring API using ${generatedToken ? "generated" : "saved"} refresh token.`)
|
||||
|
||||
try {
|
||||
ringClient = new RingApi(ringAuth)
|
||||
await ringClient.getProfile()
|
||||
} catch(error) {
|
||||
ringClient = null
|
||||
debug(colors.brightYellow(error.message))
|
||||
debug(colors.brightYellow('Unable to connect to Ring API using '+tokenSource+' refresh token.'))
|
||||
}
|
||||
const tokenSource = generatedToken ? "generated" : "saved"
|
||||
const ringAuth = {
|
||||
refreshToken: state.data.ring_token,
|
||||
systemId: state.data.systemId,
|
||||
controlCenterDisplayName: (config.runMode === 'addon') ? 'ring-mqtt-addon' : 'ring-mqtt',
|
||||
...config.data.enable_cameras ? { cameraStatusPollingSeconds: 20, cameraDingsPollingSeconds: 2 } : {},
|
||||
...config.data.enable_modes ? { locationModePollingSeconds: 20 } : {},
|
||||
...(!(config.data.location_ids === undefined || config.data.location_ids == 0)) ? { locationIds: config.data.location_ids } : {}
|
||||
}
|
||||
|
||||
try {
|
||||
debug(`Attempting connection to Ring API using ${generatedToken ? "generated" : "saved"} refresh token.`)
|
||||
ringClient = new RingApi(ringAuth)
|
||||
await ringClient.getProfile()
|
||||
} catch(error) {
|
||||
ringClient = null
|
||||
debug(colors.brightYellow(error.message))
|
||||
debug(colors.brightYellow('Failed to establed connection to Ring API using '+tokenSource+' refresh token.'))
|
||||
}
|
||||
}
|
||||
|
||||
if (ringClient) {
|
||||
debug('Connection to Ring API successful')
|
||||
debug('Successfully established connection to Ring API')
|
||||
|
||||
// Update the web app with current connected refresh token
|
||||
const currentAuth = await ringClient.restClient.authPromise
|
||||
@@ -521,10 +510,13 @@ const main = async(generatedToken) => {
|
||||
} else {
|
||||
debug(colors.brightRed('Failed to connect to Ring API using the refresh token in the saved state file.'))
|
||||
if (config.runMode === 'docker') {
|
||||
debug(colors.brightRed('Restart the container to try again or generate a new token with ring-auth-cli.js.'))
|
||||
debug(colors.brightRed('Restart the container to try again or generate a new token using get-ring-token.js.'))
|
||||
process.exit(2)
|
||||
} else {
|
||||
debug(colors.brightRed(`Use the web UI to generate a new token or restart the ${this.runMode === 'addon' ? 'addon' : 'script'} to try again with the existing token.`))
|
||||
debug(colors.brightRed(`Restart the ${this.runMode === 'addon' ? 'addon' : 'script'} or generate a new token using the Web UI.`))
|
||||
if (config.runMode === 'standard' && !tokenApp.listener) {
|
||||
tokenApp.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user