Small server wrapper around eufy-security-client library to access it via a WebSocket.
The development of this server was inspired by the following project:
Credits go to them as well.
If you appreciate my work and progress and want to support me, you can do it here:
These instructions are for development only. These CLIs will be available as eufy-security-server
and eufy-security-client
after installing the NPM package.
ts-node src/bin/server.ts
Opens server on ws://localhost:3000
.
You can specify a configuration file with --config
. This can be a JSON file or a JS file that exports the config. It needs to following format:
export interface EufySecurityConfig {
username: string; // Eufy Account Username (required)
password: string; // Eufy Account Password (required)
country?: string; // ISO 3166-1 Alpha-2 country code (default: US)
language?: string; // ISO 639 language code (default: en)
trustedDeviceName?: string; // Label of the trusted devices (viewable with 2fa activated in Eufy App; default: eufyclient)
persistentDir?: string; // Directory in which the persistent information is saved (default: module path)
p2pConnectionSetup: number; // P2P connection setup (default: 0 ; Prefers local connection over cloud)
pollingIntervalMinutes: number; // Polling intervall for data refresh from Eufy Cloud (default: 10 min.)
eventDurationSeconds: number; // Duration in seconds before an event is reset E.g. motion event (default: 10 sec.)
acceptInvitations?: booleam; // Automatically accept device invitations (default: false)
}
To specify different listening port specify --port
.
Requires server to be running.
Default connects to ws://localhost:3000
:
ts-node src/bin/client.ts
To specify different host and port:
ts-node src/bin/client.ts --host 192.168.1.100 --port 6000
To specify a schema version other than the latest (maxSchemaVersion
):
ts-node src/bin/client.ts --schemaVersion 0
All these options can be combined.
When a client connects, the server will send the version.
interface {
type: "version";
driverVersion: string;
serverVersion: string;
minSchemaVersion: number;
maxSchemaVersion: number;
}
To start receive the state and get events, the client needs to send the start_listening
command.
interface {
messageId: string;
command: "start_listening";
}
The server will respond with the current state and start sending events.
interface {
type: "result";
messageId: string; // maps the `start_listening` command
success: true,
result: {
state: {
driver: {
version:
connected:
pushConnected:
}
stations: Partial<StationState>[];
devices: Partial<DeviceState>[];
}
};
}
After that, the client will be notified of each state change that happens inside eufy-security-client.
interface {
messageId: string;
command: "start_listening";
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "set_api_schema";
schemaVersion: number;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "driver.set_verify_code";
verifyCode: string;
}
Returns:
interface {
result: boolean;
}
[compatible with schema version: 7+]
interface {
messageId: string;
command: "driver.set_captcha";
captchaId?: string;
captcha: string;
}
Returns:
interface {
result: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "driver.poll_refresh";
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "driver.is_connected";
}
Returns:
interface {
connected: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "driver.is_push_connected";
}
Returns:
interface {
connected: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "driver.connect";
}
Returns:
interface {
result: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "driver.disconnect";
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "driver.get_video_events";
startTimestampMs?: number;
endTimestampMs?: number;
filter?: EventFilterType;
maxResults?: number;
}
Returns:
interface {
events: Array<EventRecordResponse>
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "driver.get_alarm_events";
startTimestampMs?: number;
endTimestampMs?: number;
filter?: EventFilterType;
maxResults?: number;
}
Returns:
interface {
events: Array<EventRecordResponse>
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "driver.get_history_events";
startTimestampMs?: number;
endTimestampMs?: number;
filter?: EventFilterType;
maxResults?: number;
}
Returns:
interface {
events: Array<EventRecordResponse>
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "station.reboot";
serialNumber: string;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "station.set_guard_mode";
serialNumber: string;
mode: number;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "station.isConnected";
serialNumber: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
connected: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "station.connect";
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "station.disconnect";
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "station.get_properties_metadata";
serialNumber: string;
}
Returns:
interface {
properties: {
[index: string]: PropertyMetadataAny;
}
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "station.get_properties";
serialNumber: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
properties: {
[index: string]: PropertyValue;
}
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "station.set_property";
serialNumber: string;
name: string;
value: unknown;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "station.trigger_alarm";
serialNumber: string;
seconds: number;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "station.reset_alarm";
serialNumber: string;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "station.get_commands";
serialNumber: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
commands: Array<CommandName>;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "station.has_command";
serialNumber: string;
commandName: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
exists: boolean;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "station.has_property";
serialNumber: string;
propertyName: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
exists: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.get_properties_metadata";
serialNumber: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
properties: {
[index: string]: PropertyMetadataAny;
}
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.get_properties";
serialNumber: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
properties: {
[index: string]: PropertyValue;
}
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_property";
serialNumber: string;
name: string;
value: unknown;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_status_led";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_auto_night_vision";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_motion_detection";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_sound_detection";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_pet_detection";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_rtsp_stream";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_anti_theft_detection";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.set_watermark";
serialNumber: string;
value: number;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.enable_device";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 0+]
interface {
messageId: string;
command: "device.lock_device";
serialNumber: string;
value: boolean;
}
[compatible with schema version: 2+]
interface {
messageId: string;
command: "device.start_livestream";
serialNumber: string;
}
[compatible with schema version: 2+]
interface {
messageId: string;
command: "device.stop_livestream";
serialNumber: string;
}
[compatible with schema version: 2+]
interface {
messageId: string;
command: "device.is_livestreaming";
serialNumber: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
livestreaming: boolean;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.trigger_alarm";
serialNumber: string;
seconds: number;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.reset_alarm";
serialNumber: string;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.start_download";
serialNumber: string;
path: string;
cipherId: number;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.cancel_download";
serialNumber: string;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.pan_and_tilt";
serialNumber: string;
direction: PanTiltDirection;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.quick_response";
serialNumber: string;
voiceId: number;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.get_voices";
serialNumber: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
voices: Voices
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.get_commands";
serialNumber: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
commands: Array<CommandName>;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.has_command";
serialNumber: string;
commandName: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
exists: boolean;
}
[compatible with schema version: 3+]
interface {
messageId: string;
command: "device.has_property";
serialNumber: string;
propertyName: string;
}
Returns:
interface {
serialNumber: string; // [added with schema version: 4+]
exists: boolean;
}
[compatible with schema version: 6+]
interface {
messageId: string;
command: "device.start_rtsp_livestream";
serialNumber: string;
}
[compatible with schema version: 6+]
interface {
messageId: string;
command: "device.stop_rtsp_livestream";
serialNumber: string;
}
[compatible with schema version: 6+]
interface {
messageId: string;
command: "device.is_rtsp_livestreaming";
serialNumber: string;
}
Returns:
interface {
serialNumber: string;
livestreaming: boolean;
}
[compatible with schema version: 0+]
This event is sent whenever the Eufy Cloud asks for a 2FA token during the login process.
interface {
type: "event";
event: {
source: "driver";
event: "verify code";
}
}
[compatible with schema version: 7+]
This event is sent whenever the Eufy Cloud asks for a captcha during the login process.
interface {
type: "event";
event: {
source: "driver";
event: "captcha request";
captchaId: string;
captcha: string;
}
}
[compatible with schema version: 0+]
This event is sent whenever the connection to the Eufy Cloud is successfully established.
interface {
type: "event";
event: {
source: "driver";
event: "connected";
}
}
[compatible with schema version: 0+]
This event is sent whenever the connection to the Eufy Cloud connection is lost.
interface {
type: "event";
event: {
source: "driver";
event: "disconnected";
}
}
[compatible with schema version: 0+]
This event is sent whenever the connection to the Eufy Cloud Push notification is successfully established.
interface {
type: "event";
event: {
source: "driver";
event: "push connected";
}
}
[compatible with schema version: 0+]
This event is sent whenever the connection to the Eufy Cloud Push notification is lost.
interface {
type: "event";
event: {
source: "driver";
event: "push disconnected";
}
}
[compatible with schema version: 0+]
This event is sent when a new station is found.
interface {
type: "event";
event: {
source: "station";
event: "station added";
station: {
name: string;
model: string;
serialNumber: string;
hardwareVersion: string;
softwareVersion: string;
lanIpAddress: string;
macAddress: string;
currentMode: number;
guardMode: number;
connected: boolean;
type: number; // [added with schema version: 1+]
timeFormat: number; // [added with schema version: 3+]
alarmVolume: number; // [added with schema version: 3+]
alarmTone: number; // [added with schema version: 3+]
promptVolume: number; // [added with schema version: 3+]
notificationSwitchModeSchedule: boolean; // [added with schema version: 3+]
notificationSwitchModeGeofence: boolean; // [added with schema version: 3+]
notificationSwitchModeApp: boolean; // [added with schema version: 3+]
notificationSwitchModeKeypad: boolean; // [added with schema version: 3+]
notificationStartAlarmDelay: boolean; // [added with schema version: 3+]
switchModeWithAccessCode: boolean; // [added with schema version: 5+]
autoEndAlarm: boolean; // [added with schema version: 5+]
turnOffAlarmWithButton: boolean; // [added with schema version: 5+]
}
}
}
[compatible with schema version: 0+]
This event is sent when a station is removed.
interface {
type: "event";
event: {
source: "station";
event: "station removed";
station: {
name: string;
model: string;
serialNumber: string;
hardwareVersion: string;
softwareVersion: string;
lanIpAddress: string;
macAddress: string;
currentMode: number;
guardMode: number;
connected: boolean;
type: number; // [added with schema version: 1+]
timeFormat: number; // [added with schema version: 3+]
alarmVolume: number; // [added with schema version: 3+]
alarmTone: number; // [added with schema version: 3+]
promptVolume: number; // [added with schema version: 3+]
notificationSwitchModeSchedule: boolean; // [added with schema version: 3+]
notificationSwitchModeGeofence: boolean; // [added with schema version: 3+]
notificationSwitchModeApp: boolean; // [added with schema version: 3+]
notificationSwitchModeKeypad: boolean; // [added with schema version: 3+]
notificationStartAlarmDelay: boolean; // [added with schema version: 3+]
switchModeWithAccessCode: boolean; // [added with schema version: 5+]
autoEndAlarm: boolean; // [added with schema version: 5+]
turnOffAlarmWithButton: boolean; // [added with schema version: 5+]
}
}
}
[compatible with schema version: 0+]
This event is sent whenever the guard mode of a station is changed.
interface {
type: "event";
event: {
source: "station";
event: "guard mode changed";
serialNumber: string;
currentMode: number; // [removed with schema version: 3+ as there is now a separate event]
guardMode: number;
}
}
[compatible with schema version: 3+]
This event is sent whenever the current mode of a station is changed.
interface {
type: "event";
event: {
source: "station";
event: "current mode changed";
serialNumber: string;
currentMode: number;
}
}
[compatible with schema version: 0+]
This event is sent after each execution of a p2p command and reflects the result of the command.
interface {
type: "event";
event: {
source: "station";
event: "command result";
serialNumber: string;
command: string;
returnCode: number;
returnCodeName: string;
}
}
[compatible with schema version: 0+]
This event is sent when the connection to the station is successfully established.
interface {
type: "event";
event: {
source: "station";
event: "connected";
serialNumber: string;
}
}
[compatible with schema version: 0+]
This event is sent whenever the connection to the station is lost.
interface {
type: "event";
event: {
source: "station";
event: "disconnected";
serialNumber: string;
}
}
[compatible with schema version: 0+]
This event is sent whenever a property of a station is changed.
interface {
type: "event";
event: {
source: "station";
event: "property changed";
serialNumber: string;
name: string;
value: JSONValue;
timestamp: number;
}
}
[compatible with schema version: 3+]
This event is sent whenever an alarm event occurred.
interface {
type: "event";
event: {
source: "station";
event: "alarm event";
serialNumber: string;
alarmEvent: AlarmEvent;
}
}
[compatible with schema version: 0+]
This event is sent when a new device is found.
interface {
type: "event";
event: {
source: "device";
event: "device added";
device: {
name: string;
model: string;
serialNumber: string;
hardwareVersion: string;
softwareVersion: string;
stationSerialNumber: device.getPropertyValue(PropertyName.DeviceStationSN)?.value as string,
enabled: boolean;
state: number;
battery: number;
batteryTemperature: number;
batteryLow: boolean;
lastChargingDays: number;
lastChargingTotalEvents: number;
lastChargingRecordedEvents: number;
lastChargingFalseEvents: number;
batteryUsageLastWeek: number;
motionDetected: boolean;
personDetected: boolean;
personName: string;
soundDetected: boolean;
petDetected: boolean;
cryingDetected: boolean;
ringing: boolean;
locked: boolean;
sensorOpen: boolean;
sensorChangeTime: number;
antitheftDetection: boolean;
autoNightvision: boolean;
ledStatus: boolean; // [added with schema version: 0+; removed with schema version: 4+]
motionDetection: boolean;
soundDetection: boolean;
petDetection: boolean;
rtspStream: boolean;
watermark: number;
lockStatus: number;
motionSensorPIREvent: number;
wifiRSSI: number;
pictureUrl: string;
type: number; // [added with schema version: 1+]
motionDetectionType: number; // [added with schema version: 3+]
motionDetectionSensivity: number; // [added with schema version: 3+; removed with schema version: 4+]
motionTracking: boolean; // [added with schema version: 3+]
soundDetectionType: number; // [added with schema version: 3+]
soundDetectionSensivity: number; // [added with schema version: 3+; removed with schema version: 4+]
light: boolean; // [added with schema version: 3+]
microphone: boolean; // [added with schema version: 3+]
speaker: boolean; // [added with schema version: 3+]
speakerVolume: number; // [added with schema version: 3+]
ringtoneVolume: number; // [added with schema version: 3+]
audioRecording: boolean; // [added with schema version: 3+]
powerSource: number; // [added with schema version: 3+]
powerWorkingMode: number; // [added with schema version: 3+]
recordingEndClipMotionStops: boolean; // [added with schema version: 3+]
recordingClipLength: number; // [added with schema version: 3+]
recordingRetriggerInterval: number; // [added with schema version: 3+]
videoStreamingQuality: number; // [added with schema version: 3+]
videoRecordingQuality: number; // [added with schema version: 3+]
videoWDR: boolean; // [added with schema version: 3+]
lightSettingsEnable: boolean; // [added with schema version: 3+]
lightSettingsBrightnessManual: number; // [added with schema version: 3+]
lightSettingsBrightnessMotion: number; // [added with schema version: 3+]
lightSettingsBrightnessSchedule: number; // [added with schema version: 3+]
lightSettingsMotionTriggered: boolean; // [added with schema version: 3+]
lightSettingsMotionTriggeredDistance: number; // [added with schema version: 3+]
lightSettingsMotionTriggeredTimer: number; // [added with schema version: 3+]
chimeIndoor: boolean; // [added with schema version: 3+]
chimeHomebase: boolean; // [added with schema version: 3+]
chimeHomebaseRingtoneVolume: number; // [added with schema version: 3+]
chimeHomebaseRingtoneType: number; // [added with schema version: 3+]
notificationType: number; // [added with schema version: 3+]
rotationSpeed: number; // [added with schema version: 3+]
notificationPerson: boolean; // [added with schema version: 3+]
notificationPet: boolean; // [added with schema version: 3+]
notificationAllOtherMotion: boolean; // [added with schema version: 3+]
notificationCrying: boolean; // [added with schema version: 3+]
notificationAllSound: boolean; // [added with schema version: 3+]
notificationIntervalTime: boolean; // [added with schema version: 3+]
notificationRing: boolean; // [added with schema version: 3+]
notificationMotion:boolean; // [added with schema version: 3+]
chirpVolume: number; // [added with schema version: 4+]
chirpTone: number; // [added with schema version: 4+]
motionDetectionSensitivity: number; // [added with schema version: 4+]
soundDetectionSensitivity: number; // [added with schema version: 4+]
videoHdr: boolean; // [added with schema version: 4+]
videoDistortionCorrection: boolean; // [added with schema version: 4+]
videoRingRecord: number; // [added with schema version: 4+]
statusLed: boolean; // [added with schema version: 4+]
chargingStatus: number; // [added with schema version: 4+]
rtspStreamUrl: string; // [added with schema version: 4+]
wifiSignalLevel: number; // [added with schema version: 4+]
nightvision: number; // [added with schema version: 5+]
batteryIsCharging: boolean; // [added with schema version: 5+]
}
}
}
[compatible with schema version: 0+]
This event is sent when a device is removed.
interface {
type: "event";
event: {
source: "device";
event: "device removed";
device: {
name: string;
model: string;
serialNumber: string;
hardwareVersion: string;
softwareVersion: string;
stationSerialNumber: device.getPropertyValue(PropertyName.DeviceStationSN)?.value as string,
enabled: boolean;
state: number;
battery: number;
batteryTemperature: number;
batteryLow: boolean;
lastChargingDays: number;
lastChargingTotalEvents: number;
lastChargingRecordedEvents: number;
lastChargingFalseEvents: number;
batteryUsageLastWeek: number;
motionDetected: boolean;
personDetected: boolean;
personName: string;
soundDetected: boolean;
petDetected: boolean;
cryingDetected: boolean;
ringing: boolean;
locked: boolean;
sensorOpen: boolean;
sensorChangeTime: number;
antitheftDetection: boolean;
autoNightvision: boolean;
ledStatus: boolean; // [added with schema version: 0+; removed with schema version: 4+]
motionDetection: boolean;
soundDetection: boolean;
petDetection: boolean;
rtspStream: boolean;
watermark: number;
lockStatus: number;
motionSensorPIREvent: number;
wifiRSSI: number;
pictureUrl: string;
type: number; // [added with schema version: 1+]
motionDetectionType: number; // [added with schema version: 3+]
motionDetectionSensivity: number; // [added with schema version: 3+; removed with schema version: 4+]
motionTracking: boolean; // [added with schema version: 3+]
soundDetectionType: number; // [added with schema version: 3+]
soundDetectionSensivity: number; // [added with schema version: 3+; removed with schema version: 4+]
light: boolean; // [added with schema version: 3+]
microphone: boolean; // [added with schema version: 3+]
speaker: boolean; // [added with schema version: 3+]
speakerVolume: number; // [added with schema version: 3+]
ringtoneVolume: number; // [added with schema version: 3+]
audioRecording: boolean; // [added with schema version: 3+]
powerSource: number; // [added with schema version: 3+]
powerWorkingMode: number; // [added with schema version: 3+]
recordingEndClipMotionStops: boolean; // [added with schema version: 3+]
recordingClipLength: number; // [added with schema version: 3+]
recordingRetriggerInterval: number; // [added with schema version: 3+]
videoStreamingQuality: number; // [added with schema version: 3+]
videoRecordingQuality: number; // [added with schema version: 3+]
videoWDR: boolean; // [added with schema version: 3+]
lightSettingsEnable: boolean; // [added with schema version: 3+]
lightSettingsBrightnessManual: number; // [added with schema version: 3+]
lightSettingsBrightnessMotion: number; // [added with schema version: 3+]
lightSettingsBrightnessSchedule: number; // [added with schema version: 3+]
lightSettingsMotionTriggered: boolean; // [added with schema version: 3+]
lightSettingsMotionTriggeredDistance: number; // [added with schema version: 3+]
lightSettingsMotionTriggeredTimer: number; // [added with schema version: 3+]
chimeIndoor: boolean; // [added with schema version: 3+]
chimeHomebase: boolean; // [added with schema version: 3+]
chimeHomebaseRingtoneVolume: number; // [added with schema version: 3+]
chimeHomebaseRingtoneType: number; // [added with schema version: 3+]
notificationType: number; // [added with schema version: 3+]
rotationSpeed: number; // [added with schema version: 3+]
notificationPerson: boolean; // [added with schema version: 3+]
notificationPet: boolean; // [added with schema version: 3+]
notificationAllOtherMotion: boolean; // [added with schema version: 3+]
notificationCrying: boolean; // [added with schema version: 3+]
notificationAllSound: boolean; // [added with schema version: 3+]
notificationIntervalTime: boolean; // [added with schema version: 3+]
notificationRing: boolean; // [added with schema version: 3+]
notificationMotion:boolean; // [added with schema version: 3+]
chirpVolume: number; // [added with schema version: 4+]
chirpTone: number; // [added with schema version: 4+]
motionDetectionSensitivity: number; // [added with schema version: 4+]
soundDetectionSensitivity: number; // [added with schema version: 4+]
videoHdr: boolean; // [added with schema version: 4+]
videoDistortionCorrection: boolean; // [added with schema version: 4+]
videoRingRecord: number; // [added with schema version: 4+]
statusLed: boolean; // [added with schema version: 4+]
chargingStatus: number; // [added with schema version: 4+]
rtspStreamUrl: string; // [added with schema version: 4+]
wifiSignalLevel: number; // [added with schema version: 4+]
nightvision: number; // [added with schema version: 5+]
batteryIsCharging: boolean; // [added with schema version: 5+]
}
}
}
[compatible with schema version: 0+]
This event is sent whenever a motion is detected on the device (the cooldown is determined by the eventDurationSeconds
param).
interface {
type: "event";
event: {
source: "device";
event: "motion detected";
serialNumber: string;
state: boolean;
}
}
[compatible with schema version: 0+]
This event is sent whenever a person is detected on the device (the cooldown is determined by the eventDurationSeconds
param).
interface {
type: "event";
event: {
source: "device";
event: "person detected";
serialNumber: string;
state: boolean;
person: string;
}
}
[compatible with schema version: 0+]
This event is sent whenever a crying is detected on the device (the cooldown is determined by the eventDurationSeconds
param).
interface {
type: "event";
event: {
source: "device";
event: "crying detected";
serialNumber: string;
state: boolean;
}
}
[compatible with schema version: 0+]
This event is sent whenever sound is detected on the device (the cooldown is determined by the eventDurationSeconds
param).
interface {
type: "event";
event: {
source: "device";
event: "sound detected";
serialNumber: string;
state: boolean;
}
}
[compatible with schema version: 0+]
This event is sent whenever a pet is detected on the device (the cooldown is determined by the eventDurationSeconds
param).
interface {
type: "event";
event: {
source: "device";
event: "pet detected";
serialNumber: string;
state: boolean;
}
}
[compatible with schema version: 0+]
This event is sent whenever the device is ringing (the cooldown is determined by the eventDurationSeconds
param).
interface {
type: "event";
event: {
source: "device";
event: "rings";
serialNumber: string;
state: boolean;
}
}
[compatible with schema version: 0+]
This event is sent whenever the device is opened/closed (the cooldown is determined by the eventDurationSeconds
param).
interface {
type: "event";
event: {
source: "device";
event: "sensor open";
serialNumber: string;
state: boolean;
}
}
[compatible with schema version: 0+]
This event is sent after each execution of a p2p command and reflects the result of the command.
interface {
type: "event";
event: {
source: "device";
event: "command result";
serialNumber: string;
command: string;
returnCode: number;
returnCodeName: string;
}
}
[compatible with schema version: 0+]
This event is sent after RTSP is enabled on the supported device.
interface {
type: "event";
event: {
source: "device";
event: "got rtsp url";
serialNumber: string;
rtspUrl: string;
}
}
[compatible with schema version: 0+]
This event is sent whenever a property of a device is changed.
interface {
type: "event";
event: {
source: "device";
event: "property changed";
serialNumber: string;
name: string;
value: JSONValue;
timestamp: number;
}
}
[compatible with schema version: 2+]
This event is sent whenever the live stream of a device is started.
interface {
type: "event";
event: {
source: "device";
event: "livestream started";
serialNumber: string;
}
}
[compatible with schema version: 2+]
This event is sent whenever the live stream of a device is stopped.
interface {
type: "event";
event: {
source: "device";
event: "livestream stopped";
serialNumber: string;
}
}
[compatible with schema version: 2+]
This event is sent when video data is received during an active live stream of a device. It contains the metadata information and the video chunck.
interface {
type: "event";
event: {
source: "device";
event: "livestream video data";
serialNumber: string;
buffer: JSONValue,
metadata: {
videoCodec: string;
videoFPS: number;
videoHeight: number;
videoWidth: number;
}
}
}
[compatible with schema version: 2+]
This event is sent when audio data is received during an active live stream of a device. It contains the metadata information and the video chunck.
interface {
type: "event";
event: {
source: "device";
event: "livestream audio data";
serialNumber: string;
buffer: JSONValue,
metadata: {
audioCodec: string;
}
}
}
[compatible with schema version: 3+]
This event is sent whenever a video download is started.
interface {
type: "event";
event: {
source: "device";
event: "download started";
serialNumber: string;
}
}
[compatible with schema version: 3+]
This event is sent whenever a video download is finished.
interface {
type: "event";
event: {
source: "device";
event: "download finished";
serialNumber: string;
}
}
[compatible with schema version: 3+]
This event is sent when video data is received during a video download. It contains the metadata information and the video chunck.
interface {
type: "event";
event: {
source: "device";
event: "download video data";
serialNumber: string;
buffer: JSONValue,
metadata: {
videoCodec: string;
videoFPS: number;
videoHeight: number;
videoWidth: number;
}
}
}
[compatible with schema version: 3+]
This event is sent when audio data is received during a video download. It contains the metadata information and the video chunck.
interface {
type: "event";
event: {
source: "device";
event: "download audio data";
serialNumber: string;
buffer: JSONValue,
metadata: {
audioCodec: string;
}
}
}
In an attempt to keep compatibility between different server and client versions, we've introduced a (basic) API Schema Version.
-
client connects --> server sends back version info including the schema versions it can handle:
{ "type": "version", "driverVersion": "0.8.0", "serverVersion": "0.1.0", "minSchemaVersion": 0, "maxSchemaVersion": 1 }
-
Client decides what to do based on supported schema version. For example drop connection if the supported server schema is too old or just handle the supported schema itself. For example most/all basic commands will just work but relatively new commands won't and the client decides to only not handle the stuff in the upgraded schema.
-
Client needs to tell the server what schema it wants to use. This is done with the "set_api_schema" command:
{ "command": "set_api_schema", "messageId": 1, "schemaVersion": 1 }
From this moment the server knows how to treat commands to/from this client. The server can handle multiple clients with different schema versions.
-
By default the server will use the minimum schema it supports (which is 0 at this time) if the
set_api_schema
command is omitted. -
If the client sends a schema version which is out of range, this will produce an error to the client and in the server's log:
{ "command": "set_api_schema", "messageId": 1, "schemaVersion": 4 } {"type":"result","success":false,"messageId":1,"errorCode":"schema_incompatible"}
-
When we make breaking changes in the api, we bump the schema version. When adding new commands/features, we also bump the api schema and note in both code comments and documentation to which schema version that feature is compatible with.
eufy-security-ws does not handle authentication and allows all connections to the websocket API. If you want to add authentication, add authentication middleware to your Express instance or run NGINX in front of Express instance.
eufy-security-ws is available via a Docker image
(bropat/eufy-security-ws
). It is configured by a handful of environment variables that correspond to the options found in the config file above:
USERNAME:
Eufy Account Username (required)PASSWORD:
Eufy Account Password (required)COUNTRY:
ISO 3166-1 Alpha-2 country code (default: US)LANGUAGE:
ISO 639 language code (default: en)TRUSTED_DEVICE_NAME:
Label of the trusted devices (viewable with 2fa activated in Eufy App; default: eufyclient)EVENT_DURATION_SECONDS:
Duration in seconds before an event is reset E.g. motion event (default: 10 sec.)P2P_CONNECTION_SETUP:
P2P connection setup (default: 0 ; Prefers local connection over cloud)POLLING_INTERVAL_MINUTES:
Polling intervall for data refresh from Eufy Cloud (default: 10 min.)ACCEPT_INVITATIONS:
Automatically accept device invitations (default: false)DEBUG:
When the variable is set, debug mode is activated (default: unset)
The image also exposes a /data
volume that corresponds to the persistentDir
.
Running the image is straightforward:
docker run -it \
-e USERNAME=user \
-e PASSWORD=password \
-v "$(PWD)"/data:/data \
-p 3000:0000 \
bropat/eufy-security-ws:latest