Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

homebridge-arlo

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

homebridge-arlo - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

326

index.js

@@ -6,2 +6,4 @@ 'use strict';

const DEFAULT_SUBSCRIBE_TIME = 60000;
let Accessory, PlatformAccessory, Characteristic, Service, StreamController, UUIDGen;

@@ -57,3 +59,3 @@

let accessory = new PlatformAccessory(deviceName, UUIDGen.generate(device.id), Accessory.Categories.CAMERA);
let accessory = new PlatformAccessory(device.id, UUIDGen.generate(device.id), Accessory.Categories.CAMERA);

@@ -87,2 +89,35 @@ let service = accessory.getService(Service.AccessoryInformation);

}
else if (deviceType === Arlo.Q) {
this.log("Found: Camera - %s [%s]", device.id, device.id);
let accessory = new PlatformAccessory(device.id, UUIDGen.generate(device.id), Accessory.Categories.CAMERA);
let service = accessory.getService(Service.AccessoryInformation);
service.setCharacteristic(Characteristic.Manufacturer, "Arlo")
.setCharacteristic(Characteristic.Model, deviceModel);
service.getCharacteristic(Characteristic.FirmwareRevision);
service.getCharacteristic(Characteristic.HardwareRevision);
accessory.addService(Service.MotionSensor, deviceName);
service = accessory.addService(Service.CameraControl, deviceName);
service.addCharacteristic(Characteristic.NightVision);
service.addCharacteristic(Characteristic.ImageMirroring);
service.addCharacteristic(Characteristic.ImageRotation)
.setProps({
maxValue: 180,
minValue: 0,
minStep: 180
});
accessory.configureCameraSource(new ArloCameraSource(this.log, accessory, device));
accessory.addService(Service.SecuritySystem, deviceName);
this.accessories[accessory.UUID] = new ArloQAccessory(this.log, this.config, accessory, device);
this.api.publishCameraAccessories("homebridge-arlo", [accessory]);
}
}

@@ -110,4 +145,9 @@

else if(device.getType() === Arlo.CAMERA) {
this.accessories[uuid] = new ArloCameraAccessory(this.log, (accessory instanceof ArloBaseStationAccessory ? accessory.accessory : accessory), device);
this.log("Online: Camera %s [%s]", accessory.displayName, device.id);
this.accessories[uuid] = new ArloCameraAccessory(this.log, (accessory instanceof ArloCameraAccessory ? accessory.accessory : accessory), device);
}
else if(device.getType() === Arlo.Q) {
this.log("Online: Camera %s [%s]", accessory.displayName, device.id);
this.accessories[uuid] = new ArloQAccessory(this.log, this.config, (accessory instanceof ArloQAccessory ? accessory.accessory : accessory), device);
}
}.bind(this));

@@ -130,2 +170,3 @@

this.NIGHT_ARM = config.night_arm || Arlo.ARMED;
this.interval = config.interval || DEFAULT_SUBSCRIBE_TIME;

@@ -203,3 +244,3 @@ this.accessory

}.bind(this),
60000
(this.interval)
);

@@ -465,7 +506,6 @@ }

