📜 ⬆️ ⬇️

Weather forecast by phone

I decided that it would turn out to be a very useful opportunity when going to work to listen to the weather forecast on the telephone loudspeaker by pressing one programmed button. How I did it look under the cut.



The first thing we need is the weather forecast itself. I decided to take it from the site gismeteo.ru.
How I did it:
I went to the site gismeteo.ru found your city.
I clicked the "Informers" link in the header.
On the next page I found the text “Data in XML format” and took the link from the “get code” button.
Thus, we now know how we get a fresh forecast in XML format.

Now you need to save it for further processing:
I did not reinvent the bicycle and wrote a two-line bash script


Copy Source | Copy HTML #!/bin/bash cd /usr/isp/weather /usr/bin/wget 'http://informer.gismeteo.ru/xml/34214_1.xml' -O ./34214_1.xml
  1. Copy Source | Copy HTML #!/bin/bash cd /usr/isp/weather /usr/bin/wget 'http://informer.gismeteo.ru/xml/34214_1.xml' -O ./34214_1.xml
  2. Copy Source | Copy HTML #!/bin/bash cd /usr/isp/weather /usr/bin/wget 'http://informer.gismeteo.ru/xml/34214_1.xml' -O ./34214_1.xml
  3. Copy Source | Copy HTML #!/bin/bash cd /usr/isp/weather /usr/bin/wget 'http://informer.gismeteo.ru/xml/34214_1.xml' -O ./34214_1.xml

')
where informer.gismeteo.ru/xml/34214_1.xml is the link for your city. The wget command downloads our XML and writes it to file 34214_1.xml in the current directory, we will need it later. To make the forecast always fresh, you need to write this script to cron for example like this:

*/60 * * * * /usr/isp/weather/weather_up.sh

I decided to make a voice prediction algorithm in Perl which interacts with Asterisk through AGI . Our algorithm is required to parse the XML file and output to stdout a sequence of lines with commands for Asterisk to play audio files like this:

Copy Source | Copy HTML
  1. EXEC Playback weather / Po_dannym_Gismeteo ""
  2. EXEC Playback weather / tod / dnem ""
  3. EXEC Playback weather / m / 15ogo ""
  4. EXEC Playback weather / budet ""
  5. EXEC Playback weather / cloudiness / pasmurno ""
  6. EXEC Playback weather / precipitation / dozhd '"" <br/>
    EXEC Playback weather / temp_vosduha_sostavit "" <br/> EXEC Playback weather / digits / 20 "" <br/> EXEC Playback weather / digits / 2 "" <br/> EXEC Playback weather / Do "" <br/> EXEC Playback weather / digits / 20 "" <br/> EXEC Playback weather / gradusov_C "" <br/> EXEC Playback weather / Skorost'_vetra_sostavit ""
  7. EXEC Playback weather / digits / 5 ""
  8. EXEC Playback weather / Do ""
  9. EXEC Playback weather / digits / 3 ""
  10. EXEC Playback weather / metrov_v_sekundu ""
  11. EXEC Playback weather / Atmosfernoe_davlenie_sostavit ""
  12. EXEC Playback weather / digits / 700 ""
  13. EXEC Playback weather / digits / 40 ""
  14. EXEC Playback weather / digits / 7 ""
  15. EXEC Playback weather / Do ""
  16. EXEC Playback weather / digits / 700 ""
  17. EXEC Playback weather / digits / 40 ""
  18. EXEC Playback weather / digits / 5 ""
  19. EXEC Playback weather / milimetrov_rtutnogo_stolba ""


As you noticed, you will have to prepare a lot of sound recordings, but this is once and for all.

In my version in some recorded phrases there is the word "from". For example: Atmosfernoe_davlenie_sostavit read as "Atmospheric pressure will be from."

Actually, I used the XML :: Simple module to parse XML. It seemed to me the easiest to use. To replace the XML tags with the lines I need, I used lists for dubbing:

Copy Source | Copy HTML
  1. my $ date_name = {
  2. 1 => [ "EXEC Playback weather \ / m \ / 1ogo \" \ "\ n" ],
  3. 2 => [ "EXEC Playback weather \ / m \ / 2ogo \" \ "\ n" ],
  4. 3 => [ "EXEC Playback weather \ / m \ / 3ogo \" \ "\ n" ],
  5. .....

With the algorithm for converting numbers into a set of commands for playing numbers, I also decided not to reinvent the wheel and took a ready-made algorithm for converting money to a record (unfortunately I don’t remember anyone else), replaced the lines such as " one " with " Playback weather \ / digits " in the right places. \ / 1 \ "\" \ n "and the algorithm is adapted (a lot of time saved).
I think now everything will be clear, it's time to look at the script:


Copy Source | Copy HTML
  1. #! / usr / bin / perl
  2. use strict;
  3. use XML :: Simple;
  4. use Data :: Dumper;
  5. my $ date_name = {
  6. 1 => [ "EXEC Playback weather \ / m \ / 1ogo \" \ "\ n" ],
  7. 2 => [ "EXEC Playback weather \ / m \ / 2ogo \" \ "\ n" ],
  8. 3 => [ "EXEC Playback weather \ / m \ / 3ogo \" \ "\ n" ],
  9. 4 => [ "EXEC Playback weather \ / m \ / 4ogo \" \ "\ n" ],
  10. 5 => [ "EXEC Playback weather \ / m \ / 5ogo \" \ "\ n" ],
  11. 6 => [ "EXEC Playback weather \ / m \ / 6ogo \" \ "\ n" ],
  12. 7 => [ "EXEC Playback weather \ / m \ / 7ogo \" \ "\ n" ],
  13. 8 => [ "EXEC Playback weather \ / m \ / 8ogo \" \ "\ n" ],
  14. 9 => [ "EXEC Playback weather \ / m \ / 9ogo \" \ "\ n" ],
  15. 10 => [ "EXEC Playback weather \ / m \ / 10ogo \" \ "\ n" ],
  16. 11 => [ "EXEC Playback weather \ / m \ / 11ogo \" \ "\ n" ],
  17. 12 => [ "EXEC Playback weather \ / m \ / 12ogo \" \ "\ n" ],
  18. 13 => [ "EXEC Playback weather \ / m \ / 13ogo \" \ "\ n" ],
  19. 14 => [ "EXEC Playback weather \ / m \ / 14ogo \" \ "\ n" ],
  20. 15 => [ "EXEC Playback weather \ / m \ / 15ogo \" \ "\ n" ],
  21. 16 => [ "EXEC Playback weather \ / m \ / 16ogo \" \ "\ n" ],
  22. 17 => [ "EXEC Playback weather \ / m \ / 17ogo \" \ "\ n" ],
  23. 18 => [ "EXEC Playback weather \ / m \ / 18ogo \" \ "\ n" ],
  24. 19 => [ "EXEC Playback weather \ / m \ / 19ogo \" \ "\ n" ],
  25. 20 => [ "EXEC Playback weather \ / m \ / 10ogo \" \ "\ n" ],
  26. 21 => [ "EXEC Playback weather \ / m \ / 21ogo \" \ "\ n" ],
  27. 22 => [ "EXEC Playback weather \ / m \ / 22ogo \" \ "\ n" ],
  28. 23 => [ "EXEC Playback weather \ / m \ / 23ogo \" \ "\ n" ],
  29. 24 => [ "EXEC Playback weather \ / m \ / 24ogo \" \ "\ n" ],
  30. 25 => [ "EXEC Playback weather \ / m \ / 25ogo \" \ "\ n" ],
  31. 26 => [ "EXEC Playback weather \ / m \ / 26ogo \" \ "\ n" ],
  32. 27 => [ "EXEC Playback weather \ / m \ / 27ogo \" \ "\ n" ],
  33. 28 => [ "EXEC Playback weather \ / m \ / 28ogo \" \ "\ n" ],
  34. 29 => [ "EXEC Playback weather \ / m \ / 29ogo \" \ "\ n" ],
  35. 30 => [ "EXEC Playback weather \ / m \ / 30ogo \" \ "\ n" ],
  36. 31 => [ "EXEC Playback weather \ / m \ / 31ogo \" \ "\ n" ]
  37. };
  38. my $ hour_name = {
  39. 0 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  40. 1 => [ "EXEC Playback weather \ / hour \ / chas \" \ "\ n" ],
  41. 2 => [ "EXEC Playback weather \ / hour \ / chasa \" \ "\ n" ],
  42. 3 => [ "EXEC Playback weather \ / hour \ / chasa \" \ "\ n" ],
  43. 4 => [ "EXEC Playback weather \ / hour \ / chasa \" \ "\ n" ],
  44. 5 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  45. 6 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  46. 7 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  47. 8 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  48. 9 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  49. 10 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  50. 11 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  51. 12 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  52. 13 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  53. 14 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  54. 15 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  55. 16 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  56. 17 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  57. 18 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  58. 19 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  59. 20 => [ "EXEC Playback weather \ / hour \ / chasov \" \ "\ n" ],
  60. 21 => [ "EXEC Playback weather \ / hour \ / chas \" \ "\ n" ],
  61. 22 => [ "EXEC Playback weather \ / hour \ / chasa \" \ "\ n" ],
  62. 23 => [ "EXEC Playback weather \ / hour \ / chasa \" \ "\ n" ],
  63. };
  64. my $ m_name = {
  65. 1 => [ "EXEC Playback weather \ / m \ / yanvarya \" \ "\ n" ],
  66. 2 => [ "EXEC Playback weather \ / m \ / fevralya \" \ "\ n" ],
  67. 3 => [ "EXEC Playback weather \ / m \ / marta \" \ "\ n" ],
  68. 4 => [ "EXEC Playback weather \ / m \ / aprelya \" \ "\ n" ],
  69. 5 => [ "EXEC Playback weather \ / m \ / maya \" \ "\ n" ],
  70. 6 => [ "EXEC Playback weather \ / m \ / iunya \" \ "\ n" ],
  71. 7 => [ "EXEC Playback weather \ / m \ / iylya \" \ "\ n" ],
  72. 8 => [ "EXEC Playback weather \ / m \ / avgusta \" \ "\ n" ],
  73. 9 => [ "EXEC Playback weather \ / m \ / sentyabrya \" \ "\ n" ],
  74. 10 => [ "EXEC Playback weather \ / m \ / octyabya \" \ "\ n" ],
  75. 11 => [ "EXEC Playback weather \ / m \ / noyabrya \" \ "\ n" ],
  76. 12 => [ "EXEC Playback weather \ / m \ / decabrya \" \ "\ n" ]
  77. };
  78. my $ tod_name = {
  79. 0 => [ "EXEC Playback weather \ / tod \ / noch'u \" \ "\ n" ],
  80. 1 => [ "EXEC Playback weather \ / tod \ / utrom \" \ "\ n" ],
  81. 2 => [ "EXEC Playback weather \ / tod \ / dnem \" \ "\ n" ],
  82. 3 => [ "EXEC Playback weather \ / tod \ / vecherom \" \ "\ n" ]
  83. };
  84. my $ cloudiness_name = {
  85. 0 => [ "EXEC Playback weather \ / cloudiness \ / yasno \" \ "\ n" ],
  86. 1 => [ "EXEC Playback weather \ / cloudiness \ / malooblachno \" \ "\ n" ],
  87. 2 => [ "EXEC Playback weather \ / cloudiness \ / oblachno \" \ "\ n" ],
  88. 3 => [ "EXEC Playback weather \ / cloudiness \ / pasmurno \" \ "\ n" ]
  89. };
  90. my $ precipitation_name = {
  91. 4 => [ "EXEC Playback weather \ / precipitation \ / dozhd '\" \ "\ n" ],
  92. 5 => [ "EXEC Playback weather \ / precipitation \ / liven '\" \ "\ n" ],
  93. 6 => [ "EXEC Playback weather \ / precipitation \ / sneg \" \ "\ n" ],
  94. 7 => [ "EXEC Playback weather \ / precipitation \ / sneg \" \ "\ n" ],
  95. 8 => [ "EXEC Playback weather \ / precipitation \ / groza \" \ "\ n" ],
  96. 9 => [ "" ],
  97. 10 => [ "EXEC Playback weather \ / precipitation \ / bez_osadkov \" \ "\ n" ]
  98. };
  99. my $ wind_direction_name = {
  100. 0 => [ "EXEC Playback weather \ / wind_direction \ / severnyi \" \ "\ n" ],
  101. 1 => [ "EXEC Playback weather \ / wind_direction \ / severo-vostochnyi \" \ "\ n" ],
  102. 2 => [ "EXEC Playback weather \ / wind_direction \ / vostochno-uzhnyi \" \ "\ n" ],
  103. 3 => [ "EXEC Playback weather \ / wind_direction \ / ugo-zapadnyi \" \ "\ n" ]
  104. };
  105. my $ xmlWeather = new XML :: Simple (keeproot => 1 , searchpath => "." , forcearray => 1 , suppressempty => '' );
  106. my $ xmlData1 = $ xmlWeather -> XMLin ( '/usr/isp/weather/34214_1.xml' );
  107. my $ xmlData = $ xmlData1 -> {MMWEATHER} [ 0 ] -> {REPORT} [ 0 ] -> {TOWN} [ 0 ] -> {FORECAST};
  108. $ | = 1 ;
  109. while (<STDIN>) {
  110. chomp ( $ _ );
  111. last if length ( $ _ ) == 0 ;
  112. }
  113. # "Po dannym Gismeteo"
  114. print "EXEC Playback weather \ / Po_dannym_Gismeteo \" \ "\ n" ;
  115. my $ i = 0 ;
  116. for ( $ i = 0 ; $ i < 4 ; $ i ++)
  117. {
  118. print $ tod_name -> { $ xmlData -> [ $ i ] -> {tod}} -> [ 0 ];
  119. print $ date_name -> { $ xmlData -> [ $ i ] -> {day}} -> [ 0 ];
  120. print $ m_name -> { $ xmlData -> [ $ i ] -> {month}} -> [ 0 ];
  121. #
  122. print "EXEC Playback weather \ / budet \" \ "\ n" ;
  123. print $ cloudiness_name -> { $ xmlData -> [ $ i ] -> {PHENOMENA} [ 0 ] -> {cloudiness}} -> [ 0 ];
  124. print $ precipitation_name -> { $ xmlData -> [ $ i ] -> {PHENOMENA} [ 0 ] -> {precipitation}} -> [ 0 ];
  125. # Temp
  126. print "EXEC Playback weather \ / temp_vosduha_sostavit \" \ "\ n" ;
  127. print digit_string ( $ xmlData -> [ $ i ] -> {TEMPERATURE} [ 0 ] -> {max});
  128. print "EXEC Playback weather \ / Do \" \ "\ n" ;
  129. print digit_string ( $ xmlData -> [ $ i ] -> {TEMPERATURE} [ 0 ] -> {min});
  130. print "EXEC Playback weather \ / gradusov_C \" \ "\ n" ;
  131. # Veter
  132. print "EXEC Playback weather \ / Skorost'_vetra_sostavit \" \ "\ n" ;
  133. print digit_string ( $ xmlData -> [ $ i ] -> {WIND} [ 0 ] -> {max});
  134. print "EXEC Playback weather \ / Do \" \ "\ n" ;
  135. print digit_string ( $ xmlData -> [ $ i ] -> {WIND} [ 0 ] -> {min});
  136. print "EXEC Playback weather \ / metrov_v_sekundu \" \ "\ n" ;
  137. # Atmosfernoe davlenie
  138. print "EXEC Playback weather \ / Atmosfernoe_davlenie_sostavit \" \ "\ n" ;
  139. print digit_string ( $ xmlData -> [ $ i ] -> {PRESSURE} [ 0 ] -> {max});
  140. print "EXEC Playback weather \ / Do \" \ "\ n" ;
  141. print digit_string ( $ xmlData -> [ $ i ] -> {PRESSURE} [ 0 ] -> {min});
  142. print "EXEC Playback weather \ / milimetrov_rtutnogo_stolba \" \ "\ n" ;
  143. }
  144. # ================================================= =================================================
  145. # ================================================= =================================================
  146. # ================================================= =================================================
  147. sub digit_string {
  148. my $ digit = shift;
  149. local $ _ ;
  150. my $ sign = 1 if $ digit = ~ s / ^ - + //;
  151. $ digit = ~ s # ^ 0 + ##;
  152. my ( $ b_dig , $ s_dig ) = (split (m /[ , . digit $ , 2 ));
  153. $ s_dig = "" ;
  154. #
  155. # Clear the numbers from the `extra 'characters (100_000,43)
  156. #
  157. if (defined $ b_dig and length $ b_dig ) {
  158. # $ b_dig = ~ s # [^ \ d] ## sg;
  159. } else {
  160. $ b_dig = "" ;
  161. }
  162. if (defined $ s_dig and length $ s_dig ) {
  163. # $ s_dig = ~ s # [^ \ d] ## sg;
  164. } else {
  165. $ s_dig = "" ;
  166. }
  167. #
  168. # We round a penny in a big way, if as a result of rounding
  169. # get the ruble, then add it to b_dig (rubles)
  170. #
  171. # if (sprintf ('% 0.2f', "0. $ s_dig") == 1) {
  172. # $ b_dig ++;
  173. # $ s_dig = '00';
  174. #} else {
  175. # $ s_dig = substr (sprintf ('% 0.2f', "0. $ s_dig"), 2);
  176. #}
  177. #
  178. my @ array = split ( //, ($ b_dig || 0));
  179. #
  180. # Determine the digit capacity of the number.
  181. #
  182. my $ class_id = int (scalar (@ array ) / 3 );
  183. $ class_id ++ if (scalar (@ array )% 3 );
  184. #
  185. # Unsupported bit depth.
  186. #
  187. return $ digit if $ class_id > 5 ;
  188. my $ digits_name = {
  189. 0 => [ "EXEC Playback weather \ / digits \ / 0 \" \ "\ n" , "" , "" ],
  190. 1 => [[ "EXEC Playback weather \ / digits \ / 1 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 1a \" \ "\ n" ], "EXEC Playback weather \ / digits \ / 10 \ "\" \ n " , " EXEC Playback weather \ / digits \ / 100 \ "\" \ n " ],
  191. 2 => [[ "EXEC Playback weather \ / digits \ / 2 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 2e \" \ "\ n" ], "EXEC Playback weather \ / digits \ / 20 \ "\" \ n " , " EXEC Playback weather \ / digits \ / 200 \ "\" \ n " ],
  192. 3 => [ "EXEC Playback weather \ / digits \ / 3 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 30 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 300 \ "\" \ n " ],
  193. 4 => [ "EXEC Playback weather \ / digits \ / 4 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 40 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 400 \ "\" \ n " ],
  194. 5 => [ "EXEC Playback weather \ / digits \ / 5 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 50 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 500 \ "\" \ n " ],
  195. 6 => [ "EXEC Playback weather \ / digits \ / 6 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 60 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 600 \ "\" \ n " ],
  196. 7 => [ "EXEC Playback weather \ / digits \ / 7 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 70 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 700 \ "\" \ n " ],
  197. 8 => [ "EXEC Playback weather \ / digits \ / 8 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 80 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 800 \ "\" \ n " ],
  198. 9 => [ "EXEC Playback weather \ / digits \ / 9 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 90 \" \ "\ n" , "EXEC Playback weather \ / digits \ / 900 \ "\" \ n " ],
  199. };
  200. my $ dec_digits = {
  201. 11 => "EXEC Playback weather \ / digits \ / 11 \" \ "\ n" ,
  202. 12 => "EXEC Playback weather \ / digits \ / 12 \" \ "\ n" ,
  203. 13 => "EXEC Playback weather \ / digits \ / 13 \" \ "\ n" ,
  204. 14 => "EXEC Playback weather \ / digits \ / 14 \" \ "\ n" ,
  205. 15 => "EXEC Playback weather \ / digits \ / 15 \" \ "\ n" ,
  206. 16 => "EXEC Playback weather \ / digits \ / 16 \" \ "\ n" ,
  207. 17 => "EXEC Playback weather \ / digits \ / 17 \" \ "\ n" ,
  208. 18 => "EXEC Playback weather \ / digits \ / 18 \" \ "\ n" ,
  209. 19 => "EXEC Playback weather \ / digits \ / 19 \" \ "\ n"
  210. };
  211. my $ digits_class = {
  212. '-1' => [ 1 , "" , "" , "" ],
  213. 0 => [ 0 , "" , "" , "" ],
  214. 1 => [ 1 , "EXEC Playback weather \ / digits \ / tysiacha \" \ "\ n" , "EXEC Playback weather \ / digits \ / tysiach \" \ "\ n" , "EXEC Playback weather \ / digits \ / tysiachi \ "\" \ n " ],
  215. 2 => [ 0 , "EXEC Playback weather \ / digits \ / million \" \ "\ n" , "EXEC Playback weather \ / digits \ / millionov \" \ "\ n" , "EXEC Playback weather \ / digits \ / milliona \ "\" \ n " ],
  216. 3 => [ 0 , "EXEC Playback weather \ / digits \ / milliard \" \ "\ n" , "EXEC Playback weather \ / digits \ / milliardov \" \ "\ n" , "EXEC Playback weather \ / digits \ / milliarda \ "\" \ n " ],
  217. 4 => [ 0 , "EXEC Playback weather \ / digits \ / trillion \" \ "\ n" , "EXEC Playback weather \ / digits \ / trillionov \" \ "\ n" , "EXEC Playback weather \ / digits \ / trilliona \ "\" \ n " ],
  218. };
  219. #
  220. # Determine the length of the left `three '...
  221. #
  222. my $ id = 0 ;
  223. unless ((scalar @ array )% 3 ) {
  224. $ id = 2 ;
  225. } else {
  226. $ id = ((scalar @ array )% 3 ) - 1 ;
  227. }
  228. my $ str = '' ;
  229. my $ sub_str = 0 ;
  230. my $ tvar = 0 ;
  231. if ( $ array [ 0 ] == 0 ) {
  232. #
  233. # If rubles are still zero, then we write 'zero rubles',
  234. # if you don’t need to just close the next line ...
  235. #
  236. $ str . = $ digits_name -> { '0' } -> [ 0 ]. '' . $ digits_class -> { '0' } -> [ 2 ]. '' ;
  237. } else {
  238. while (defined ( $ _ = shift @ array )) {
  239. if ( $ _ > 0 ) {
  240. if ( $ _ == 1 and $ id == 1 ) {
  241. #
  242. # Consider the amount to be used in sub num ()
  243. #
  244. $ sub_str + = $ _ * 10 ;
  245. if (defined ( $ tvar = shift @ array ) and $ tvar > 0 ) {
  246. $ str . = $ dec_digits -> { $ _ . $ tvar };
  247. $ sub_str + = $ tvar ;
  248. $ id -;
  249. } else {
  250. unshift @ array , $ tvar ;
  251. if (ref $ digits_name -> { $ _ } -> [ $ id ] eq 'ARRAY' ) {
  252. # $ str. = $ digits_name -> {$ _} -> [$ id] -> [$ digits_class -> {$ class_id-1} -> [0]];
  253. } else {
  254. $ str . = $ digits_name -> { $ _ } -> [ $ id ];
  255. }
  256. }
  257. } else {
  258. #
  259. # Consider the amount to be used in sub num ()
  260. #
  261. $ sub_str + = ( $ _ * ( 10 ** $ id ));
  262. if (ref $ digits_name -> { $ _ } -> [ $ id ] eq 'ARRAY' ) {
  263. $ str . = $ digits_name -> { $ _ } -> [ $ id ] -> [ $ digits_class -> { $ class_id - 1 } -> [ 0 ]];
  264. } else {
  265. $ str . = $ digits_name -> { $ _ } -> [ $ id ];
  266. }
  267. }
  268. $ str . = '' ;
  269. }
  270. if (- $ id == - 1 ) {
  271. $ id = 2 ;
  272. $ class_id -;
  273. if ( $ sub_str > 0 ) {
  274. $ str . = num ( $ sub_str , (@ { $ digits_class -> { $ class_id }}) [ 1 .. 3 ]). '' ;
  275. } elsif ( $ class_id == 0 ) {
  276. $ str . = $ digits_class -> { $ class_id } -> [ 2 ]. '' ;
  277. }
  278. $ sub_str = 0 ;
  279. }
  280. }
  281. }
  282. $ str . = $ s_dig . '' . num ( $ s_dig , (@ { $ digits_class -> { '-1' }}) [ 1 .. 3 ]);
  283. if (defined $ sign ) {
  284. $ str = "EXEC Playback weather \ / digits / minus \" \ "\ n" . $ str ;
  285. }
  286. $ s_dig = substr ( $ str , 0 , 1 );
  287. #
  288. # In the case where it was used it turned out easier
  289. # so, than through use locale & ucfirst ...
  290. #
  291. if ( $ s_dig = ~ tr / abvgdeyzkykmnoprstufkhtschshchyyyyuya / abvgdeyezhziyklmlopprstufhtstshschschyyuya /) {
  292. substr ( $ str , 0 , 1 , $ s_dig );
  293. }
  294. return $ str ;
  295. }
  296. #
  297. # Used when translating money into a string in words ..
  298. #
  299. sub num {
  300. my $ d1 = $ _ [ 0 ]% 10 ;
  301. my $ d2 = int (( $ _ [ 0 ]% 100 ) / 10 );
  302. return $ _ [ 2 ] if (( $ d2 == 1 ) or ( $ d1 = ~ / [ 05 - 9 ] /));
  303. return $ _ [ 1 ] if ( $ d1 == 1 );
  304. return $ _ [ 3 ];
  305. }


Next we need to teach Asterisk to use this script. To do this, in the extensions.conf file in the right context, we write it like this:


Copy Source | Copy HTML
  1. exten => XXXX, 1, Wait (1)
  2. exten => XXXX, n, Answer ()
  3. exten => XXXX, n, Agi (/usr/isp/weather/weather.pl)
  4. exten => XXXX, n, Hangup ()

Where XXXX is the number you want to assign to the Weather service. For example, I have a Digium board, through which everyone can check the weather by calling from any phone.
That's all!

Source: https://habr.com/ru/post/70771/


All Articles