Subversion Repositories HomeAutomation

Rev

Rev 2211 | Rev 2232 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1648 runge 1
 
1936 englund 2
Sensor_ModuleNames    = [ "DS18x20", "FOST02", "BusVoltage", "SimpleDTMF", "DHT11" ];
2205 arune 3
SensorRf_ModuleNames    = [ "rfTransceive" ];
1648 runge 4
Sensor_Intervals      = function() { return [ 1, 5, 10, 15, 20 ]; };
5
Sensor_Aliases        = function() { return Module_GetAliasNames(Sensor_ModuleNames); };
6
Sensor_AvailableIds   = function() { return Module_GetAvailableIds(Sensor_ModuleNames); };
7
 
8
function Sensor_SetReportInterval(alias_name, interval)
9
{
10
    if (arguments.length < 2)
11
    {
1649 runge 12
        Log("\033[31mNot enough parameters given.\033[0m\n");
1648 runge 13
        return false;
14
    }
2091 runge 15
 
1648 runge 16
    var aliases_data = Module_ResolveAlias(alias_name, Sensor_ModuleNames);
17
    var found = false;
2091 runge 18
 
1648 runge 19
    for (var name in aliases_data)
20
    {
1765 linlun 21
        var variables = {"Time"     : interval };
1649 runge 22
        if (Module_SendMessage(aliases_data[name]["module_name"], aliases_data[name]["module_id"], "Report_Interval", variables))
23
        {
24
            Log("\033[32mCommand sent successfully to " + name + ".\033[0m\n");
25
        }
26
        else
27
        {
28
            Log("\033[31mFailed to send command to " + name + ".\033[0m\n");
29
        }
2091 runge 30
 
1649 runge 31
        found = true;
32
    }
2091 runge 33
 
1649 runge 34
    if (!found)
35
    {
36
        Log("\033[31mNo aliases by the name " + alias_name + " were applicable for this command.\033[0m\n");
37
        return false;
38
    }
2091 runge 39
 
1649 runge 40
    return true;
41
}
42
Console_RegisterCommand(Sensor_SetReportInterval, function(arg_index, args) { return Console_StandardAutocomplete(arg_index, args, Sensor_Aliases(), Sensor_Intervals()); });
43
 
2091 runge 44
Sensor_OnNewPhonenumberFunctions = [];
2050 arune 45
 
46
function Sensor_RegisterToNewPhonenumber(alias_name, callback)
47
{
2091 runge 48
  if (!Sensor_OnNewPhonenumberFunctions[alias_name])
49
  {
50
    Sensor_OnNewPhonenumberFunctions[alias_name] = [];
51
  }
52
 
53
  Sensor_OnNewPhonenumberFunctions[alias_name].push(callback);
2050 arune 54
}
55
 
2207 arune 56
Sensor_OnDeviceStateChangeFunctions = [];
57
 
58
function Sensor_RegisterToDeviceStateChange(alias_name, callback)
59
{
60
  if (!Sensor_OnDeviceStateChangeFunctions[alias_name])
61
  {
62
    Sensor_OnDeviceStateChangeFunctions[alias_name] = [];
63
  }
64
 
65
  Sensor_OnDeviceStateChangeFunctions[alias_name].push(callback);
66
}
67
 
68
 
1649 runge 69
function Sensor_OnMessage(module_name, module_id, command, variables)
70
{
2091 runge 71
  if (in_array(Sensor_ModuleNames, module_name))
72
  {
73
    var aliases_data = Module_LookupAliases({
74
      "module_name" : module_name,
75
      "module_id"   : module_id,
76
      "group"       : false
77
    });
1807 linlun 78
 
2091 runge 79
    switch (command)
80
    {
81
      case "Phonenumber":
82
      {
83
        for (var alias_name in aliases_data)
84
        {
85
          var number = variables["Number"];
86
          var incommingCall = true;
2098 runge 87
          var checkName = true;
1649 runge 88
 
2098 runge 89
          Log("received from DTMF:\"" + number + "\"");
90
 
2122 runge 91
          if (variables["Number"].length >= 6)
2091 runge 92
          {
2092 runge 93
            /* A seems to mean it is an incomming call! */
94
            if (number.charAt(0) === 'A' || number.charAt(0) === 'D')
2091 runge 95
            {
2092 runge 96
              incommingCall = true;
2091 runge 97
 
98
              /* Remove leading A */
99
              number = number.substring(1);
100
            }
2092 runge 101
            else /* Outgoing call */
2091 runge 102
            {
2092 runge 103
              incommingCall = false;
2091 runge 104
            }
105
 
106
            /* A number can have a trailing C */
107
            var endIndex = number.indexOf('C');
108
 
109
            if (endIndex !== -1)
110
            {
111
              /* Remove trailing C */
112
              number = number.substring(0, endIndex);
113
            }
114
          }
115
          else if (number == "B00C")
116
          {
117
            /* Unknown number */
118
            number = "Unknown";
119
            incommingCall = true;
2098 runge 120
            checkName = false;
2091 runge 121
          }
122
          else if (number == "B10C")
123
          {
124
            /* Secret/protected number */
125
            number = "Protected";
126
            incommingCall = true;
2098 runge 127
            checkName = false;
2091 runge 128
          }
129
          else
130
          {
131
            Log("DTMF decoded number is to short, number: \"" + number + "\", length: " + number.length);
132
            return;
133
          }
2181 arune 134
 
135
          /* Adding area code prefix if needed */
136
          if (number.charAt(0) != '0' && checkName)
137
          {
138
            if (typeof sensorDefaultPhoneAreaCode === 'undefined')
139
            {
140
              Log("\033[31mOnlinePhonebook: please add sensorDefaultPhoneAreaCode = yourAreaCode to autostart.js, defaulting to 031\033[0m\n");
141
              number = "031" + number;
142
            }
143
            else
144
            {
145
                number = sensorDefaultPhoneAreaCode + number;
146
            }
147
          }
2091 runge 148
 
149
          /* Store number and direction in last values */
150
          var lastValue = {};
151
          var lastValueString = Storage_GetParameter("LastValues", alias_name);
152
 
153
          if (lastValueString)
154
          {
155
            lastValue = JSON.parse(lastValueString);
156
          }
157
 
158
          var timestamp = get_time();
159
 
160
          lastValue["Phonenumber"] = { "value" : number, "timestamp" : timestamp };
161
          lastValue["Direction"] = { "value" : incommingCall ? "in" : "out", "timestamp" : timestamp };
162
 
163
          Storage_SetParameter("LastValues", alias_name, JSON.stringify(lastValue));
164
 
165
 
166
          /* Store number in phone call history */
167
          var newValue = { "number" : number, "direction" : incommingCall ? "in" : "out", "module" : alias_name, "names" : [], "timestamp" : timestamp };
168
 
169
          Storage_SetParameter("PhoneCalls", timestamp, JSON.stringify(newValue));
170
 
171
 
172
          /* Log the number */
173
          Log("New number: " + number + ", direction: " + (incommingCall ? "in" : "out"));
2152 arune 174
 
2091 runge 175
          /* Lookup name */
2098 runge 176
          if (checkName)
177
          {
2181 arune 178
            Sensor_StoreNumberInPhonebook(number, timestamp);
2098 runge 179
          }
2091 runge 180
 
2181 arune 181
          var phonebookNumbers = Storage_GetJsonParamter("PhoneBook", number);
2152 arune 182
          if (!phonebookNumbers)
183
          {
184
            phonebookNumbers = [];
185
          }
186
 
2091 runge 187
          /* Call any potential subscribers */
188
          if (Sensor_OnNewPhonenumberFunctions[alias_name])
189
          {
190
            for (var n in Sensor_OnNewPhonenumberFunctions[alias_name])
191
            {
2152 arune 192
              /* Call callback with arguments alias, number, direction */
193
              Sensor_OnNewPhonenumberFunctions[alias_name][n](alias_name, number, incommingCall ? "in" : "out", phonebookNumbers);
2091 runge 194
            }
195
          }
196
        }
197
        break;
198
      }
199
      case "Voltage":
200
      case "Temperature_Celsius":
201
      {
202
        if ((module_name == "DS18x20") && (variables["Value"] == 85))
203
        {
204
          Log("\033[31mDS18x20: Temperature conversion error: " + module_name + ":" + module_id + ", SensorId=" + variables["SensorId"] + "\033[0m");
205
          break;
206
        }
207
      }
208
      case "Humidity_Percent":
209
      {
210
        for (var alias_name in aliases_data)
211
        {
212
          if (aliases_data[alias_name]["specific"]["SensorId"] != variables["SensorId"])
213
          {
214
            continue;
215
          }
216
 
217
          var last_value = {};
218
          var last_value_string = Storage_GetParameter("LastValues", alias_name);
219
 
220
          if (last_value_string)
221
          {
222
            last_value = eval("(" + last_value_string + ")");
223
          }
224
 
225
          last_value[command] = { "value" : variables["Value"], "timestamp" : get_time() };
226
 
227
          Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
228
        }
229
 
230
        break;
231
      }
232
    }
233
  }
1649 runge 234
}
235
Module_RegisterToOnMessage("all", Sensor_OnMessage);
1899 linlun 236
 
