diff --git a/docs/supported_devices.md b/docs/supported_devices.md index dadb195b..fac1e967 100644 --- a/docs/supported_devices.md +++ b/docs/supported_devices.md @@ -30,6 +30,7 @@ | ![T8B0 image](_media/solocamc210_small.jpg) | SoloCam C210 (T8B0) | :heavy_check_mark: | Firmware: 3.2.3.5 (20231218) | | ![T8124 image](_media/solocams40_small.jpg) | SoloCam S230 (T8124; SoloCam S40) | :heavy_check_mark: | | | ![T8B0 image](_media/solocamc35_small.jpg) | SoloCam C35 (T8110) | :heavy_check_mark: | Firmware: 1.1.2.5 (20231218) | +| ![T814X image](_media/solocams340_small.jpg) | eufyCam C37 (T814X) | :wrench: | Firmware: 1.0.7.2; 360° outdoor pan & tilt, HomeBase Mini (T8025) controlled | | ![T8134 image](_media/solocams220_small.jpg) | SoloCam S220 (T8134) | :heavy_check_mark: | | | ![T8170 image](_media/solocams340_small.jpg) | SoloCam S340 (T8170) | :heavy_check_mark: | Firmware: 3.0.9.6 (20231125) | | ![T8171 image](_media/solocame30_small.jpg) | SoloCam E30 (T8171) | :wrench: | | diff --git a/src/http/device.ts b/src/http/device.ts index 9d66929c..3a6c4798 100644 --- a/src/http/device.ts +++ b/src/http/device.ts @@ -1203,7 +1203,8 @@ export class Device extends TypedEmitter { (property.name === PropertyName.DeviceMotionDetectionTypeHuman || property.name === PropertyName.DeviceMotionDetectionTypeVehicle || property.name === PropertyName.DeviceMotionDetectionTypeAllOtherMotions) && - this.isOutdoorPanAndTiltCamera() + this.isOutdoorPanAndTiltCamera() && + !this.isCameraC37() ) { const booleanProperty = property as PropertyMetadataBoolean; try { @@ -1230,7 +1231,7 @@ export class Device extends TypedEmitter { property.name === PropertyName.DeviceMotionDetectionTypePet || property.name === PropertyName.DeviceMotionDetectionTypeVehicle || property.name === PropertyName.DeviceMotionDetectionTypeAllOtherMotions) && - this.isCameraC35() + (this.isCameraC35() || this.isCameraC37()) ) { const booleanProperty = property as PropertyMetadataBoolean; try { @@ -1904,6 +1905,7 @@ export class Device extends TypedEmitter { type == DeviceType.INDOOR_CAMERA_1080 || type == DeviceType.INDOOR_PT_CAMERA_1080 || type == DeviceType.OUTDOOR_PT_CAMERA || + type == DeviceType.CAMERA_C37 || type == DeviceType.SOLO_CAMERA || type == DeviceType.SOLO_CAMERA_PRO || type == DeviceType.SOLO_CAMERA_SPOTLIGHT_1080 || @@ -1993,6 +1995,7 @@ export class Device extends TypedEmitter { type == DeviceType.WALL_LIGHT_CAM_81A0 || type == DeviceType.SMART_DROP || type == DeviceType.OUTDOOR_PT_CAMERA || + type == DeviceType.CAMERA_C37 || type == DeviceType.SOLOCAM_E42 || type == DeviceType.ENTRY_SENSOR_E20 ); @@ -2099,6 +2102,7 @@ export class Device extends TypedEmitter { type == DeviceType.FLOODLIGHT_CAMERA_8426 || type == DeviceType.INDOOR_COST_DOWN_CAMERA || type == DeviceType.OUTDOOR_PT_CAMERA || + type == DeviceType.CAMERA_C37 || type == DeviceType.CAMERA_S4 || type == DeviceType.SOLOCAM_E42 || type == DeviceType.CAMERA_4G_S330 || @@ -2116,6 +2120,7 @@ export class Device extends TypedEmitter { static isOutdoorPanAndTiltCamera(type: number): boolean { if ( type == DeviceType.OUTDOOR_PT_CAMERA || + type == DeviceType.CAMERA_C37 || type == DeviceType.SOLO_CAMERA_E30 || type == DeviceType.CAMERA_S4 || type == DeviceType.SOLOCAM_E42 || @@ -2374,6 +2379,10 @@ export class Device extends TypedEmitter { return DeviceType.CAMERA_C35 == type; } + static isCameraC37(type: number): boolean { + return DeviceType.CAMERA_C37 == type; + } + static isIndoorPTCameraE30(type: number): boolean { return DeviceType.INDOOR_PT_CAMERA_E30 == type; } @@ -2848,6 +2857,10 @@ export class Device extends TypedEmitter { return Device.isCameraC35(this.rawDevice.device_type); } + public isCameraC37(): boolean { + return Device.isCameraC37(this.rawDevice.device_type); + } + public isIndoorPTCameraE30(): boolean { return Device.isIndoorPTCameraE30(this.rawDevice.device_type); } diff --git a/src/http/station.ts b/src/http/station.ts index 7d84be2d..b04ad463 100644 --- a/src/http/station.ts +++ b/src/http/station.ts @@ -3203,7 +3203,7 @@ export class Station extends TypedEmitter { deviceSN: device.getSerial(), }); } - } else if (device.isOutdoorPanAndTiltCamera()) { + } else if (device.isOutdoorPanAndTiltCamera() && !device.isCameraC37()) { try { if (!Object.values(T8170DetectionTypes).includes(type as T8170DetectionTypes)) { rootHTTPLogger.error( @@ -3255,7 +3255,7 @@ export class Station extends TypedEmitter { deviceSN: device.getSerial(), }); } - } else if (device.isCameraC35()) { + } else if (device.isCameraC35() || device.isCameraC37()) { try { if (!Object.values(EufyCamC35DetectionTypes).includes(type as EufyCamC35DetectionTypes)) { rootHTTPLogger.error( diff --git a/src/http/types.ts b/src/http/types.ts index 768e3e0c..accd84a4 100644 --- a/src/http/types.ts +++ b/src/http/types.ts @@ -110,6 +110,7 @@ export enum DeviceType { INDOOR_PT_CAMERA_C220_V2 = 10010, // T8W11C (Type 10010) INDOOR_PT_CAMERA_C220_V3 = 10011, // T8419N CAMERA_C35 = 10035, //T8110 + CAMERA_C37 = 10037, //T814X (eufyCam C37, 360° outdoor pan & tilt, HomeBase Mini controlled) } export enum ParamType { @@ -1082,6 +1083,7 @@ export const GenericTypeProperty: PropertyMetadataNumeric = { 10010: "Indoor Cam C220 (T8W11C)", 10011: "Indoor Cam C220 (T8419N)", 10035: "eufyCam C35 (T8110)", + 10037: "eufyCam C37 (T814X)", }, }; @@ -8831,6 +8833,13 @@ export const DeviceProperties: Properties = { DeviceProperties[DeviceType.INDOOR_PT_CAMERA_C220_V2] = DeviceProperties[DeviceType.INDOOR_PT_CAMERA_C220]; DeviceProperties[DeviceType.INDOOR_PT_CAMERA_C220_V3] = DeviceProperties[DeviceType.INDOOR_PT_CAMERA_C220]; +// eufyCam C37 (T814X): 360° outdoor pan & tilt battery/solar cam, modeled on the outdoor pan & tilt +// camera, plus pet detection (the C37 additionally supports human/pet/vehicle, handled via the C35 path). +DeviceProperties[DeviceType.CAMERA_C37] = { + ...DeviceProperties[DeviceType.OUTDOOR_PT_CAMERA], + [PropertyName.DeviceMotionDetectionTypePet]: DeviceMotionHB3DetectionTypePetProperty, + [PropertyName.DevicePetDetected]: DevicePetDetectedProperty, +}; export const StationNameProperty: PropertyMetadataString = { key: "station_name", @@ -10867,6 +10876,7 @@ export const DeviceCommands: Commands = { DeviceCommands[DeviceType.INDOOR_PT_CAMERA_C220_V2] = DeviceCommands[DeviceType.INDOOR_PT_CAMERA_C220]; DeviceCommands[DeviceType.INDOOR_PT_CAMERA_C220_V3] = DeviceCommands[DeviceType.INDOOR_PT_CAMERA_C220]; +DeviceCommands[DeviceType.CAMERA_C37] = DeviceCommands[DeviceType.OUTDOOR_PT_CAMERA]; export const StationCommands: Commands = { [DeviceType.STATION]: [