New TclWeather module

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

New TclWeather module

Tim Miller WB0RXX
Hi guys and gals,

I have developed a module for our favorite program which provides
on-demand weather information.  It is designed for use with the Davis
Vantage Pro running vanprod, but it should not be too hard to change it
to work with any weather station that has a CSV data output.

Please note that this module is designed to work under the latest CVS
release of SvxLink (v0.7.0rc2).  It should work with older versions of
SvxLink with little or no tweaking.

To make it work, just add the following to your /etc/svxlink.conf

MODULES=ModuleHelp,ModuleParrot,ModuleTclVoiceMail,ModuleTclWeather

[ModuleTclWeather]
NAME=TclWeather
PLUGIN_NAME=Tcl
ID=8                    <----  Think "Weather on the eights" :-)
TIMEOUT=300

To get the time and negative values to function properly, I needed to
add two symlinks from within the Default directory:

lrwxrwxrwx  1 tim users   -.raw -> ../TclWeather/minus.raw
lrwxrwxrwx  1 tim users   :.raw -> ../TclWeather/hours.raw

The first symlink allows the playNumber function to say "minus" when it
sees a "-".  The second symlink is a bit less obvious.  When playNumber
is saying "12:34" the  ":" is interpreted as the word "hours".  It
certainly is not very pretty, but it seems to work. ;-)

The audio files are a bit too large to post on this forum (+6 MB), so
here is an external link to them:

   http://www.MontevideoComputers.com/ham/files/TclWeather_sounds.tar.gz

This tarball also contains the scripts used to generate the sound files,
as well as the Davis forecast rules.  This should be enough information
to re-record these files in a language other than English, or if you do
not want to hear my voice on your system. <grin>

For anyone that is interested, I am also working on a number of other
additions to SvxLink including Long Tone Zero (LiTZ)/operator paging,
Skywarn activation notices, NOAA weather radio rebroadcasts, and
on-demand broadcasts of local info, the ARRL letter, and the Newsline
bulletins.  I would be most interested to know if anyone else is doing
something similar, as I'd be happy to share what I have so far.

My thanks again to Tobias for making such a very FB program that is so
easy to work with!

73 de Tim

--
Tim Miller WB0RXX [EN24dw]
SvxLink v0.7.0rc2 (Nov  2 2005)
Slackware 10.1/P200 MHz/64 MB

###############################################################################
#
# Tcl module event handlers
#
###############################################################################
#
# This is the namespace in which all functions and variables below will exist.
# The name must match the configuration variable "NAME" in the
# [Module TclWeather] section in the configuration file. The name may be changed
# but it must be changed in both places.
#

