Browse code

new workflows adn refactoring

Louis authored on28/04/2025 18:37:32
Showing4 changed files
1 1
Binary files a/build/synocam_home_switch.pbw and b/build/synocam_home_switch.pbw differ
... ...
@@ -19,7 +19,6 @@
19 19
       "watchface": false
20 20
     },
21 21
     "messageKeys": [
22
-      "auth",
23 22
       "status",
24 23
       "server",
25 24
       "username",
... ...
@@ -9,8 +9,7 @@ const uint32_t inbox_size = 64;
9 9
 const uint32_t outbox_size = 64;
10 10
 
11 11
 
12
-static char s_auth[60];
13
-static char s_api[40];
12
+static char s_api[60];
14 13
 static char s_api_short[22];
15 14
 static char s_username[40];
16 15
 static char s_password[40];
... ...
@@ -206,7 +205,7 @@ static void update_time() {
206 205
 
207 206
 void comm_is_ready() {
208 207
 
209
-  // Authenticate to get token from syno
208
+  // Trigger timed home mode (15 min)
210 209
 
211 210
   // Declare the dictionary's iterator
212 211
   DictionaryIterator *out_iter;
... ...
@@ -216,15 +215,13 @@ void comm_is_ready() {
216 215
   
217 216
   if(result == APP_MSG_OK) {
218 217
     // Add an item to ask for weather data
219
-    msg = "auth";
218
+    msg = "timed";
220 219
     dict_write_cstring(out_iter, status, msg);
221 220
   
222 221
     // Send this message
223 222
     result = app_message_outbox_send();
224 223
     if(result != APP_MSG_OK) {
225 224
       APP_LOG(APP_LOG_LEVEL_ERROR, "Error sending the outbox: %d", (int)result);
226
-    }else{
227
-      text_layer_set_text(s_text_layer, "Authenticating...");
228 225
     }
229 226
   } else {
230 227
     // The outbox cannot be used right now
... ...
@@ -259,28 +256,14 @@ static void inbox_received_callback(DictionaryIterator *iter, void *context) {
259 256
     APP_LOG(APP_LOG_LEVEL_DEBUG, "received jsready message on watch... ");
260 257
   }
261 258
 
262
-  // Read Auth returns
263
-  Tuple *auth_tuple = dict_find(iter, MESSAGE_KEY_auth);
264
-
265
-  if(auth_tuple) {
266
-    strncpy(s_auth, auth_tuple->value->cstring, 60);
267
-    // Display in the TextLayer
268
-    text_layer_set_text(s_text_layer, s_auth);
269
-    if(strcmp(s_auth, "Authentication failed")==0){
270
-      vibes_long_pulse();
271
-    }
272
-    APP_LOG(APP_LOG_LEVEL_DEBUG, "Auth message received ... ");
273
-  }else{
274
-    APP_LOG(APP_LOG_LEVEL_DEBUG, "not auth message... ");
275
-  }
276
-
277 259
   // Read API returns
278 260
   Tuple *api_tuple = dict_find(iter, MESSAGE_KEY_status);
279 261
 
280 262
   if(api_tuple) {
281
-    strncpy(s_api, api_tuple->value->cstring, 40);
263
+    strncpy(s_api, api_tuple->value->cstring, 60);
282 264
     // Display in the TextLayer
283 265
     text_layer_set_text(s_text_layer, s_api);
266
+    // Vibrating depending of returns, not everytime
284 267
     strncpy(s_api_short, s_api, 22);
285 268
     if(strcmp(s_api_short, "Home mode is ON")==0){
286 269
       vibes_short_pulse();
... ...
@@ -5,7 +5,7 @@ const jsSHA = require('./sha');
5 5
 
6 6
 var messageKeys = require('message_keys');
7 7
 
8
-var sid;
8
+var sid="";
9 9
 var status;
10 10
 var retry;
11 11
 retry = 0;
... ...
@@ -46,11 +46,12 @@ function leftpad(str, len, pad) {
46 46
 }
47 47
 
48 48
 function getOtp() {
49
+    send_message_to_watch("Authenticating..")
49 50
     key = base32tohex(JSON.parse(localStorage.getItem('clay-settings')).OTP_seed)
50 51
     //console.log('-- seed:' + JSON.parse(localStorage.getItem('clay-settings')).OTP_seed)
51 52
     //console.log('-- key:' + key)
52 53
     var epoch = Math.round(new Date().getTime() / 1000.0);
53
-    if ((30 - (epoch % 30)) < 10) {
54
+    if ((30 - (epoch % 30)) < 12) {
54 55
         console.log('------- waiting for new TOTP,' + epoch);
55 56
         return false;
56 57
     } else {
... ...
@@ -90,66 +91,27 @@ function xhr_to_syno(method, url_path, onload_function, max_retry, timeout) {
90 91
                     console.log('------xhr status 200 ');
91 92
                     onload_function(xhr);
92 93
                     return true;
93
-                } else if (xhr.status == 407) { //blocked by proxy (and syno Firewall too)
94
-                    console.log('------xhr status 407 blocked by proxy (and syno Firewall too) ');
94
+                } else if (xhr.status == 407) { // IP blocked by syno (or by syno Firewall)
95
+                    console.log('------xhr status 407 IP blocked by syno (or by syno Firewall) ');
95 96
                     onload_function(xhr);
96 97
                     return false;
97
-                } else if (xhr.status >= 400) { //wrong credentials
98
-                    console.log('------xhr status 401 wrong credentials ');
98
+                } else if (xhr.status == 400) { //wrong credentials
99
+                    console.log('------xhr status wrong user or password ');
100
+                    onload_function(xhr);
101
+                    return false;
102
+                } else if (xhr.status == 404) { //wrong OTP
103
+                    console.log('------xhr status 404 wrong OTP ');
99 104
                     onload_function(xhr);
100 105
                     return false;
101 106
                 } else if (xhr.status == 0) { //timeout
102
-                    retry++;
103
-                    if (retry < max_retry) {
104
-                        console.log('------xhr timed out retrying another time ');
105
-                        //send back "timeout" to watch
106
-                        message = "Time out (" + retry + "), retrying...";
107
-
108
-                        // Build message
109
-                        var dict = {
110
-                            'status': message,
111
-                        };
112
-
113
-                        // Send the message
114
-                        Pebble.sendAppMessage(dict, function (e) {
115
-                            console.log('sent');
116
-                        }, function () {
117
-                            console.log('failed');
118
-                        });
119
-
120
-                        setTimeout(function () { xhr_to_syno(method, url_path, onload_function, max_retry, timeout) }, 60000 * retry);
121
-                    } else {
122
-                        console.log('------xhr timed out ' + retry + ' times');
123
-                        //send back "timeout" to watch
124
-                        message = "Time out " + retry + " times, verify settings and connectivity";
125
-
126
-                        // Build message
127
-                        var dict = {
128
-                            'status': message,
129
-                        };
130
-
131
-                        // Send the message
132
-                        Pebble.sendAppMessage(dict, function (e) {
133
-                            console.log('sent');
134
-                        }, function () {
135
-                            console.log('failed');
136
-                        });
137
-                        return false;
138
-                    }
139
-                } else { //timeout ?
107
+                    console.log('------xhr timed out');
108
+                    //send back "timeout" to watch
109
+                    message = "Time out";
110
+                    send_message_to_watch(message)
111
+                } else { // why would this happen?
140 112
                     console.log('------xhr request returned error code ' + xhr.status);
141 113
                     message = "Error (XHR" + xhr.status + ")";
142
-                    // Build message
143
-                    var dict = {
144
-                        'status': message,
145
-                    };
146
-
147
-                    // Send the message
148
-                    Pebble.sendAppMessage(dict, function (e) {
149
-                        console.log('sent');
150
-                    }, function () {
151
-                        console.log('failed');
152
-                    });
114
+                    send_message_to_watch(message)
153 115
                     return false;
154 116
                 }
155 117
             } else {
... ...
@@ -169,20 +131,23 @@ function xhr_to_syno(method, url_path, onload_function, max_retry, timeout) {
169 131
 
170 132
 }
171 133
 
172
-
173
-function authenticate() {
134
+function authenticate(action_callback) {    
135
+    send_message_to_watch("Authenticating.")
174 136
     var response;
175
-    sid = "";
137
+    sid = ""; //re-use sid from another session (7 days before expiry)
176 138
     console.log('---- authenticate');
177 139
     if (JSON.parse(localStorage.getItem('clay-settings')).username && JSON.parse(localStorage.getItem('clay-settings')).password) {
178 140
         var username = JSON.parse(localStorage.getItem('clay-settings')).username;
179 141
         var password = JSON.parse(localStorage.getItem('clay-settings')).password;
180
-        console.log('-- username:' + username);
181
-        console.log('-- password:' + password.substring(0, 1) + '...');
182 142
         var url_path = "/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=6&account=" + username + "&passwd=" + password + "&session=SurveillanceStation&format=sid";
183 143
         if (JSON.parse(localStorage.getItem('clay-settings')).OTP_enabled) {
184 144
             var otp_code = getOtp()
185 145
             if (!otp_code) {
146
+                setTimeout( function () {
147
+                    send_message_to_watch("Authenticating...");
148
+                    home_mode_handler(action_callback);
149
+                    }
150
+                    ,4000);
186 151
                 return false
187 152
             }
188 153
             console.log('-- otp_code is :' + otp_code)
... ...
@@ -195,31 +160,13 @@ function authenticate() {
195 160
                 sid = response.data.sid;
196 161
                 console.log('------Authentication succeeded');
197 162
                 if (sid != "") {
198
-                    message = "Welcome to Syno Cam Switch ! ready & authenticated";
199
-                    // Build message
200
-                    var dict = {
201
-                        'auth': message,
202
-                    };
203
-                    // Send the message
204
-                    Pebble.sendAppMessage(dict, function (e) {
205
-                        console.log('sent');
206
-                    }, function () {
207
-                        console.log('failed');
208
-                    });
209
-                    timed_switch_home(15 * 60);
163
+                    message = "Authenticated";
164
+                    send_message_to_watch(message)
165
+                    home_mode_handler(action_callback);
210 166
                 } else {
211 167
                     console.log('------Unexpected error : authentication is OK but no SID retrieved');
212 168
                     message = "Auth error, no SID";
213
-                    // Build message
214
-                    var dict = {
215
-                        'auth': message,
216
-                    };
217
-                    // Send the message
218
-                    Pebble.sendAppMessage(dict, function (e) {
219
-                        console.log('sent');
220
-                    }, function () {
221
-                        console.log('failed');
222
-                    });
169
+                    send_message_to_watch(message)
223 170
                 }
224 171
             } else {
225 172
                 console.log('------Authentication failed : ' + JSON.stringify(response));
... ...
@@ -229,20 +176,15 @@ function authenticate() {
229 176
                 } else if (response.error.code == 404) {
230 177
                     console.log('------Authentication failed because of wrong TOTP');
231 178
                     message = "Authentication failed, check your TOTP seed";
179
+                } else if (response.error.code == 407) {
180
+                    console.log('------Authentication failed because of IP Blocked');
181
+                    message = "Authentication failed, IP is blocked";
232 182
                 }
233
-                // Build message
234
-                var dict = {
235
-                    'auth': message,
236
-                };
237
-                // Send the message
238
-                Pebble.sendAppMessage(dict, function (e) {
239
-                    console.log('sent');
240
-                }, function () {
241
-                    console.log('failed');
242
-                });
183
+                send_message_to_watch(message)
243 184
             }
244
-        };
245
-        max_retry = 1;
185
+        };        
186
+        send_message_to_watch("Authenticating....");
187
+        max_retry = 0;
246 188
         xhr_to_syno(method, url_path, onload_function, max_retry, 20000);
247 189
     } else {
248 190
         console.log("--- failed to get settings");
... ...
@@ -253,7 +195,6 @@ function authenticate() {
253 195
 
254 196
 }
255 197
 
256
-
257 198
 function get_status() {
258 199
     var response;
259 200
 
... ...
@@ -282,131 +223,93 @@ function get_status() {
282 223
             } else {
283 224
                 message = "something happened, try again ! (G200)";
284 225
             }
285
-            // Build message
286
-            var dict = {
287
-                'status': message,
288
-            };
289
-
290
-            // Send the message
291
-            Pebble.sendAppMessage(dict, function (e) {
292
-                console.log('sent');
293
-            }, function () {
294
-                console.log('failed');
295
-            });
226
+            send_message_to_watch(message)
296 227
         }
297 228
 
298 229
         max_retry = 10;
299 230
         xhr_to_syno(method, url_path, onload_function, max_retry, 10000);
300 231
 
301 232
     } else {
302
-        authenticate();        
303
-        get_status();
233
+        authenticate("get");
304 234
     }
305 235
 
306 236
 }
307 237
 
308
-
309
-function timed_switch_home(duration) {
238
+function home_mode_handler(action) {
310 239
     var response;
311
-    console.log('---- timed switch');
240
+    var duration = 15 * 60
312 241
     if (sid != "") {
242
+        console.log('---- switching home mode to ' + action);
313 243
         var epoch = Math.round(new Date().getTime() / 1000.0);
314
-        var start_ts = epoch + 10
315
-        var end_ts = duration + start_ts
316
-        var d = new Date(end_ts * 1000)
317
-        var end_time = d.toLocaleTimeString("fr-FR",{timestyle:'short'});
318
-        console.log('---- switching home mode for ' + duration + 'seconds, until ' + end_time);
319
-        url_path = "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=SaveOneTimeSwitch&onetime_enable_on=true&onetime_disable_on=true&onetime_enable_time=" + start_ts + "&onetime_disable_time=" + end_ts + "&_sid=" + sid;
320
-        method = "GET"
321
-        onload_switch_function = function (xhr) {
322
-            response = JSON.parse(xhr.responseText);
323
-            if (response.success == true) {
324
-                message = "Home mode is ON until " + end_time;
325
-            } else {
326
-                message = "something happened, try again ! (S200)";
327
-                console.log('---- ' + message + ' ' + xhr.responseText)
328
-            }
329
-            // Build message
330
-            dict = {
331
-                'status': message,
332
-            };
333
-
334
-            // Send the message Home mode is ON for 900 seconds
335
-            Pebble.sendAppMessage(dict, function (e) {
336
-                console.log('sent \"' + message + '\"');
337
-            }, function () {
338
-                console.log('failed');
339
-            });
340
-        }
341
-        max_retry = 10;
342
-        xhr_to_syno(method, url_path, onload_switch_function, max_retry, 10000);
343
-
344
-
345
-    } else {
346
-        authenticate();
347
-        timed_switch_home(duration)
348
-    }
349
-
350
-}
351
-
352
-function switch_home(bool) {
353
-    var response;
354
-    if (sid != "") {
355
-        console.log('---- switching home mode to ' + bool);
356
-        var epoch = Math.round(new Date().getTime() / 1000.0);
357
-        var start_ts = epoch + 10
358
-        switch (bool) {
359
-            case true:
244
+        var start_ts = epoch + 10;
245
+        method = "GET";
246
+        max_retry = 0;
247
+        
248
+        switch (action) {
249
+            case "home_on":
250
+                send_message_to_watch("Setting Home Mode to ON")
360 251
                 url_path = "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=SaveOneTimeSwitch&onetime_enable_on=true&onetime_disable_on=false&onetime_enable_time=" + start_ts + "&_sid=" + sid;
361 252
                 break;
362
-            case false:
253
+            case "home_off":
254
+                send_message_to_watch("Setting Home Mode to OFF")
363 255
                 url_path = "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=SaveOneTimeSwitch&onetime_enable_on=false&onetime_disable_on=true&onetime_disable_time=" + start_ts + "&_sid=" + sid;
364 256
                 break;
257
+            case "timed":
258
+                send_message_to_watch("Temporary setting Home Mode to ON")
259
+                var end_ts = duration + start_ts
260
+                var d = new Date(end_ts * 1000)
261
+                var end_time = d.toLocaleTimeString("fr-FR",{timestyle:'short'});
262
+                url_path = "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=SaveOneTimeSwitch&onetime_enable_on=true&onetime_disable_on=true&onetime_enable_time=" + start_ts + "&onetime_disable_time=" + end_ts + "&_sid=" + sid;    
263
+                break;
365 264
             default:
366 265
                 message = "something happened, try again ! (IMPOSSIBLE)";
367 266
         }
368
-
369
-        //url_path = "/webapi/entry.cgi?api=SYNO.SurveillanceStation.HomeMode&version=1&method=Switch&on=" + bool + "&_sid=" + sid;
370
-        method = "GET"
267
+        
371 268
         onload_switch_function = function (xhr) {
372 269
             response = JSON.parse(xhr.responseText);
270
+            console.log(response.success);
373 271
             if (response.success == true) {
374
-                switch (bool) {
375
-                    case true:
272
+                switch (action) {
273
+                    case "home_on":
376 274
                         message = "Home mode is ON (camera is off)";
377 275
                         break;
378
-                    case false:
276
+                    case "home_off":
379 277
                         message = "Home mode is OFF (camera is on)";
380 278
                         break;
279
+                    case "timed":
280
+                        message = "Home mode is ON until " + end_time;
281
+                        break;
381 282
                     default:
382 283
                         message = "something happened, try again ! (IMPOSSIBLE)";
383 284
                 }
384 285
             } else {
385 286
                 message = "something happened, try again ! (S200)";
386 287
             }
387
-            // Build message
388
-            dict = {
389
-                'status': message,
390
-            };
391
-
392
-            // Send the message
393
-            Pebble.sendAppMessage(dict, function (e) {
394
-                console.log('sent');
395
-            }, function () {
396
-                console.log('failed');
397
-            });
288
+            send_message_to_watch(message)
398 289
         }
399
-        max_retry = 10;
290
+        max_retry = 0;
400 291
         xhr_to_syno(method, url_path, onload_switch_function, max_retry, 10000);
401 292
 
402 293
 
403 294
     } else {
404
-        authenticate();
405
-        switch_home(bool);
295
+        authenticate(action);
406 296
     }
407 297
 
408 298
 }
409 299
 
300
+function send_message_to_watch(message){
301
+    // Build message
302
+    var dict = {
303
+        'status': message,
304
+    };
305
+    console.log('DSCam Home-Switch: -- message to sent to watch:'+JSON.stringify(dict));
306
+    // Send the message
307
+    Pebble.sendAppMessage(dict, function (e) {
308
+        console.log('DSCam Home-Switch: -- message sent to watch');
309
+    }, function () {
310
+        console.log('DSCam Home-Switch: -- Failed to message sent to watch');
311
+    });
312
+}
410 313
 // Get JS readiness events
411 314
 Pebble.addEventListener('ready', function (e) {
412 315
     console.log("---- local storage:");
... ...
@@ -414,28 +317,25 @@ Pebble.addEventListener('ready', function (e) {
414 317
     console.log('PebbleKit JS is ready');
415 318
     // Update Watch on this
416 319
     Pebble.sendAppMessage({ 'JSReady': 1 });
320
+    send_message_to_watch("Welcome !")
417 321
 });
418 322
 
419 323
 // Get AppMessage events
420 324
 Pebble.addEventListener('appmessage', function (e) {
421 325
     // Get the dictionary from the message
422 326
     var dict = e.payload;
423
-    console.log(dict[0].toString());
424 327
     switch (dict[0]) {
425
-        case 'auth':
426
-            if (!authenticate()){
427
-                console.log("---- waited 1sec:");
428
-                setTimeout(authenticate(),1000);
429
-            }
430
-            break;
431 328
         case 'get':
432 329
             get_status();
433 330
             break;
331
+        case 'timed':
332
+            home_mode_handler("timed"); 
333
+            break;
434 334
         case 'home_on':
435
-            switch_home(true);
335
+            home_mode_handler("home_on");
436 336
             break;
437 337
         case 'home_off':
438
-            switch_home(false);
338
+            home_mode_handler("home_off");
439 339
             break;
440 340
         default:
441 341
             console.log('Sorry. I don\'t understand your request :' + dict[0]);