2205 arune 237
function SensorRf_OnMessage(module_name, module_id, command, variables)
238
{
239
    if (in_array(SensorRf_ModuleNames, module_name))
240
    {
241
        var aliases_data = Module_LookupAliases({
242
        "module_name" : module_name,
243
        "module_id"   : module_id,
244
        "group"       : false   });
245
 
2211 arune 246
        /* Must check sensor here in case no alias is stored the adress needs to be printed */
2205 arune 247
        var VikingSuccess = "NoVikingSensor";
2211 arune 248
        if (variables["Protocol"] == "Viking")
249
        {
250
            /*
251
                              ??? aaaaaaaa sttttttttttt hhhhhhhh cccccccc
252
            341731651126    0b100 11111001 000011001011 00101110 00110110   20.3 46%
253
            a = address, s = sign, t = temperature, h = humidity, c = crc
254
            */
255
            var data = variables["IRdata"];
256
            var crc = data&0xFF;
257
            var humidity = (data>>>8)&0xFF;
258
            var temp = (data>>>16)&0xFFF;
259
            var addr = rshift(data,28)&0xFF;
260
            var unknown = rshift(data,36)&0xF;
261
            var calccrc=crc8(rshift(data,8), 32);
262
 
263
            var sign = (temp>>>11)&1;
264
            temp = temp&0x7FF;
265
            if (sign > 0)
266
            {
267
                temp = -temp;
268
            }
269
            temp = temp/10;
270
 
271
            VikingSuccess = "VikingNotFound";
272
 
273
            if (unknown != 4)
274
            {
275
                Log("\033[33mWarning: VikingSensor, unknown part="+unknown+", data="+data+"\033[0m");
276
            }
277
        }
278
 
2205 arune 279
        loopAliases:    /* Label to break nested */
280
        for (var alias_name in aliases_data)
281
        {
282
            if (aliases_data[alias_name]["specific"]["Channel"] == variables["Channel"] &&
283
                aliases_data[alias_name]["specific"]["Proto"] == variables["Protocol"])
284
            {
285
                switch (variables["Protocol"])
286
                {
287
                    case "Viking":
2207 arune 288
                    {   /* Add alias with these specifics: Channel=0,Proto=Viking,Address=<address of sensor> */
2205 arune 289
                        if (crc != calccrc)
290
                        {
291
                            Log("\033[31mError: VikingSensor, incorrect CRC, data="+data+", CRC="+crc+", calcCRC="+calccrc+"\033[0m");
292
                            break loopAliases;
293
                        }
294
                        if (addr == aliases_data[alias_name]["specific"]["Address"])
295
                        {
296
                            VikingSuccess = "VikingFound";
297
 
298
                            var last_value = {};
299
                            var last_value_string = Storage_GetParameter("LastValues", alias_name);
300
 
301
                            if (last_value_string)
302
                            {
303
                                last_value = eval("(" + last_value_string + ")");
304
                            }
305
 
306
                            var timestamp = get_time();
307
                            last_value["Temperature_Celsius"] = { "value" : temp.toString(), "timestamp" : timestamp };
2218 arune 308
                            if (humidity<101)
309
                            {
310
                                last_value["Humidity_Percent"] = { "value" : humidity.toString(), "timestamp" : timestamp };
311
                            }
2205 arune 312
 
313
                            Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
314
 
315
                            break loopAliases;
316
                        }
317
                        break;
318
                    }
2207 arune 319
                    case "Nexa2":
2211 arune 320
                    {   /* Add alias with these specifics: Channel=0,Proto=Nexa2,OnData=<data for on>,OffData=<data for off> */
2207 arune 321
                        var deviceStateCommand = "";
322
                        if (variables["IRdata"] == aliases_data[alias_name]["specific"]["OnData"] && variables["Status"] == "Pressed")
323
                        {
324
                            deviceStateCommand = "On";
325
                        }
326
                        else if (variables["IRdata"] == aliases_data[alias_name]["specific"]["OffData"] && variables["Status"] == "Pressed")
327
                        {
328
                            deviceStateCommand = "Off";
329
                        }
330
                        else
331
                        {
332
                            break;
333
                        }
334
 
335
                        var last_value = {};
336
                        var last_value_string = Storage_GetParameter("LastValues", alias_name);
337
 
338
                        if (last_value_string)
339
                        {
340
                            last_value = eval("(" + last_value_string + ")");
341
                        }
342
 
343
                        if (( typeof(last_value["State"]) == "undefined" ) ||
344
                            ( deviceStateCommand == "Off" && last_value["State"]["value"] == "On" ) ||
345
                            ( deviceStateCommand == "On" && last_value["State"]["value"] == "Off" ))
346
                        {
347
                            last_value["State"] = { "value" : deviceStateCommand, "timestamp" : get_time() };
348
 
349
                            Storage_SetParameter("LastValues", alias_name, JSON.stringify(last_value));
350
 
351
                            /* Call any potential subscribers */
352
                            if (Sensor_OnDeviceStateChangeFunctions[alias_name])
353
                            {
354
                                for (var n in Sensor_OnDeviceStateChangeFunctions[alias_name])
355
                                {
356
                                    /* Call callback with arguments alias, state */
357
                                    Sensor_OnDeviceStateChangeFunctions[alias_name][n](alias_name, deviceStateCommand);
358
                                }
359
                            }
360
                        }
361
                        break;
362
                    }
2205 arune 363
                }
364
            }
365
        }
366
        if (VikingSuccess == "VikingNotFound")
367
        {
368
            Log("Found unknown vikingsensor address="+addr+" temperature="+temp+" humidity="+humidity+" unknown="+unknown);
369
        }
370
    }
371
}
372
Module_RegisterToOnMessage("all", SensorRf_OnMessage);
373
 
