11"use strict" ;
22
3- import Homey from "homey" ;
3+ import { OAuth2App } from "homey-oauth2app " ;
44import { Products , Teslemetry } from "@teslemetry/api" ;
5+ import TeslemetryOAuth2Client from "./lib/TeslemetryOAuth2Client.js" ;
6+
7+ export default class TeslemetryApp extends OAuth2App {
8+ // OAuth2App configuration
9+ static OAUTH2_CLIENT = TeslemetryOAuth2Client ;
10+ static OAUTH2_DEBUG = true ;
11+ static OAUTH2_MULTI_SESSION = false ;
12+ static OAUTH2_DRIVERS = [ "vehicle" , "powerwall" , "wall-connector" ] ;
513
6- export default class TeslemetryApp extends Homey . App {
714 teslemetry ?: Teslemetry ;
815 products ?: Products ;
916 private initializationPromise ?: Promise < void > ;
1017
1118 /**
12- * onInit is called when the app is initialized.
19+ * onOAuth2Init is called when the OAuth2App is initialized
1320 */
14- async onInit ( ) {
15- this . homey . log ( "Teslemetry app initializing..." ) ;
21+ async onOAuth2Init ( ) {
22+ this . homey . log ( "Teslemetry OAuth2 app initializing..." ) ;
1623
17- // Register API routes for settings page
24+ // Register API routes for testing (if needed for settings page)
1825 this . homey . api . on (
19- "test " ,
20- (
21- args : { token : string } ,
26+ "test_oauth " ,
27+ async (
28+ args : { sessionId ? : string } ,
2229 callback : ( err : Error | null , result ?: boolean ) => void ,
2330 ) => {
24- const teslemetry = new Teslemetry ( args . token ) ;
25- teslemetry . api
26- . test ( )
27- . then ( ( { response } ) => {
28- callback ( null , response ) ;
29- } )
30- . catch ( ( error ) => {
31- callback ( null , false ) ;
32- } ) ;
31+ try {
32+ const sessionId =
33+ args . sessionId || this . getFirstSavedOAuth2SessionId ( ) ;
34+ if ( ! sessionId ) {
35+ callback ( new Error ( "No OAuth2 session available" ) ) ;
36+ return ;
37+ }
38+
39+ const client = this . getOAuth2Client ( { sessionId } ) ;
40+
41+ // Test with Teslemetry SDK using access token
42+ const accessToken = await client . getAccessToken ( ) ;
43+ const teslemetry = new Teslemetry ( accessToken ) ;
44+ const result = await teslemetry . api . test ( ) ;
45+ callback ( null , ! ! result . response ) ;
46+ } catch ( error ) {
47+ this . homey . error ( "OAuth test failed:" , error ) ;
48+ callback ( null , false ) ;
49+ }
3350 } ,
3451 ) ;
3552
36- // Listen for settings changes
37- this . homey . settings . on ( "set" , ( key : string ) => {
38- if ( key === "access_token" ) {
39- this . homey . log ( "Access token updated, reinitializing..." ) ;
40- this . reinitialize ( ) ;
41- }
42- } ) ;
43-
44- // Initialize the Teslemetry connection
53+ // Initialize the Teslemetry SDK connection using OAuth2 token
4554 await this . initializeTeslemetry ( ) ;
4655 }
4756
4857 /**
49- * Initialize Teslemetry connection with current access token
58+ * Initialize Teslemetry connection with OAuth2 token
5059 */
5160 private async initializeTeslemetry ( ) : Promise < void > {
5261 try {
53- const accessToken = this . homey . settings . get ( "access_token" ) as string ;
54-
55- if ( ! accessToken ) {
62+ // Get the first available OAuth2 session
63+ const sessionId = this . getFirstSavedOAuth2SessionId ( ) ;
64+ if ( ! sessionId ) {
5665 this . homey . log (
57- "No access token configured. Please configure in app settings ." ,
66+ "No OAuth2 session available. User needs to authenticate ." ,
5867 ) ;
5968 return ;
6069 }
6170
62- this . homey . log ( "Initializing Teslemetry with access token..." ) ;
71+ const client = this . getOAuth2Client ( { sessionId } ) ;
72+
73+ this . homey . log ( "Initializing Teslemetry with OAuth2 token..." ) ;
74+ const accessToken = await client . getAccessToken ( ) ;
6375 this . teslemetry = new Teslemetry ( accessToken ) ;
6476 this . products = await this . teslemetry . createProducts ( ) ;
6577
@@ -78,7 +90,29 @@ export default class TeslemetryApp extends Homey.App {
7890 }
7991
8092 /**
81- * Reinitialize the app when settings change
93+ * Called when OAuth2 session is created or updated
94+ */
95+ async onOAuth2Saved ( { sessionId } : { sessionId : string } ) {
96+ this . homey . log ( `OAuth2 session saved: ${ sessionId } ` ) ;
97+ await this . reinitialize ( ) ;
98+ }
99+
100+ /**
101+ * Called when OAuth2 session is deleted
102+ */
103+ async onOAuth2Deleted ( { sessionId } : { sessionId : string } ) {
104+ this . homey . log ( `OAuth2 session deleted: ${ sessionId } ` ) ;
105+
106+ // Clean up Teslemetry connection
107+ if ( this . teslemetry ) {
108+ this . teslemetry . sse . close ( ) ;
109+ this . teslemetry = undefined ;
110+ this . products = undefined ;
111+ }
112+ }
113+
114+ /**
115+ * Reinitialize the app when OAuth2 session changes
82116 */
83117 private async reinitialize ( ) : Promise < void > {
84118 // Prevent multiple simultaneous initializations
@@ -95,7 +129,7 @@ export default class TeslemetryApp extends Homey.App {
95129 this . products = undefined ;
96130 }
97131
98- // Initialize with new settings
132+ // Initialize with new OAuth2 session
99133 await this . initializeTeslemetry ( ) ;
100134 } catch ( error ) {
101135 this . homey . error ( "Failed to reinitialize:" , error ) ;
@@ -128,15 +162,41 @@ export default class TeslemetryApp extends Homey.App {
128162 }
129163
130164 /**
131- * Check if the app is properly configured
165+ * Check if the app is properly configured with OAuth2
132166 */
133167 isConfigured ( ) : boolean {
134- const accessToken = this . homey . settings . get ( "access_token" ) as string ;
135- return ! ! accessToken && ! ! this . teslemetry && ! ! this . products ;
168+ const sessionId = this . getFirstSavedOAuth2SessionId ( ) ;
169+ if ( ! sessionId ) return false ;
170+
171+ const session = this . getSavedOAuth2SessionBySessionId ( sessionId ) ;
172+ return ! ! ( session && session . token && this . teslemetry && this . products ) ;
173+ }
174+
175+ /**
176+ * Get OAuth2 client for API calls
177+ */
178+ getOAuth2Client ( {
179+ sessionId,
180+ } : { sessionId ?: string } = { } ) : TeslemetryOAuth2Client {
181+ const actualSessionId = sessionId || this . getFirstSavedOAuth2SessionId ( ) ;
182+ if ( ! actualSessionId ) {
183+ throw new Error ( "No OAuth2 session available" ) ;
184+ }
185+ return super . getOAuth2Client ( {
186+ sessionId : actualSessionId ,
187+ } ) as TeslemetryOAuth2Client ;
188+ }
189+
190+ /**
191+ * Get a token function for the Teslemetry SDK
192+ */
193+ getTokenFunction ( sessionId ?: string ) : ( ) => Promise < string > {
194+ const client = this . getOAuth2Client ( { sessionId } ) ;
195+ return ( ) => client . getAccessToken ( ) ;
136196 }
137197
138198 async onUninit ( ) {
139- this . homey . log ( "Teslemetry app shutting down..." ) ;
199+ this . homey . log ( "Teslemetry OAuth2 app shutting down..." ) ;
140200
141201 // Wait for any pending initialization to complete
142202 if ( this . initializationPromise ) {
0 commit comments