Subversion Repositories HomeAutomation

Rev

Rev 2182 | Rev 2207 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

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