namespace eval TclWeather {

#
# Set weather data locations
#
set currentobs_file /var/spool/weather/currentobs;
set extremes_file /var/spool/weather/extremes;


#
# Extract the module name from the current namespace
#
set module_name [namespace tail [namespace current]];


#
# Emulates the 'lassign' command in TclX
#
proc lassign {list args} {
  foreach elem $list varName $args {
    upvar 1 $varName var
    set var $elem
  }
}


#
# An "overloaded" playMsg that eliminates the need to write the module name
# as the first argument.
#
proc playMsg {msg} {
  variable module_name;
  ::playMsg $module_name $msg;
}


#
# A convenience function for printing out information prefixed by the
# module name
#
proc printInfo {msg} {
  variable module_name;
  puts "$module_name: $msg";
}


#
# Executed when this module is being activated
#
proc activating_module {} {
  variable module_name;
  Module::activating_module $module_name;
  playSilence 500;
  playMsg "menu";
  playSilence 500;
}


#
# Main menu selection
#
proc dtmf_cmd_received {cmd} {
    if {$cmd == ""} {
      deactivateModule;
    } elseif {$cmd == "0"} {
      cmdPlayQuickHelp;
    } elseif {$cmd == "1"} {
      standardWeather;
    } elseif {$cmd == "2"} {
      extendedWeather;
    } elseif {$cmd == "3"} {
      dailyExtremes;
    } elseif {$cmd == "4"} {
      davisForecast;
    } else {
      playNumber $cmd;
      playMsg "unknown_command";
    }
}


#
# Standard weather information
#
proc standardWeather {} {
  variable currentobs_file;

  set file [open $currentobs_file];
  set content [read $file];
  close $file;

  set wxfields [split $content ","];

  lassign $wxfields \
    hh mm ss bar temp avg_windspd windspd wind_dir hum dewpoint \
    wind_chill heat_index rain_rate daily_rain mtd_rain ytd_rain \
    sunrise sunset indoor_temp indoor_hum indoor_dewpoint bar_trend \
    fcst_icon fcst_rule storm_start storm_rain rain24 rain1 rain_con;

  playMsg "current";
  playMsg "weather_conditions";
  playMsg "for_location";
  playSilence 500;

  playMsg "winds";
  if { $windspd > 0 } {
    playMsg "$wind_dir";
    playMsg "at";
    playNumber "$windspd";
    playMsg "miles_per_hour";
  } else {
    playMsg "are_calm";
  }
  playSilence 500;

  playMsg "temperature";
  playNumber "[format "%.0f" $temp]";
  playMsg "degrees";
  playSilence 500;

  playMsg "humidity";
  playNumber "$hum";
  playMsg "percent";
  playSilence 500;

  playMsg "dewpoint";
  playNumber "[format "%.0f" $dewpoint]";
  playMsg "degrees";
  playSilence 500;

  playMsg "barometer";
  playNumber "[format "%.2f" $bar]";
  playMsg "inches";
  playMsg "and";
  playMsg "$bar_trend";
  playSilence 500;

  if { $wind_chill != "--" } {
    playMsg "wind_chill";
    playNumber "[format "%.0f" $wind_chill]";
    playMsg "degrees";
    playSilence 500;
  }

  if { $heat_index != "--" } {
    playMsg "heat_index";
    playNumber "[format "%.0f" $heat_index]";
    playMsg "degrees";
    playSilence 500;
  }

  if { $daily_rain > 0 } {
    playMsg "daily_rainfall";
    playNumber "$daily_rain";
    playMsg "inches";
    playSilence 500;
  }
  playSilence 500;
}


#
# Extended weather information
#
proc extendedWeather {} {
  variable currentobs_file;

  set file [open $currentobs_file];
  set content [read $file];
  close $file;

  set wxfields [split $content ","];

  lassign $wxfields \
    hh mm ss bar temp avg_windspd windspd wind_dir hum dewpoint \
    wind_chill heat_index rain_rate daily_rain mtd_rain ytd_rain \
    sunrise sunset indoor_temp indoor_hum indoor_dewpoint bar_trend \
    fcst_icon fcst_rule storm_start storm_rain rain24 rain1 rain_con;

  playMsg "extended";
  playMsg "weather_conditions";
  playMsg "for_location";
  playSilence 500;

  playMsg "average_wind_speed";
  playNumber "$avg_windspd";
  playMsg "miles_per_hour";
  playSilence 500;

  playMsg "month_to_date";
  playMsg "rainfall";
  playNumber "$mtd_rain";
  playMsg "inches";
  playSilence 500;

  playMsg "year_to_date";
  playMsg "rainfall";
  playNumber "$ytd_rain";
  playMsg "inches";
  playSilence 500;

  if { $rain1 > 0 } {
    playMsg "rainfall";
    playMsg "last";
    playMsg "sixty_minutes";
    playNumber "$rain1";
    playMsg "inches";
    playSilence 500;
  }

  if { $rain24 > 0 } {
    playMsg "rainfall";
    playMsg "last";
    playMsg "twenty_four_hours";
    playNumber "$rain24";
    playMsg "inches";
    playSilence 500;
  }

  if { $storm_rain > 0 } {
    playMsg "storm_total";
    playMsg "rainfall";
    playNumber "$storm_rain";
    playMsg "inches";
    playSilence 500;
  }

  playMsg "sunrise";
  playNumber "$sunrise";
  playMsg "minutes";
  playSilence 500;

  playMsg "sunset";
  playNumber "$sunset";
  playMsg "minutes";
  playSilence 500;

  playMsg "indoor";
  playMsg "temperature";
  playNumber "[format "%.0f" $indoor_temp]";
  playMsg "degrees";
  playSilence 500;

  playMsg "indoor";
  playMsg "humidity";
  playNumber "[format "%.0f" $indoor_hum]";
  playMsg "percent";
  playSilence 500;

  playMsg "indoor";
  playMsg "dewpoint";
  playNumber "[format "%.0f" $indoor_dewpoint]";
  playMsg "degrees";
  playSilence 500;
}


#
# Extremes data since midnight
#
proc dailyExtremes {} {
  variable extremes_file;

  set file [open $extremes_file];
  set content [read $file];
  close $file;

  set wxfields [split $content ","];

  lassign $wxfields \
    min_bar min_bar_tm max_bar max_bar_tm min_temp min_temp_tm \
    max_temp max_temp_tm max_wind max_wind_dir max_wind_tm \
    min_hum min_hum_tm max_hum max_hum_tm min_dew min_dew_tm \
    max_dew max_dew_tm min_wind_chill min_wind_chill_tm \
    max_heat_index max_heat_index_tm max_rain_rate max_rain_rate_tm \
    daily_rain ytd_rain min_indoor_temp min_indoor_temp_tm \
    max_indoor_temp max_indoor_temp_tm min_indoor_hum min_indoor_hum_tm \
    max_indoor_hum max_indoor_hum_tm min_indoor_dew min_indoor_dew_tm \
    max_indoor_dew max_indoor_dew_tm;

  playMsg "extreme";
  playMsg "weather_conditions";
  playMsg "for_location";
  playSilence 500;

  playMsg "maximum";
  playMsg "winds";
  if { $max_wind > 0 } {
    playMsg "$max_wind_dir";
    playMsg "at";
    playNumber "$max_wind";
    playMsg "miles_per_hour";
  playMsg "at";
  playNumber "[format "%.5s" $max_wind_tm]";
  playMsg "minutes";
  } else {
    playMsg "are_calm";
  }
  playSilence 500;

  playMsg "maximum";
  playMsg "temperature";
  playNumber "[format "%.0f" $max_temp]";
  playMsg "degrees";
  playMsg "at";
  playNumber "[format "%.5s" $max_temp_tm]";
  playMsg "minutes";
  playSilence 500;

  playMsg "minimum";
  playMsg "temperature";
  playNumber "[format "%.0f" $min_temp]";
  playMsg "degrees";
  playMsg "at";
  playNumber "[format "%.5s" $min_temp_tm]";
  playMsg "minutes";
  playSilence 500;

  playMsg "maximum";
  playMsg "humidity";
  playNumber "$max_hum";
  playMsg "percent";
  playMsg "at";
  playNumber "[format "%.5s" $max_hum_tm]";
  playMsg "minutes";
  playSilence 500;

  playMsg "minimum";
  playMsg "humidity";
  playNumber "$min_hum";
  playMsg "percent";
  playMsg "at";
  playNumber "[format "%.5s" $min_hum_tm]";
  playMsg "minutes";
  playSilence 500;

  playMsg "maximum";
  playMsg "dewpoint";
  playNumber "[format "%.0f" $max_dew]";
  playMsg "degrees";
  playMsg "at";
  playNumber "[format "%.5s" $max_dew_tm]";
  playMsg "minutes";
  playSilence 500;

  playMsg "minimum";
  playMsg "dewpoint";
  playNumber "[format "%.0f" $min_dew]";
  playMsg "degrees";
  playMsg "at";
  playNumber "[format "%.5s" $min_dew_tm]";
  playMsg "minutes";
  playSilence 500;

  playMsg "maximum";
  playMsg "barometer";
  playNumber "[format "%.2f" $max_bar]";
  playMsg "inches";
  playMsg "at";
  playNumber "[format "%.5s" $max_bar_tm]";
  playMsg "minutes";
  playSilence 500;

  playMsg "minimum";
  playMsg "barometer";
  playNumber "[format "%.2f" $min_bar]";
  playMsg "inches";
  playMsg "at";
  playNumber "[format "%.5s" $min_bar_tm]";
  playMsg "minutes";
  playSilence 500;

  if { $max_heat_index != "--" } {
    playMsg "maximum";
    playMsg "heat_index";
    playNumber "[format "%.0f" $heat_index]";
    playMsg "degrees";
    playMsg "at";
    playNumber "[format "%.5s" $max_heat_index_tm]";
    playMsg "minutes";
    playSilence 500;
  }

  if { $min_wind_chill != "--" } {
    playMsg "minimum";
    playMsg "wind_chill";
    playNumber "[format "%.0f" $min_wind_chill]";
    playMsg "degrees";
    playMsg "at";
    playNumber "[format "%.5s" $min_wind_chill_tm]";
    playMsg "minutes";
    playSilence 500;
  }
}


#
# Davis Vantage Pro weather forecast
#
proc davisForecast {} {
  variable module_name;
  variable currentobs_file;

  set file [open $currentobs_file];
  set content [read $file];
  close $file;

  set wxfields [split $content ","];

  lassign $wxfields \
    hh mm ss bar temp avg_windspd windspd wind_dir hum dewpoint \
    wind_chill heat_index rain_rate daily_rain mtd_rain ytd_rain \
    sunrise sunset indoor_temp indoor_hum indoor_dewpoint bar_trend \
    fcst_icon fcst_rule storm_start storm_rain rain24 rain1 rain_con;

  playMsg "davis_vantage_pro";
  playMsg "forecast";
  playMsg "for_location";
  playSilence 500;
  playMsg "forecasts\/$fcst_rule";
  playSilence 1000;

  playMsg "icon";
  playMsg "forecast";
  switch $fcst_icon {
    2 { playMsg "mostly_cloudy" }
    3 { playMsg "rain_likely" }
    6 { playMsg "partly_cloudy" }
    7 { playMsg "rain_possible" }
    8 { playMsg "sunny" }
    18 { playMsg "snow_likely" }
    19 { playMsg "snow_likely" }
    21 { playMsg "snow_possible" }
    23 { playMsg "snow_possible" }
    default { playMsg "not_available" }
  }
  playSilence 500;
}


#
# Executed when this module is being deactivated.
#
proc deactivating_module {} {
  variable module_name;
  Module::deactivating_module $module_name;
}


#
# Executed when the inactivity timeout for this module has expired.
#
proc timeout {} {
  variable module_name;
  Module::timeout $module_name;
}


#
# Executed when playing of the help message for this module has been requested.
#
proc play_help {} {
  variable module_name;
  Module::play_help $module_name;
}


#
# Executed when a DTMF digit (0-9, A-F, *, #) is received
#
proc dtmf_digit_received {char} {
  #printInfo "DTMF digit received: $char";
}


#
# Executed when the squelch open or close. If it's open is_open is set to 1,
# otherwise it's set to 0.
#
proc squelch_open {is_open} {
  if {$is_open} {set str "OPEN"} else { set str "CLOSED"};
  printInfo "The squelch is $str";
}


#
# Executed when all announcement messages has been played.
# Note that this function also may be called even if it wasn't this module
# that initiated the message playing.
#
proc all_msgs_written {} {
#  printInfo "all_msgs_written called...";
}


#
# Executed when the state of this module should be reported on the radio
# channel. Typically this is done when a manual identification has been
# triggered by the user by sending a "*".
# This function will only be called if this module is active.
#
proc status_report {} {
#  printInfo "status_report called...";
}


#
# Quick help from within module
#
proc cmdPlayQuickHelp {} {
  playMsg "help";
  playSilence 500;
  playMsg "menu";
}


# end of namespace
}