handleSnapshotRequest(request, callback) {
// todo - remove this
let now = Date.now();
if (this.lastSnapshot && now < this.lastSnapshot + 300000) {
this.log('Camera %s [%s] - Next snapshot in %d secs', this.accessory.displayName, this.device.id, parseInt((this.lastSnapshot + 300000 - now) / 1000));
this.log('Snapshot skipped: Camera %s [%s] - Next in %d secs', this.accessory.displayName, this.device.id, parseInt((this.lastSnapshot + 300000 - now) / 1000));
callback();

@@ -475,8 +515,4 @@ return;

this.log("Camera %s [%s] - Snapshot request", this.accessory.displayName, this.device.id);
this.log("Snapshot request: Camera %s [%s]", this.accessory.displayName, this.device.id);
//this.once('snapshot', function(data) {
// callback(undefined,data);
//});
this.device.getSnapshot(function(error, data) {

@@ -491,8 +527,7 @@ if (error) {

this.log("Camera %s [%s] - Snapshot confirmed", this.accessory.displayName, this.device.id);
this.log(data);
this.log("Snapshot confirmed: Camera %s [%s]", this.accessory.displayName, this.device.id);
this.device.once('fullFrameSnapshotAvailable', function(url) {
this.device.once(Arlo.FF_SNAPSHOT, function(url) {
this.device.downloadSnapshot(url, function (data) {
this.log("Camera %s [%s] - Snapshot downloaded", this.accessory.displayName, this.device.id);
this.log("Snapshot downloaded: Camera %s [%s]", this.accessory.displayName, this.device.id);
callback(undefined, data);

@@ -520,3 +555,3 @@ }.bind(this));

_createStreamControllers(options) {
this.log("_createStreamControllers");
//this.log("_createStreamControllers");
let streamController = new StreamController(1, options, this);

@@ -528,1 +563,262 @@

}
class ArloQAccessory {
constructor(log, config, accessory, device) {
this.accessory = accessory;
this.device = device;
this.log = log;
config = config || {};
this.STAY_ARM = config.stay_arm || Arlo.ARMED;
this.NIGHT_ARM = config.night_arm || Arlo.ARMED;
this.interval = config.interval || DEFAULT_SUBSCRIBE_TIME;
this.accessory
.getService(Service.AccessoryInformation)
.setCharacteristic(Characteristic.Model, device.getModel())
.setCharacteristic(Characteristic.SerialNumber, device.getSerialNumber());
this.setupListeners();
}
setupListeners() {
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.on('set', this.setTargetState.bind(this));
this.device.on(Arlo.ARMED, function() {
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.updateValue(Characteristic.SecuritySystemTargetState.AWAY_ARM);
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemCurrentState)
.updateValue(Characteristic.SecuritySystemCurrentState.AWAY_ARM);
}.bind(this));
this.device.on(Arlo.DISARMED, function() {
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.updateValue(Characteristic.SecuritySystemTargetState.DISARM);
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemCurrentState)
.updateValue(Characteristic.SecuritySystemCurrentState.DISARMED);
}.bind(this));
if (this.STAY_ARM !== Arlo.ARMED) {
this.device.on(this.STAY_ARM, function() {
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.updateValue(Characteristic.SecuritySystemTargetState.STAY_ARM);
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemCurrentState)
.updateValue(Characteristic.SecuritySystemCurrentState.STAY_ARM);
}.bind(this));
}
if (this.NIGHT_ARM !== Arlo.ARMED) {
this.device.on(this.NIGHT_ARM, function() {
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemTargetState)
.updateValue(Characteristic.SecuritySystemTargetState.NIGHT_ARM);
this.accessory
.getService(Service.SecuritySystem)
.getCharacteristic(Characteristic.SecuritySystemCurrentState)
.updateValue(Characteristic.SecuritySystemCurrentState.NIGHT_ARM);
}.bind(this));
}
this.accessory
.getService(Service.CameraControl)
.getCharacteristic(Characteristic.On)
.on('set', this.setPrivacyActive.bind(this));
this.accessory
.getService(Service.CameraControl)
.getCharacteristic(Characteristic.ImageMirroring)
.on('set', this.setImageMirroring.bind(this));
this.accessory
.getService(Service.CameraControl)
.getCharacteristic(Characteristic.ImageRotation)
.on('set', this.setImageRotation.bind(this));
this.accessory
.getService(Service.MotionSensor)
.getCharacteristic(Characteristic.MotionDetected)
.on('get', this.get.bind(this));
this.device.on(Arlo.MOTION, this.updateMotionDetected.bind(this));
this.device.on(Arlo.UPDATE, function(info) {
this.updateInfo(info);
this.updateConnectionState(info.connectionState);
this.updateImageMirroring(info.mirror);
this.updateImageRotation(info.flip);
this.updateNightVision(info.nightVisionMode);
this.updatePrivacyActive(info.privacyActive);
}.bind(this));
setInterval(
function() {
this.device.subscribe();
}.bind(this),
(this.interval)
);
}
get(callback) {
if (this.device) {
this.device.get();
}
callback(null, null)
}
setImageMirroring(value, callback) {
this.device.set({mirror: value}, function() {
callback(null);
})
}
setImageRotation(value, callback) {
this.device.set({flip: (value > 0 ? true : false)}, function() {
callback(null);
})
}
setPrivacyActive(value, callback) {
this.device.set({privacyActive: value == false}, function() {
callback(null);
})
}
setTargetState(state, callback) {
switch(state) {
case Characteristic.SecuritySystemTargetState.AWAY_ARM:
this.device.arm(function() {
callback(null);
this.device.emit(Arlo.ARMED);
}.bind(this));
break;
case Characteristic.SecuritySystemTargetState.DISARM:
this.device.disarm(function() {
callback(null);
this.device.emit(Arlo.DISARMED);
}.bind(this));
break;
case Characteristic.SecuritySystemTargetState.STAY_ARM:
this.device.setMode(this.STAY_ARM, function() {
callback(null);
this.device.emit(this.STAY_ARM);
}.bind(this));
break;
case Characteristic.SecuritySystemTargetState.NIGHT_ARM:
this.device.setMode(this.NIGHT_ARM, function() {
callback(null);
this.device.emit(this.NIGHT_ARM);
}.bind(this));
break;
}
}
updateInfo(info) {
if (info === undefined) {
return;
}
let service = this.accessory.getService(Service.AccessoryInformation);
if (info.modelId) {
service.getCharacteristic(Characteristic.Model).updateValue(info.modelId);
}
if (info.serialNumber) {
service.getCharacteristic(Characteristic.SerialNumber).updateValue(info.serialNumber);
}
if (info.swVersion) {
service.getCharacteristic(Characteristic.FirmwareRevision).updateValue(info.swVersion);
}
if (info.hwVersion) {
service.getCharacteristic(Characteristic.HardwareRevision).updateValue(info.hwVersion);
}
}
updateConnectionState(connectionState) {
if (connectionState === undefined) {
return;
}
let online = connectionState === 'available';
this.log("%s: Camera %s [%s]", (online ? 'Online' : 'Offline'), this.accessory.displayName, this.device.id);
}
updateMotionDetected(motionDetected) {
if (motionDetected === undefined) {
return;
}
this.accessory
.getService(Service.MotionSensor)
.getCharacteristic(Characteristic.MotionDetected)
.updateValue(motionDetected);
}
updateImageMirroring(mirror) {
if (mirror === undefined) {
return;
}
this.accessory
.getService(Service.CameraControl)
.getCharacteristic(Characteristic.ImageMirroring)
.updateValue(mirror);
}
updateImageRotation(flip) {
if (flip === undefined) {
return;
}
this.accessory
.getService(Service.CameraControl)
.getCharacteristic(Characteristic.ImageRotation)
.updateValue(flip === true ? 180 : 0);
}
updateNightVision(nightVisionMode) {
if (nightVisionMode === undefined) {
return;
}
this.accessory
.getService(Service.CameraControl)
.getCharacteristic(Characteristic.NightVision)
.updateValue(nightVisionMode === 1);
}
updatePrivacyActive(privacyActive) {
if (privacyActive === undefined) {
return;
}
this.accessory
.getService(Service.CameraControl)
.getCharacteristic(Characteristic.On)
.updateValue(privacyActive == false);
}
}

4

package.json
{
"name": "homebridge-arlo",
"version": "0.0.2",
"version": "0.0.3",
"author": "David Parry <npm@introversion.com.au>",

@@ -19,4 +19,4 @@ "description": "Arlo platform plugin for homebridge",

"dependencies": {
"node-arlo": ">=0.0.5"
"node-arlo": ">=0.0.7"
}
}

@@ -5,4 +5,3 @@ # homebridge-arlo

[![NPM Version](https://img.shields.io/npm/v/homebridge-arlo.svg)](https://www.npmjs.com/package/homebridge-arlo)
[![Dependency Status](https://img.shields.io/versioneye/d/nodejs/arlo.svg)](https://www.versioneye.com/nodejs/homebridge-arlo/)
[![donate](https://img.shields.io/badge/%24-Buy%20me%20a%20coffee-ff69b4.svg)](https://www.buymeacoffee.com/devbobo)
[![Slack Channel](https://img.shields.io/badge/slack-homebridge--arlo-e01563.svg)](https://homebridgeteam.slack.com/messages/C5C0Z6XPW)

@@ -20,11 +19,15 @@

- npm update -g homebridge-arlo
- `npm update -g homebridge-arlo`
# Setup
Arlo only allows a single login to each account at a time, as a result, if you are running Homebridge and the Arlo on the same account...logging in on your iPhone to view cameras will log out homebridge's Arlo access.
Arlo only allows a single login to each account at a time, as a result, if you
are running Homebridge and the Arlo on the same account... logging in on your
iPhone to view cameras will log out homebridge's Arlo access.
Therefore, I **highly recommend** creating an additional account in Arlo, just for homebridge access.
Therefore, I **highly recommend** creating an additional account in Arlo, just
for homebridge access.
# Limitations
This plugin currently only support Base Stations, not cameras. This is mainly because I haven't gotten video streaming to work yet.
This plugin currently only support Base Stations, not cameras. This is mainly
because I haven't gotten video streaming to work yet.

@@ -40,2 +43,3 @@ # Configuration

"password": "<insert arlo account password>"
"interval": 6000
}

@@ -45,12 +49,31 @@ ]

```
NOTE: interval time is in milliseconds - e.g. 6000 ms are 10 sec
## Optional parameters
By default, Arlo only provides two modes (**armed** and **disarmed**). Since HomeKit allows a security system to have 4 statees (**away**, **home**, **night** and **off**), we provide two config parameters to enable support for the additional 2 states. If these configuration parameters aren't provided setting the state to **home** or **night** will result in the state being set to **away**.
By default, Arlo only provides two modes (**armed** and **disarmed**). Since
HomeKit allows a security system to have 4 states (**away**, **home**,
**night** and **off**), we provide two config parameters to enable support for
the additional 2 states. If these configuration parameters aren't provided
setting the state to **home** or **night** will result in the state being set
to **away**, i.e. **armed**.
`stay_arm` - The string label for the mode created in Arlo for the **home** or **stay** state.
Arlo uses the string `modeX` to identify each mode, with `mode0` used for the
default **disarmed** state and `mode1` used for the default **armed** state.
To determine the correct `modeX` string for your custom state, login to the
[Arlo web console](https://arlo.netgear.com) and click the "Edit Mode" button.
The URL will show the ` modeX` string for that custom state, e.g.
https\://arlo.netgear.com/#/modes/`<USER_ID>`/edit/**mode2**
`night_arm` - The string label for the mode created in Arlo for the **night** state.
Once you've determined the `modeX` string of your custom mode(s), you can
configure `homebridge-arlo` to use those for the additional modes available
via HomeKit:
Sample Configuration
* `stay_arm` - The `modeX` label for the custom mode created in Arlo for the
**home** or **stay** state.
* `night_arm` - The `modeX` label for the custom mode created in Arlo for the
**night** state.
### Sample Configuration with Optional Parameters
```javascript

@@ -67,18 +90,1 @@ "platforms": [

]
```
# Siri commands
**Arming - Away Mode**<br/>
_Set the security system to armed/away_
**Disarming - Off Mode**<br/>
_Set the security system to disarmed/off_
**Arming - Home Mode**<br/>
_Set the security system to stay_
**Arming - Night Mode**<br/>
_Set the security system to night_
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc