homebridge-tryfi 1.1.0
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/CHANGELOG.md +43 -0
- package/CHANGES-V3.md +103 -0
- package/LICENSE +201 -0
- package/README.md +139 -0
- package/SUMMARY.md +289 -0
- package/config.schema.json +91 -0
- package/dist/accessory.d.ts +31 -0
- package/dist/accessory.d.ts.map +1 -0
- package/dist/accessory.js +134 -0
- package/dist/accessory.js.map +1 -0
- package/dist/api.d.ts +37 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +365 -0
- package/dist/api.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +41 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +168 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.d.ts +9 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +12 -0
- package/dist/settings.js.map +1 -0
- package/dist/types.d.ts +118 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -0
- package/src/accessory.ts +172 -0
- package/src/api.ts +409 -0
- package/src/index.ts +10 -0
- package/src/platform.ts +220 -0
- package/src/settings.ts +9 -0
- package/src/types.ts +119 -0
- package/tsconfig.json +25 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { PlatformConfig } from 'homebridge';
|
|
2
|
+
/**
|
|
3
|
+
* TryFi Platform Configuration
|
|
4
|
+
*/
|
|
5
|
+
export interface TryFiPlatformConfig extends PlatformConfig {
|
|
6
|
+
username: string;
|
|
7
|
+
password: string;
|
|
8
|
+
pollingInterval?: number;
|
|
9
|
+
escapeAlertType?: 'leak' | 'motion';
|
|
10
|
+
ignoredPets?: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* TryFi Session Information
|
|
14
|
+
*/
|
|
15
|
+
export interface TryFiSession {
|
|
16
|
+
userId: string;
|
|
17
|
+
sessionId: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* TryFi Pet Data (processed from API response)
|
|
21
|
+
*/
|
|
22
|
+
export interface TryFiPet {
|
|
23
|
+
petId: string;
|
|
24
|
+
name: string;
|
|
25
|
+
breed: string;
|
|
26
|
+
moduleId: string;
|
|
27
|
+
batteryPercent: number;
|
|
28
|
+
isCharging: boolean;
|
|
29
|
+
ledEnabled: boolean;
|
|
30
|
+
mode: string;
|
|
31
|
+
connectedToUser: string | null;
|
|
32
|
+
latitude: number;
|
|
33
|
+
longitude: number;
|
|
34
|
+
areaName: string | null;
|
|
35
|
+
placeName: string | null;
|
|
36
|
+
placeAddress: string | null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* GraphQL Response Wrapper
|
|
40
|
+
*/
|
|
41
|
+
export interface GraphQLResponse<T> {
|
|
42
|
+
data?: T;
|
|
43
|
+
errors?: Array<{
|
|
44
|
+
message: string;
|
|
45
|
+
locations?: Array<{
|
|
46
|
+
line: number;
|
|
47
|
+
column: number;
|
|
48
|
+
}>;
|
|
49
|
+
path?: string[];
|
|
50
|
+
}>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* CurrentUser Query Response - matches pytryfi structure
|
|
54
|
+
*/
|
|
55
|
+
export interface CurrentUserResponse {
|
|
56
|
+
currentUser: {
|
|
57
|
+
__typename: string;
|
|
58
|
+
id: string;
|
|
59
|
+
email: string;
|
|
60
|
+
firstName: string;
|
|
61
|
+
lastName: string;
|
|
62
|
+
userHouseholds: Array<{
|
|
63
|
+
__typename: string;
|
|
64
|
+
household: {
|
|
65
|
+
__typename: string;
|
|
66
|
+
pets: Array<{
|
|
67
|
+
__typename: string;
|
|
68
|
+
id: string;
|
|
69
|
+
name: string;
|
|
70
|
+
homeCityState?: string;
|
|
71
|
+
gender?: string;
|
|
72
|
+
breed?: {
|
|
73
|
+
__typename: string;
|
|
74
|
+
id: string;
|
|
75
|
+
name: string;
|
|
76
|
+
};
|
|
77
|
+
device?: {
|
|
78
|
+
__typename: string;
|
|
79
|
+
id: string;
|
|
80
|
+
moduleId: string;
|
|
81
|
+
info: any;
|
|
82
|
+
operationParams?: {
|
|
83
|
+
__typename: string;
|
|
84
|
+
mode: string;
|
|
85
|
+
ledEnabled: boolean;
|
|
86
|
+
ledOffAt?: string;
|
|
87
|
+
};
|
|
88
|
+
lastConnectionState?: {
|
|
89
|
+
__typename: string;
|
|
90
|
+
date: string;
|
|
91
|
+
} | {
|
|
92
|
+
__typename: 'ConnectedToUser';
|
|
93
|
+
date: string;
|
|
94
|
+
user: {
|
|
95
|
+
__typename: string;
|
|
96
|
+
id: string;
|
|
97
|
+
firstName: string;
|
|
98
|
+
lastName: string;
|
|
99
|
+
};
|
|
100
|
+
} | {
|
|
101
|
+
__typename: 'ConnectedToBase';
|
|
102
|
+
date: string;
|
|
103
|
+
chargingBase: {
|
|
104
|
+
__typename: string;
|
|
105
|
+
id: string;
|
|
106
|
+
};
|
|
107
|
+
} | {
|
|
108
|
+
__typename: 'ConnectedToCellular';
|
|
109
|
+
date: string;
|
|
110
|
+
signalStrengthPercent: number;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
}>;
|
|
114
|
+
};
|
|
115
|
+
}>;
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "homebridge-tryfi",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Homebridge plugin for TryFi Dog GPS Collars",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc",
|
|
8
|
+
"watch": "tsc -w",
|
|
9
|
+
"prepublishOnly": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"homebridge-plugin",
|
|
13
|
+
"tryfi",
|
|
14
|
+
"dog",
|
|
15
|
+
"gps",
|
|
16
|
+
"collar",
|
|
17
|
+
"pet tracker"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18.0.0",
|
|
21
|
+
"homebridge": ">=1.6.0"
|
|
22
|
+
},
|
|
23
|
+
"author": "Dave Linger",
|
|
24
|
+
"license": "Apache-2.0",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/DaveLinger/homebridge-tryfi.git"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/DaveLinger/homebridge-tryfi/issues"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"axios": "^1.6.0",
|
|
34
|
+
"axios-cookiejar-support": "^6.0.5",
|
|
35
|
+
"tough-cookie": "^6.0.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^20.0.0",
|
|
39
|
+
"homebridge": "^1.6.0",
|
|
40
|
+
"typescript": "^5.0.0"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/accessory.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Service, PlatformAccessory, CharacteristicValue } from 'homebridge';
|
|
2
|
+
import { TryFiPlatform } from './platform';
|
|
3
|
+
import { TryFiPet } from './types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TryFi Collar Accessory
|
|
7
|
+
* Represents a single dog collar with multiple HomeKit services
|
|
8
|
+
*/
|
|
9
|
+
export class TryFiCollarAccessory {
|
|
10
|
+
private escapeAlertService: Service;
|
|
11
|
+
private batteryService: Service;
|
|
12
|
+
private lightbulbService: Service;
|
|
13
|
+
private lostDogSwitchService: Service;
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly platform: TryFiPlatform,
|
|
17
|
+
private readonly accessory: PlatformAccessory,
|
|
18
|
+
private pet: TryFiPet,
|
|
19
|
+
) {
|
|
20
|
+
// Set accessory information
|
|
21
|
+
this.accessory.getService(this.platform.Service.AccessoryInformation)!
|
|
22
|
+
.setCharacteristic(this.platform.Characteristic.Manufacturer, 'TryFi')
|
|
23
|
+
.setCharacteristic(this.platform.Characteristic.Model, 'GPS Dog Collar')
|
|
24
|
+
.setCharacteristic(this.platform.Characteristic.SerialNumber, pet.moduleId)
|
|
25
|
+
.setCharacteristic(this.platform.Characteristic.FirmwareRevision, '1.0.0');
|
|
26
|
+
|
|
27
|
+
// Get or create services
|
|
28
|
+
const escapeAlertType = this.platform.config.escapeAlertType || 'leak';
|
|
29
|
+
|
|
30
|
+
if (escapeAlertType === 'leak') {
|
|
31
|
+
this.escapeAlertService = this.accessory.getService(this.platform.Service.LeakSensor) ||
|
|
32
|
+
this.accessory.addService(this.platform.Service.LeakSensor);
|
|
33
|
+
this.escapeAlertService.setCharacteristic(this.platform.Characteristic.Name, `${pet.name} Escape Alert`);
|
|
34
|
+
} else {
|
|
35
|
+
this.escapeAlertService = this.accessory.getService(this.platform.Service.MotionSensor) ||
|
|
36
|
+
this.accessory.addService(this.platform.Service.MotionSensor);
|
|
37
|
+
this.escapeAlertService.setCharacteristic(this.platform.Characteristic.Name, `${pet.name} Escape Alert`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.batteryService = this.accessory.getService(this.platform.Service.Battery) ||
|
|
41
|
+
this.accessory.addService(this.platform.Service.Battery);
|
|
42
|
+
this.batteryService.setCharacteristic(this.platform.Characteristic.Name, `${pet.name} Battery`);
|
|
43
|
+
|
|
44
|
+
this.lightbulbService = this.accessory.getService(this.platform.Service.Lightbulb) ||
|
|
45
|
+
this.accessory.addService(this.platform.Service.Lightbulb);
|
|
46
|
+
this.lightbulbService.setCharacteristic(this.platform.Characteristic.Name, `${pet.name} LED Light`);
|
|
47
|
+
|
|
48
|
+
this.lostDogSwitchService = this.accessory.getService(this.platform.Service.Switch) ||
|
|
49
|
+
this.accessory.addService(this.platform.Service.Switch);
|
|
50
|
+
this.lostDogSwitchService.setCharacteristic(this.platform.Characteristic.Name, `${pet.name} Lost Dog Mode`);
|
|
51
|
+
|
|
52
|
+
// Set up characteristic handlers
|
|
53
|
+
this.setupCharacteristics();
|
|
54
|
+
|
|
55
|
+
// Initial update
|
|
56
|
+
this.updateCharacteristics();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private setupCharacteristics() {
|
|
60
|
+
// LED Light handlers
|
|
61
|
+
this.lightbulbService.getCharacteristic(this.platform.Characteristic.On)
|
|
62
|
+
.onGet(this.handleLightGet.bind(this))
|
|
63
|
+
.onSet(this.handleLightSet.bind(this));
|
|
64
|
+
|
|
65
|
+
// Lost Dog Mode handlers
|
|
66
|
+
this.lostDogSwitchService.getCharacteristic(this.platform.Characteristic.On)
|
|
67
|
+
.onGet(this.handleLostModeGet.bind(this))
|
|
68
|
+
.onSet(this.handleLostModeSet.bind(this));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Update all characteristics from latest pet data
|
|
73
|
+
*/
|
|
74
|
+
updateCharacteristics() {
|
|
75
|
+
const escapeAlertType = this.platform.config.escapeAlertType || 'leak';
|
|
76
|
+
|
|
77
|
+
// Escape Alert: Triggered when NOT in safe zone AND NOT with owner
|
|
78
|
+
const isEscaped = (this.pet.placeName === null) && (this.pet.connectedToUser === null);
|
|
79
|
+
|
|
80
|
+
if (escapeAlertType === 'leak') {
|
|
81
|
+
this.escapeAlertService.updateCharacteristic(
|
|
82
|
+
this.platform.Characteristic.LeakDetected,
|
|
83
|
+
isEscaped
|
|
84
|
+
? this.platform.Characteristic.LeakDetected.LEAK_DETECTED
|
|
85
|
+
: this.platform.Characteristic.LeakDetected.LEAK_NOT_DETECTED,
|
|
86
|
+
);
|
|
87
|
+
} else {
|
|
88
|
+
this.escapeAlertService.updateCharacteristic(
|
|
89
|
+
this.platform.Characteristic.MotionDetected,
|
|
90
|
+
isEscaped,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Battery Service
|
|
95
|
+
this.batteryService.updateCharacteristic(
|
|
96
|
+
this.platform.Characteristic.BatteryLevel,
|
|
97
|
+
this.pet.batteryPercent,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
this.batteryService.updateCharacteristic(
|
|
101
|
+
this.platform.Characteristic.ChargingState,
|
|
102
|
+
this.pet.isCharging
|
|
103
|
+
? this.platform.Characteristic.ChargingState.CHARGING
|
|
104
|
+
: this.platform.Characteristic.ChargingState.NOT_CHARGING,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
this.batteryService.updateCharacteristic(
|
|
108
|
+
this.platform.Characteristic.StatusLowBattery,
|
|
109
|
+
this.pet.batteryPercent < 20
|
|
110
|
+
? this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW
|
|
111
|
+
: this.platform.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL,
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// LED Light
|
|
115
|
+
this.lightbulbService.updateCharacteristic(
|
|
116
|
+
this.platform.Characteristic.On,
|
|
117
|
+
this.pet.ledEnabled,
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Lost Dog Mode
|
|
121
|
+
this.lostDogSwitchService.updateCharacteristic(
|
|
122
|
+
this.platform.Characteristic.On,
|
|
123
|
+
this.pet.mode === 'LOST_DOG',
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
this.platform.log.debug(`Updated ${this.pet.name}: Battery ${this.pet.batteryPercent}%, ` +
|
|
127
|
+
`LED ${this.pet.ledEnabled ? 'On' : 'Off'}, Mode ${this.pet.mode}, ` +
|
|
128
|
+
`Escaped: ${isEscaped}, Place: ${this.pet.placeName}, With: ${this.pet.connectedToUser}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Update pet data and refresh characteristics
|
|
133
|
+
*/
|
|
134
|
+
updatePetData(pet: TryFiPet) {
|
|
135
|
+
this.pet = pet;
|
|
136
|
+
this.updateCharacteristics();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// LED Light Handlers
|
|
140
|
+
async handleLightGet(): Promise<CharacteristicValue> {
|
|
141
|
+
return this.pet.ledEnabled;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async handleLightSet(value: CharacteristicValue) {
|
|
145
|
+
const ledEnabled = value as boolean;
|
|
146
|
+
try {
|
|
147
|
+
await this.platform.api.setLedState(this.pet.moduleId, ledEnabled);
|
|
148
|
+
this.pet.ledEnabled = ledEnabled;
|
|
149
|
+
this.platform.log.info(`Set ${this.pet.name} LED to ${ledEnabled ? 'On' : 'Off'}`);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
this.platform.log.error(`Failed to set LED for ${this.pet.name}:`, error);
|
|
152
|
+
throw new this.platform.homebridgeApi.hap.HapStatusError(this.platform.homebridgeApi.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Lost Dog Mode Handlers
|
|
157
|
+
async handleLostModeGet(): Promise<CharacteristicValue> {
|
|
158
|
+
return this.pet.mode === 'LOST_DOG';
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async handleLostModeSet(value: CharacteristicValue) {
|
|
162
|
+
const isLost = value as boolean;
|
|
163
|
+
try {
|
|
164
|
+
await this.platform.api.setLostDogMode(this.pet.moduleId, isLost);
|
|
165
|
+
this.pet.mode = isLost ? 'LOST_DOG' : 'NORMAL';
|
|
166
|
+
this.platform.log.info(`Set ${this.pet.name} Lost Dog Mode to ${isLost ? 'On' : 'Off'}`);
|
|
167
|
+
} catch (error) {
|
|
168
|
+
this.platform.log.error(`Failed to set Lost Dog Mode for ${this.pet.name}:`, error);
|
|
169
|
+
throw new this.platform.homebridgeApi.hap.HapStatusError(this.platform.homebridgeApi.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|