#
# This file has not been truncated
#
Reply | Threaded
Open this post in threaded view
|

Re: New TclWeather module

Tobias Blomberg
On Sunday 13 November 2005 18:27, Tim Miller WB0RXX wrote:
> Hi guys and gals,
>
> I have developed a module for our favorite program which provides
> on-demand weather information.  It is designed for use with the Davis
> Vantage Pro running vanprod, but it should not be too hard to change it
> to work with any weather station that has a CSV data output.

Nice. I have to get myself a weather station ;-)  And to start thinking of how
to handle third party contributions...


> Please note that this module is designed to work under the latest CVS
> release of SvxLink (v0.7.0rc2).  It should work with older versions of
> SvxLink with little or no tweaking.
>
> To make it work, just add the following to your /etc/svxlink.conf
>
> MODULES=ModuleHelp,ModuleParrot,ModuleTclVoiceMail,ModuleTclWeather
>
> [ModuleTclWeather]
> NAME=TclWeather
> PLUGIN_NAME=Tcl
> ID=8                    <----  Think "Weather on the eights" :-)
> TIMEOUT=300

Note that variables given here also show up in the TCL script prefixed with
"CFG_". So, TIMEOUT is accessible as "$CFG_TIMEOUT". That means that you can
put all simple configuration options in svxlink.conf instead of in the TCL
file. For example:

set currentobs_file /var/spool/weather/currentobs;
set extremes_file /var/spool/weather/extremes;

could be put here as CURRENTOBS_FILE and EXTREMES_FILE and accessed from
within the TCL script as CFG_CURRENTOBS_FILE and CFG_EXTREMES_FILE.


>
> To get the time and negative values to function properly, I needed to
> add two symlinks from within the Default directory:
>
> lrwxrwxrwx  1 tim users   -.raw -> ../TclWeather/minus.raw
> lrwxrwxrwx  1 tim users   :.raw -> ../TclWeather/hours.raw
>
> The first symlink allows the playNumber function to say "minus" when it
> sees a "-".  The second symlink is a bit less obvious.  When playNumber
> is saying "12:34" the  ":" is interpreted as the word "hours".  It
> certainly is not very pretty, but it seems to work. ;-)

If at all possible, please try to make a module self contained. If a core
function like playNumber does not do what you want, don't put new files into
Default and don't modify the core function. Make your own version in the
module instead. Then if it's a good tweak, I might update the core functions
with the new functionality. Otherwise we might get clashes when different
modules want to modify the core functions in different ways.


>
> The audio files are a bit too large to post on this forum (+6 MB), so
> here is an external link to them:
>
>    http://www.MontevideoComputers.com/ham/files/TclWeather_sounds.tar.gz
>
> This tarball also contains the scripts used to generate the sound files,
> as well as the Davis forecast rules.  This should be enough information
> to re-record these files in a language other than English, or if you do
> not want to hear my voice on your system. <grin>

For you out there that is not using the SvxLink source code, this script use
the play_sound.sh script that can be found in the source tree under
svxlink/scripts.

All other sounds in SvxLink can be filtered using the filter_sounds.sh if you
want to record your own sounds.


>
> For anyone that is interested, I am also working on a number of other
> additions to SvxLink including Long Tone Zero (LiTZ)/operator paging,
> Skywarn activation notices, NOAA weather radio rebroadcasts, and
> on-demand broadcasts of local info, the ARRL letter, and the Newsline
> bulletins.  I would be most interested to know if anyone else is doing
> something similar, as I'd be happy to share what I have so far.

Keep going :-)


> My thanks again to Tobias for making such a very FB program that is so
> easy to work with!

Thank you for your contribution!

73 de SM0SVX / Tobias

>
> 73 de Tim


-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.  Get Certified Today
Register for a JBoss Training Course.  Free Certification Exam
for All Training Attendees Through End of 2005. For more info visit:
http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click
_______________________________________________
Svxlink-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/svxlink-devel
Reply | Threaded
Open this post in threaded view
|

Re: New TclWeather module

Tim Miller WB0RXX
Tobias Blomberg wrote:
> On Sunday 13 November 2005 18:27, Tim Miller WB0RXX wrote:

<snip announcement>

> Nice. I have to get myself a weather station ;-)

Thank you.  It is a lot of fun to watch the weather, as it changes more
than it stays the same this time of year.  Last week we went from sunny
skys and 71 degrees, to snow, 50 MPH wind gusts and 15 degree
temperatures in less than three days.  Where is "global warming" when
you *really* need it? <grin>

> And to start thinking of how
> to handle third party contributions...

_My_ module is not really worthy of adding to the main tree, as I doubt
more than a handful of SvxLink users that even *own* a weather station,
let alone a Davis Vantage Pro running vanprod.

>>[ModuleTclWeather]
>>NAME=TclWeather
>>PLUGIN_NAME=Tcl
>>ID=8                    <----  Think "Weather on the eights" :-)
>>TIMEOUT=300
>
>
> Note that variables given here also show up in the TCL script prefixed with
> "CFG_". So, TIMEOUT is accessible as "$CFG_TIMEOUT". That means that you can
> put all simple configuration options in svxlink.conf instead of in the TCL
> file. For example:
>
> set currentobs_file /var/spool/weather/currentobs;
> set extremes_file /var/spool/weather/extremes;
>
> could be put here as CURRENTOBS_FILE and EXTREMES_FILE and accessed from
> within the TCL script as CFG_CURRENTOBS_FILE and CFG_EXTREMES_FILE.
Unfortunately, I could not get this option to function.  Perhaps I am
doing something wrong, but it appears that these variables are not being
passed along to the Tcl module.  For example, if I add

   puts "$CFG_TIMEOUT";

to the TclWeather script, I get this error message:

/usr/share/svxlink/sounds/events.tcl: can't read "CFG_TIMEOUT": no such
variable

I also tried this line in the TclVoiceMail module with the same results.

I admit that this would be a great way to handle this option, if I could
only get it to work.  I run two SvxLink machines here, one
test/development and one on-line, and they both have different paths to
the weather data.  Editing the TclWeather file is such a hassle at
times. ;-)

<snip symlink hack>

> If at all possible, please try to make a module self contained. If a core
> function like playNumber does not do what you want, don't put new files into
> Default and don't modify the core function. Make your own version in the
> module instead. Then if it's a good tweak, I might update the core functions
> with the new functionality. Otherwise we might get clashes when different
> modules want to modify the core functions in different ways.