2091 runge 374
function Sensor_StoreNumberInPhonebook(number, timestamp)
1899 linlun 375
{
2152 arune 376
  var phonebookNumbers = Storage_GetJsonParamter("PhoneBook", number);
2091 runge 377
 
378
  if (!phonebookNumbers)
379
  {
380
    phonebookNumbers = [];
381
 
382
    url = "wap.eniro.se/query?search_word=" + number + "&what=mobwp";
383
    //Log("\033[31mURL: http://"+url+"\033[0m\n");
384
 
385
    Http_Request(url, function(socket_id, result, header, content_data)
386
    {
387
      //Log("\033[31mOnlinePhonebook-eniro: result was: " + result + "\033[0m\n");
388
      //Log("\033[31mOnlinePhonebook-eniro: content was: " + content_data + "\033[0m\n");
389
 
390
      if (result.indexOf("200 OK") != -1)
391
      {
392
 
393
        var lines = content_data.split("\n");
394
 
395
        var endString = "<anchor>Tillbaka<prev/></anchor>";
396
        var nameStartString = "<td class=\"hTd2\">";
397
        var nameEndString = "</table>";
398
 
399
        for (var n = 1; n < lines.length; n++)
400
        {
401
          var line = lines[n].trim("\n");
402
 
403
          if (line.indexOf(endString) != -1)
404
          {
405
            break;
406
          }
407
 
408
          if (line.indexOf(nameStartString) != -1)
409
          {
410
            line = lines[n + 1].trim("\n");
411
            splitted = line.split("b>");
412
 
413
            phonebookNumbers.push(splitted[1].substr(0, splitted[1].length - 2));
414
            break;
415
          }
416
        }
417
 
418
        //Log("\033[31mOnlinePhonebook: Line: " + lines[1] + "\033[0m\n");
419
        //Log("\033[31mOnlinePhonebook: Line: " + lines[2] + "\033[0m\n");
420
        //Log("\033[31mOnlinePhonebook: Line: " + lines[3] + "\033[0m\n");
421
        if (phonebookNumbers.length > 0)
422
        {
423
          Storage_SetJsonParameter("PhoneBook", number, phonebookNumbers);
424
 
425
          Sensor_UpdateNameInPhonecalls(timestamp, phonebookNumbers);
426
 
427
          Log("\033[31mOnlinePhonebook-eniro: Found: " + JSON.stringify(phonebookNumbers) + "\033[0m\n");
428
        }
429
      }
430
      else
431
      {
432
        Log("\033[31mOnlinePhonebook-eniro: Failed to do name lookup, result was: " + result + "\033[0m\n");
433
      }
434
 
2094 runge 435
      if (phonebookNumbers.length == 0)
2091 runge 436
      {
2094 runge 437
        if (typeof sensorRKSEEK_API !== 'undefined')
2091 runge 438
        {
2094 runge 439
          url = "rkseek.oblivioncreations.se/?client="+sensorRKSEEK_API+"&n=" + number + "&out=text";
440
          Log("\033[31mURL: http://"+url+"\033[0m\n");
2091 runge 441
 
2094 runge 442
          Http_Request(url, function(socket_id, result, header, content_data)
2091 runge 443
          {
2094 runge 444
            phonebookNumbers = [];
445
 
446
            if (result.indexOf("200 OK") != -1)
2091 runge 447
            {
2094 runge 448
              //Log("\033[31mOnlinePhonebook: result was: " + content_data + "\033[0m\n");
449
              var lines = content_data.split("\n");
450
              //Log("\033[31mOnlinePhonebook: Line: " + lines[1] + "\033[0m\n");
451
              //Log("\033[31mOnlinePhonebook: Line: " + lines[2] + "\033[0m\n");
452
              //Log("\033[31mOnlinePhonebook: Line: " + lines[3] + "\033[0m\n");
453
              if (lines[2].length > 0)
454
              {
455
                phonebookNumbers = [ lines[2] ]; // TODO Is this really correct?!
456
                Storage_SetJsonParameter("PhoneBook", number, phonebookNumbers);
457
 
458
                Sensor_UpdateNameInPhonecalls(timestamp, phonebookNumbers);
2152 arune 459
 
2094 runge 460
                Log("\033[31mOnlinePhonebook-rseek: Found: " + JSON.stringify(phonebookNumbers) + "\033[0m\n");
461
              }
2091 runge 462
            }
2094 runge 463
            else
464
            {
465
              Log("\033[31mOnlinePhonebook-rseek: Failed to do name lookup, result was: " + result + "\033[0m\n");
466
            }
467
          });
468
        }
2091 runge 469
      }
2094 runge 470
    });
2014 linlun 471
        /*
2091 runge 472
        Http_Request("wap.hitta.se/default.aspx?Who=" + number + "&Where=&PageAction=White",
1899 linlun 473
            function(socket_id, result, header, content_data) {
474
                var persons = new Array();
475
                if (result.indexOf("200 OK") != -1)
476
                {
477
                    var endString = "<anchor>Tillbaka<prev/></anchor>";
478
                    var nameStartString = " title=\"Link\">";
479
                    var nameEndString = "</a>";
2091 runge 480
 
1899 linlun 481
                    var lines = content_data.split("<br/>");
2091 runge 482
 
1899 linlun 483
                    for (var n = 1; n < lines.length; n++)
484
                    {
485
                        var line = lines[n].trim(" \n");
2091 runge 486
 
1899 linlun 487
                        if (line.indexOf(endString) != -1)
488
                        {
489
                            break;
490
                        }
491
                        var pos = line.indexOf(nameStartString + (persons.length+1) + ".");
2091 runge 492
 
1899 linlun 493
                        if (pos != -1)
494
                        {
495
                            pos += nameStartString.length + 2
496
                            persons[persons.length] = line.substr(pos, line.length-pos-nameEndString.length).html_entity_decode().replace("  ", " ");
497
                        }
498
                    }
499
                    if (persons.length > 0) {
500
                        Storage_SetJsonParameter("PhoneBook", number, persons);
2091 runge 501
 
1899 linlun 502
                        //CAll all listeners!
503
                        //....
2091 runge 504
 
1899 linlun 505
                        Log("\033[31mOnlinePhonebook: Found: " + JSON.stringify(persons) + "\033[0m\n");
506
                    }
507
                }
508
                else
509
                {
510
                    Log("\033[31mOnlinePhonebook: Failed to do name lookup, result was: " + result + "\033[0m\n");
2091 runge 511
                }
1899 linlun 512
            }
513
        );
2014 linlun 514
        */
2091 runge 515
 
516
  }
517
  else
518
  {
519
    //Log("Number already stored\n");
520
 
521
    Sensor_UpdateNameInPhonecalls(timestamp, phonebookNumbers);
522
  }
2152 arune 523
 
524
  return phonebookNumbers;
1899 linlun 525
}
526
Console_RegisterCommand(Sensor_StoreNumberInPhonebook, function(arg_index, args) { return Console_StandardAutocomplete(arg_index, args); });
527
 