A very good idea!  This makes perfect sense, but as a "novice
programmer", I did not think ahead about the consequences of doing this
sort of thing. :-(  Thank you for taking the time to help me learn a bit
more about the fine art of programming.

Attached is the latest version of TclWeather, which removes the need for
the symlink ugly hack, and adds a few minor bits.  It ain't very pretty
TCL code, but it now works without interfering with any other module.

>>The audio files are a bit too large to post on this forum (+6 MB), so
>>here is an external link to them:
>>
>>   http://www.MontevideoComputers.com/ham/files/TclWeather_sounds.tar.gz

A slightly updated version of the sounds and support files is now
available at this URL:

http://www.MontevideoComputers.com/ham/files/TclWeather_sounds-0.1.1.tar.gz

> For you out there that is not using the SvxLink source code, this script use
> the play_sound.sh script that can be found in the source tree under
> svxlink/scripts.

Oops...  I meant to include this script with the tarball upload.  It is
now included in the above file.  I also included a copy of the raw
weather data files, in case anyone would like to test it.

> All other sounds in SvxLink can be filtered using the filter_sounds.sh if you
> want to record your own sounds.

I was also going to complement you on these script files as well.  They
sure makes it a lot easier to add/change/update the voice files!

73 de Tim

--
Tim Miller WB0RXX [EN24dw]
SvxLink v0.7.0rc2 (Nov  2 2005)
Slackware 10.1/P200 MHz/64 MB

###############################################################################
#
# TclWeather module event handlers -- Version 0.1.1
#
#   13Nov05 - v0.1.0 - Inital public release
#   19Nov05 - v0.1.1 - Added new playNumber proc, cleaned/commented the code
#
###############################################################################
#
# This is the namespace in which all functions and variables below will exist.
# The name must match the configuration variable "NAME" in the
# [Module TclWeather] section in the configuration file. The name may be changed
# but it must be changed in both places.
#

namespace eval TclWeather {

#
# Set weather data locations
#
#set currentobs_file $CFG_CURRENTOBS_FILE
#set extremes_file $CFG_EXTREMES_FILE
set currentobs_file /var/spool/weather/currentobs;
set extremes_file /var/spool/weather/extremes;


#
# Extract the module name from the current namespace
#
set module_name [namespace tail [namespace current]];


#
# Emulates the 'lassign' command in TclX
#
proc lassign {list args} {
  foreach elem $list varName $args {
    upvar 1 $varName var
    set var $elem
  }
}


#
# Spell the specified number -- Added point, minus, and hours
#
proc playNumber {number} {
  for {set i 0} {$i < [string length $number]} {set i [expr $i + 1]} {
    set ch [string index $number $i];
    if {$ch == "."} {
      playMsg "TclWeather" "point";
    } elseif {$ch == "-"} {
      playMsg "TclWeather" "minus";
    } elseif {$ch == ":"} {
      playMsg "TclWeather" "hours";
    } else {  
      playMsg "Default" "$ch";
    }
  }
}


#
# A convenience function for printing out information prefixed by the
# module name
#
proc printInfo {msg} {
  variable module_name;
  puts "$module_name: $msg";
}
 
 
#
# Executed when this module is being activated
#
proc activating_module {} {
  variable module_name;
  Module::activating_module $module_name;
  playSilence 500;
  playMsg "TclWeather" "menu";
  playSilence 500;
}


#
# Main menu selection
#
proc dtmf_cmd_received {cmd} {
    if {$cmd == ""} {
      deactivateModule;
    } elseif {$cmd == "0"} {
      cmdPlayQuickHelp;
    } elseif {$cmd == "1"} {
      standardWeather;
    } elseif {$cmd == "2"} {
      extendedWeather;
    } elseif {$cmd == "3"} {
      dailyExtremes;
    } elseif {$cmd == "4"} {
      davisForecast;
    } else {
      playNumber $cmd;
      playMsg "Default" "unknown_command";
    }
}


#
# Standard weather information (Menu option 1)
#
proc standardWeather {} {
  variable currentobs_file;

  set file [open $currentobs_file];
  set content [read $file];
  close $file;

  set wxfields [split $content ","];

  lassign $wxfields \
    hh mm ss bar temp avg_windspd windspd wind_dir hum dewpoint \
    wind_chill heat_index rain_rate daily_rain mtd_rain ytd_rain \
    sunrise sunset indoor_temp indoor_hum indoor_dewpoint bar_trend \
    fcst_icon fcst_rule storm_start storm_rain rain24 rain1 rain_con;

  playMsg "TclWeather" "current";
  playMsg "TclWeather" "weather_conditions";
  playMsg "TclWeather" "for_location";
  playSilence 500;

  playMsg "TclWeather" "winds";
  if { $windspd > 0 } {
    playMsg "TclWeather" "$wind_dir";
    playMsg "TclWeather" "at";
    playNumber "$windspd";
    playMsg "TclWeather" "miles_per_hour";
  } else {
    playMsg "TclWeather" "are_calm";
  }
  playSilence 500;

  playMsg "TclWeather" "temperature";
  playNumber "[format "%.0f" $temp]";
  playMsg "TclWeather" "degrees";
  playSilence 500;

  playMsg "TclWeather" "humidity";
  playNumber "$hum";
  playMsg "TclWeather" "percent";
  playSilence 500;

  playMsg "TclWeather" "dewpoint";
  playNumber "[format "%.0f" $dewpoint]";
  playMsg "TclWeather" "degrees";
  playSilence 500;

  playMsg "TclWeather" "barometer";
  playNumber "[format "%.2f" $bar]";
  playMsg "TclWeather" "inches";
  playMsg "TclWeather" "and";
  playMsg "TclWeather" "$bar_trend";
  playSilence 500;

  if { $wind_chill != "--" } {
    playMsg "TclWeather" "wind_chill";
    playNumber "[format "%.0f" $wind_chill]";
    playMsg "TclWeather" "degrees";
    playSilence 500;
  }

  if { $heat_index != "--" } {
    playMsg "TclWeather" "heat_index";
    playNumber "[format "%.0f" $heat_index]";
    playMsg "TclWeather" "degrees";
    playSilence 500;
  }

  if { $daily_rain > 0 } {
    playMsg "TclWeather" "daily_rainfall";
    playNumber "$daily_rain";
    playMsg "TclWeather" "inches";
    playSilence 500;
  }
  playSilence 500;
}


#
# Extended weather information (Menu option 2)
#
proc extendedWeather {} {
  variable currentobs_file;

  set file [open $currentobs_file];
  set content [read $file];
  close $file;

  set wxfields [split $content ","];

  lassign $wxfields \
    hh mm ss bar temp avg_windspd windspd wind_dir hum dewpoint \
    wind_chill heat_index rain_rate daily_rain mtd_rain ytd_rain \
    sunrise sunset indoor_temp indoor_hum indoor_dewpoint bar_trend \
    fcst_icon fcst_rule storm_start storm_rain rain24 rain1 rain_con;

  playMsg "TclWeather" "extended";
  playMsg "TclWeather" "weather_conditions";
  playMsg "TclWeather" "for_location";
  playSilence 500;

  playMsg "TclWeather" "average_wind_speed";
  playNumber "$avg_windspd";
  playMsg "TclWeather" "miles_per_hour";
  playSilence 500;

  playMsg "TclWeather" "month_to_date";
  playMsg "TclWeather" "rainfall";
  playNumber "$mtd_rain";
  playMsg "TclWeather" "inches";
  playSilence 500;

  playMsg "TclWeather" "year_to_date";
  playMsg "TclWeather" "rainfall";
  playNumber "$ytd_rain";
  playMsg "TclWeather" "inches";
  playSilence 500;

  if { $rain1 > 0 } {
    playMsg "TclWeather" "rainfall";
    playMsg "TclWeather" "last";
    playMsg "TclWeather" "sixty_minutes";
    playNumber "$rain1";
    playMsg "TclWeather" "inches";
    playSilence 500;
  }

  if { $rain24 > 0 } {
    playMsg "TclWeather" "rainfall";
    playMsg "TclWeather" "last";
    playMsg "TclWeather" "twenty_four_hours";
    playNumber "$rain24";
    playMsg "TclWeather" "inches";
    playSilence 500;
  }

  if { $storm_rain > 0 } {
    playMsg "TclWeather" "storm_total";
    playMsg "TclWeather" "rainfall";
    playNumber "$storm_rain";
    playMsg "TclWeather" "inches";
    playSilence 500;
  }

  playMsg "TclWeather" "sunrise";
  playNumber "$sunrise";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "sunset";
  playNumber "$sunset";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "indoor";
  playMsg "TclWeather" "temperature";
  playNumber "[format "%.0f" $indoor_temp]";
  playMsg "TclWeather" "degrees";
  playSilence 500;

  playMsg "TclWeather" "indoor";
  playMsg "TclWeather" "humidity";
  playNumber "[format "%.0f" $indoor_hum]";
  playMsg "TclWeather" "percent";
  playSilence 500;

  playMsg "TclWeather" "indoor";
  playMsg "TclWeather" "dewpoint";
  playNumber "[format "%.0f" $indoor_dewpoint]";
  playMsg "TclWeather" "degrees";
  playSilence 500;
}


#
# Extremes data since midnight (Menu option 3)
#
proc dailyExtremes {} {
  variable extremes_file;

  set file [open $extremes_file];
  set content [read $file];
  close $file;

  set wxfields [split $content ","];

  lassign $wxfields \
    min_bar min_bar_tm max_bar max_bar_tm min_temp min_temp_tm \
    max_temp max_temp_tm max_wind max_wind_dir max_wind_tm \
    min_hum min_hum_tm max_hum max_hum_tm min_dew min_dew_tm \
    max_dew max_dew_tm min_wind_chill min_wind_chill_tm \
    max_heat_index max_heat_index_tm max_rain_rate max_rain_rate_tm \
    daily_rain ytd_rain min_indoor_temp min_indoor_temp_tm \
    max_indoor_temp max_indoor_temp_tm min_indoor_hum min_indoor_hum_tm \
    max_indoor_hum max_indoor_hum_tm min_indoor_dew min_indoor_dew_tm \
    max_indoor_dew max_indoor_dew_tm;

  playMsg "TclWeather" "extreme";
  playMsg "TclWeather" "weather_conditions";
  playMsg "TclWeather" "for_location";
  playSilence 500;

  playMsg "TclWeather" "maximum";
  playMsg "TclWeather" "winds";
  if { $max_wind > 0 } {
    playMsg "TclWeather" "$max_wind_dir";
    playMsg "TclWeather" "at";
    playNumber "$max_wind";
    playMsg "TclWeather" "miles_per_hour";
    playMsg "TclWeather" "at";
    playNumber "[format "%.5s" $max_wind_tm]";
    playMsg "TclWeather" "minutes";
  } else {
    playMsg "TclWeather" "are_calm";
  }
  playSilence 500;

  playMsg "TclWeather" "maximum";
  playMsg "TclWeather" "temperature";
  playNumber "[format "%.0f" $max_temp]";
  playMsg "TclWeather" "degrees";
  playMsg "TclWeather" "at";
  playNumber "[format "%.5s" $max_temp_tm]";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "minimum";
  playMsg "TclWeather" "temperature";
  playNumber "[format "%.0f" $min_temp]";
  playMsg "TclWeather" "degrees";
  playMsg "TclWeather" "at";
  playNumber "[format "%.5s" $min_temp_tm]";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "maximum";
  playMsg "TclWeather" "humidity";
  playNumber "$max_hum";
  playMsg "TclWeather" "percent";
  playMsg "TclWeather" "at";
  playNumber "[format "%.5s" $max_hum_tm]";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "minimum";
  playMsg "TclWeather" "humidity";
  playNumber "$min_hum";
  playMsg "TclWeather" "percent";
  playMsg "TclWeather" "at";
  playNumber "[format "%.5s" $min_hum_tm]";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "maximum";
  playMsg "TclWeather" "dewpoint";
  playNumber "[format "%.0f" $max_dew]";
  playMsg "TclWeather" "degrees";
  playMsg "TclWeather" "at";
  playNumber "[format "%.5s" $max_dew_tm]";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "minimum";
  playMsg "TclWeather" "dewpoint";
  playNumber "[format "%.0f" $min_dew]";
  playMsg "TclWeather" "degrees";
  playMsg "TclWeather" "at";
  playNumber "[format "%.5s" $min_dew_tm]";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "maximum";
  playMsg "TclWeather" "barometer";
  playNumber "[format "%.2f" $max_bar]";
  playMsg "TclWeather" "inches";
  playMsg "TclWeather" "at";
  playNumber "[format "%.5s" $max_bar_tm]";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  playMsg "TclWeather" "minimum";
  playMsg "TclWeather" "barometer";
  playNumber "[format "%.2f" $min_bar]";
  playMsg "TclWeather" "inches";
  playMsg "TclWeather" "at";
  playNumber "[format "%.5s" $min_bar_tm]";
  playMsg "TclWeather" "minutes";
  playSilence 500;

  if { $max_heat_index != "--" } {
    playMsg "TclWeather" "maximum";
    playMsg "TclWeather" "heat_index";
    playNumber "[format "%.0f" $heat_index]";
    playMsg "TclWeather" "degrees";
    playMsg "TclWeather" "at";
    playNumber "[format "%.5s" $max_heat_index_tm]";
    playMsg "TclWeather" "minutes";
    playSilence 500;
  }

  if { $min_wind_chill != "--" } {
    playMsg "TclWeather" "minimum";
    playMsg "TclWeather" "wind_chill";
    playNumber "[format "%.0f" $min_wind_chill]";
    playMsg "TclWeather" "degrees";
    playMsg "TclWeather" "at";
    playNumber "[format "%.5s" $min_wind_chill_tm]";
    playMsg "TclWeather" "minutes";
    playSilence 500;
  }
}


#
# Davis Vantage Pro weather forecast (Menu option 4)
#
proc davisForecast {} {
  variable module_name;
  variable currentobs_file;

  set file [open $currentobs_file];
  set content [read $file];
  close $file;

  set wxfields [split $content ","];

  lassign $wxfields \
    hh mm ss bar temp avg_windspd windspd wind_dir hum dewpoint \
    wind_chill heat_index rain_rate daily_rain mtd_rain ytd_rain \
    sunrise sunset indoor_temp indoor_hum indoor_dewpoint bar_trend \
    fcst_icon fcst_rule storm_start storm_rain rain24 rain1 rain_con;

  playMsg "TclWeather" "davis_vantage_pro";
  playMsg "TclWeather" "forecast";
  playMsg "TclWeather" "for_location";
  playSilence 500;
  playMsg "TclWeather" "forecasts\/$fcst_rule";
  playSilence 1000;

  playMsg "TclWeather" "icon";
  playMsg "TclWeather" "forecast";
  switch $fcst_icon {
    2 { playMsg "TclWeather" "mostly_cloudy" }
    3 { playMsg "TclWeather" "rain_likely" }
    6 { playMsg "TclWeather" "partly_cloudy" }
    7 { playMsg "TclWeather" "rain_possible" }
    8 { playMsg "TclWeather" "sunny" }
    18 { playMsg "TclWeather" "snow_likely" }
    19 { playMsg "TclWeather" "snow_likely" }
    21 { playMsg "TclWeather" "snow_possible" }
    23 { playMsg "TclWeather" "snow_possible" }
    default { playMsg "TclWeather" "not_available" }
  }
  playSilence 500;
}


#
# Executed when this module is being deactivated.
#
proc deactivating_module {} {
  variable module_name;
  Module::deactivating_module $module_name;
}


#
# Executed when the inactivity timeout for this module has expired.
#
proc timeout {} {
  variable module_name;
  Module::timeout $module_name;
}


#
# Executed when playing of the help message for this module has been requested.
#
proc play_help {} {
  variable module_name;
  Module::play_help $module_name;
}


#
# Executed when a DTMF digit (0-9, A-F, *, #) is received
#
proc dtmf_digit_received {char} {
#  printInfo "DTMF digit received: $char";
}


#
# Executed when the squelch open or close. If it's open is_open is set to 1,
# otherwise it's set to 0.
#
proc squelch_open {is_open} {
  if {$is_open} {set str "OPEN"} else { set str "CLOSED"};
  printInfo "The squelch is $str";
}


#
# Executed when all announcement messages has been played.
# Note that this function also may be called even if it wasn't this module
# that initiated the message playing.
#
proc all_msgs_written {} {
#  printInfo "all_msgs_written called...";
}


#
# Executed when the state of this module should be reported on the radio
# channel. Typically this is done when a manual identification has been
# triggered by the user by sending a "*".
# This function will only be called if this module is active.
#
proc status_report {} {
#  printInfo "status_report called...";
}


#
# Quick help from within module
#
proc cmdPlayQuickHelp {} {
  playMsg "TclWeather" "help";
  playSilence 500;
  playMsg "TclWeather" "menu";
}


# end of namespace
}


#
# This file has not been truncated
#
Reply | Threaded
Open this post in threaded view
|

Re: New TclWeather module

Tobias Blomberg-3

On Saturday 19 November 2005 18:47, Tim Miller WB0RXX wrote:

> Tobias Blomberg wrote:

> > Note that variables given here also show up in the TCL script prefixed

> > with "CFG_". So, TIMEOUT is accessible as "$CFG_TIMEOUT". That means that

> > you can put all simple configuration options in svxlink.conf instead of

> > in the TCL file. For example:

> >

> > set currentobs_file /var/spool/weather/currentobs;

> > set extremes_file /var/spool/weather/extremes;

> >

> > could be put here as CURRENTOBS_FILE and EXTREMES_FILE and accessed from

> > within the TCL script as CFG_CURRENTOBS_FILE and CFG_EXTREMES_FILE.

>

> Unfortunately, I could not get this option to function. Perhaps I am

> doing something wrong, but it appears that these variables are not being

> passed along to the Tcl module. For example, if I add

>

> puts "$CFG_TIMEOUT";

>

> to the TclWeather script, I get this error message:

>

> /usr/share/svxlink/sounds/events.tcl: can't read "CFG_TIMEOUT": no such

> variable

Oops. I guess I didn't test this feature after implementing it. The variables were never setup due to an error. I have fixed this in CVS. I hope you didn't waste too much time trying to get this to work.

> > For you out there that is not using the SvxLink source code, this script

> > use the play_sound.sh script that can be found in the source tree under

> > svxlink/scripts.

>

> Oops... I meant to include this script with the tarball upload. It is

> now included in the above file. I also included a copy of the raw

> weather data files, in case anyone would like to test it.

Ok, interesting. Then I can try your script with the weather data files when I find the time to do it.

> > All other sounds in SvxLink can be filtered using the filter_sounds.sh if

> > you want to record your own sounds.

>

> I was also going to complement you on these script files as well. They

> sure makes it a lot easier to add/change/update the voice files!

Well, it's a hack, but it works :-)

73 de SM0SVX / Tobias

Reply | Threaded
Open this post in threaded view
|

Re: New TclWeather module

Tim Miller WB0RXX
Tobias Blomberg wrote:
> On Saturday 19 November 2005 18:47, Tim Miller WB0RXX wrote:
>
>  > Tobias Blomberg wrote:

<snip passing variables>

> Oops. I guess I didn't test this feature after implementing it. The
> variables were never setup due to an error. I have fixed this in CVS.

Wow!  Less than 24 hours after I reported the problem, you fixed it.
Thank you ever so much.  It now works just fine.

> I
> hope you didn't waste too much time trying to get this to work.

No, not at all.  I did dig into the source a bit to see if I could
figure out what was going on, but it is just a bit too much for me at
this time. ;-)