2182 arune 528
function Sensor_StoreNumberInPhonebookManual(number, name)
529
{
530
    if (arguments.length < 2)
531
    {
532
        Log("\033[31mNot enough parameters given.\033[0m\n");
533
        return false;
534
    }
535
 
536
    var completename = arguments[1];
537
    for (var i=2; i<arguments.length; i++)
538
    {
539
        completename = completename+" "+arguments[i];
540
    }
541
 
542
    phonebookNumbers = [];
543
    phonebookNumbers.push(completename);
544
    Storage_SetJsonParameter("PhoneBook", number, phonebookNumbers);
545
}
546
Console_RegisterCommand(Sensor_StoreNumberInPhonebookManual, function(arg_index, args) { return Console_StandardAutocomplete(arg_index, args); });
547
 
2091 runge 548
function Sensor_UpdateNameInPhonecalls(timestamp, numbers)
549
{
550
  if (numbers.length > 0)
551
  {
552
    var lastValueString = Storage_GetParameter("PhoneCalls", timestamp);
1899 linlun 553
 
2091 runge 554
    if (lastValueString)
555
    {
556
      var lastValue = JSON.parse(lastValueString);
1899 linlun 557
 
2091 runge 558
      lastValue.names = numbers;
559
 
560
      Storage_SetParameter("PhoneCalls", timestamp, JSON.stringify(lastValue));
561
    }
562
  }
563
}
564