>  > I was also going to complement you on these script files as well. They
>
>  > sure makes it a lot easier to add/change/update the voice files!
>
> Well, it's a hack, but it works :-)

Hey, that is all that matters!

BTW, I like the new e-mail feature in the TclVoiceMail.  N0GMX and
myself were pondering this very same addition late last week.  Thanks to
you, I can cross one more "to-do" item off of my list... ;-)  Now, if I
can only get sendmail to work with my ISP... :-(

Thanks again for your prompt assistance Tobias.  Keep up the good work
and have a great day.

73 de Tim

--
Tim Miller WB0RXX [EN24dw]
SvxLink v0.7.0rc3 (Nov 20 2005)
Slackware 10.1/P200 MHz/64 MB


-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.  Get Certified Today
Register for a JBoss Training Course.  Free Certification Exam
for All Training Attendees Through End of 2005. For more info visit:
http://ads.osdn.com/?ad_id=7628&alloc_id=16845&op=click
_______________________________________________
Svxlink-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/svxlink-devel
Reply | Threaded
Open this post in threaded view
|

Re: New TclWeather module

Tobias Blomberg-3

On Sunday 20 November 2005 22:17, Tim Miller WB0RXX wrote:

> BTW, I like the new e-mail feature in the TclVoiceMail. N0GMX and

> myself were pondering this very same addition late last week. Thanks to

> you, I can cross one more "to-do" item off of my list... ;-) Now, if I

> can only get sendmail to work with my ISP... :-(

You usually just need to setup the "smart host" option in your mail server daemon configuration file to send all mail through the ISP SMTP server.

In Fedora, sendmail is the default mailer daemon. Look for the DS option in the sendmail configuration file (/etc/mail/sendmail.cf in Fedora). If you run Postfix it's called "relayhost" (/etc/postfix/main.cf).

73 de SM0SVX / Tobias

>

> Thanks again for your prompt assistance Tobias. Keep up the good work

> and have a great day.

>

> 73 de Tim