WeeWx 5.2 & Belchertown Skin Woes

68 views
Skip to first unread message

Sideshow Raheem

unread,
Oct 27, 2025, 2:09:50 PM (5 days ago) Oct 27
to weewx-user
What a long strange trip this has been. I had my previous station up and running for a good 2 years or so without issue, but this has really challenged me.

Heres where Im at right now after fighting permission issues with my old ssh keys, and folders:
# WEEWX CONFIGURATION FILE
#
# Copyright (c) 2009-2024 Tom Keffer <tke...@gmail.com>
# See the file LICENSE.txt for your rights.

##############################################################################

# This section is for general configuration information.

# Set to 1 for extra debug info, otherwise comment it out or set to zero.
debug = 1

# Whether to log successful operations. May get overridden below.
log_success = True

# Whether to log unsuccessful operations. May get overridden below.
log_failure = True

# This configuration file was created by ...
version = 5.2.0

# Whether to try indefinitely to load the driver
loop_on_init = 1

##############################################################################

#   This section is for information about the station.

[Station]
   
    # Description of the station location, such as your town.
    location = "Lakeside Duluth, MN"
   
    # Latitude in decimal degrees. Negative for southern hemisphere.
    latitude = 46.8267
    # Longitude in decimal degrees. Negative for western hemisphere.
    longitude = -92.0365
   
    # Altitude of the station, with the unit it is in. This is used only
    # if the hardware cannot supply a value.
    altitude = 0715, foot    # Choose 'foot' or 'meter' for unit
   
    # Set to type of station hardware. There must be a corresponding stanza
    # in this file, which includes a value for the 'driver' option.
    station_type = GW1000
   
    # If you have a website, you may specify an URL
    station_url = https://www.duluthweather.com
   
    # The start of the rain year (1=January; 10=October, etc.). This is
    # downloaded from the station if the hardware supports it.
    rain_year_start = 1
   
    # Start of week (0=Monday, 6=Sunday)
    week_start = 6

##############################################################################

[GW1000]
    # This section is for the Ecowitt Gateway driver.
   
    # How often to poll the API, default is every 20 seconds:
    poll_interval = 60
   
    # The driver to use:
    driver = user.gw1000
    ip_address = 192.168.68.59
    port = 45000

##############################################################################

[Simulator]
# This section is for the weewx weather station simulator.

# The time (in seconds) between LOOP packets.
#loop_interval = 2.5

# The simulator mode can be either 'simulator' or 'generator'.
# Real-time simulator. Sleep between each LOOP packet.
#mode = simulator
# Generator.  Emit LOOP packets as fast as possible (useful for testing).
#mode = generator

# The start time. Format is YYYY-mm-ddTHH:MM. If not specified, the
# default is to use the present time.
#start = 2011-01-01T00:00

# The driver to use.
#driver = weewx.drivers.simulator

##############################################################################

#   This section is for uploading data to Internet sites

[StdRESTful]
   
    # Uncomment and change to override logging for uploading services.
    log_success = True
    log_failure = True
   
    [[StationRegistry]]
        # To register this weather station at weewx.com, set this to true, and
        # set option 'station_url', located in the [Station] section above.
        register_this_station = True
   
    [[AWEKAS]]
        # This section is for configuring posts to AWEKAS.
       
        # If you wish to post to AWEKAS, set the option 'enable' to true, then
        # specify a username and password.
        # Use quotes around the password to guard against parsing errors.
        enable = false
        username = replace_me
        password = replace_me
   
    [[CWOP]]
        # This section is for configuring posts to CWOP.
       
        # If you wish to post to CWOP, set the option 'enable' to true,
        # then specify the station ID (e.g., CW1234).
        enable = false
        station = replace_me
        # If this is an APRS (radio amateur) station, specify the
        # passcode (e.g., 12345). Otherwise, ignore.
        passcode = replace_me
   
    [[PWSweather]]
        # This section is for configuring posts to PWSweather.com.
       
        # If you wish to post to PWSweather.com, set the option 'enable' to
        # true, then specify a station and password.
        # Use quotes around the password to guard against parsing errors.
        enable = true
        station = replace_me
        password = replace_me
   
    [[WOW]]
        # This section is for configuring posts to WOW (wow.metoffice.gov.uk).
       
        # If you wish to post to WOW, set the option 'enable' to true, then
        # specify a station and password.
        # Use quotes around the password to guard against parsing errors.
        enable = false
        station = DuluthWeather
        password = toots
   
    [[Windy]]
        enable = True
        api_key = farts
   
    [[WOW-BE]]
        # This section is for configuring WeeWX to upload to WOW-BE (wow.meteo.be)
       
        # If you wish to post to WOW-BE, set the option 'enable' to true, then
        # specify a station and password.
        # Use quotes around the password to guard against parsing errors.
        enable = false
        station = replace_me
        password = replace_me
   
    [[Wunderground]]
        # This section is for configuring posts to the Weather Underground.
       
        # If you wish to post to the Weather Underground, set the option
        # 'enable' to true,  then specify a station (e.g., 'KORHOODR3'). Use
        # the station key (find it at
        # https://www.wunderground.com/member/devices) for the password.
        enable = false
        station = replace_me
        password = replace_me
       
        # Set the following to True to have weewx use the WU "Rapidfire"
        # protocol. Not all hardware can support it. See the User's Guide.
        rapidfire = False

##############################################################################

#   This section specifies what reports, using which skins, to generate.

[StdReport]
   
    # Where the skins reside, relative to WEEWX_ROOT
    SKIN_ROOT = skins
   
    # Where the generated reports should go, relative to WEEWX_ROOT
    HTML_ROOT = /var/www/html
   
    # Uncomment and change to override logging for reports.
    # log_success = True
    # log_failure = True
   
    # The database binding indicates which data should be used in reports.
    data_binding = wx_binding
   
    # Each of the following subsections defines a report that will be run.
    # See the customizing guide to change the units, plot types and line
    # colors, modify the fonts, display additional sensor data, and other
    # customizations. Many of those changes can be made here by overriding
    # parameters, or by modifying templates within the skin itself.
   
    [[SeasonsReport]]
        # The SeasonsReport uses the 'Seasons' skin, which contains the
        # images, templates and plots for the report.
        skin = Seasons
        enable = false
   
    [[SmartphoneReport]]
        # The SmartphoneReport uses the 'Smartphone' skin, and the images and
        # files are placed in a dedicated subdirectory.
        skin = Smartphone
        enable = false
        #HTML_ROOT = /var/www/html/weewx/smartphone
   
    [[MobileReport]]
        # The MobileReport uses the 'Mobile' skin, and the images and files
        # are placed in a dedicated subdirectory.
        skin = Mobile
        enable = false
        HTML_ROOT = /var/www/html/weewx/mobile
   
    [[StandardReport]]
        # This is the old "Standard" skin. By default, it is not enabled.
         skin = Standard
         enable = false
   
    [[Belchertown]]
        skin = Belchertown
        HTML_ROOT = /var/www/html
        enable = true
       
        [[[Extras]]]
           
            # For help refer to the docs at https://github.com/poblabs/weewx-belchertown
            # and consult skin.conf for the configurable elements and their hierarchy
           
            #--- General Options ---
            # belchertown_debug = 0
            # belchertown_locale = "auto"
            theme = light
            theme_toggle_enabled = 0
            logo_image = https://s3.us-east-1.amazonaws.com/web.niffnay.org/duluthweather.png
            # logo_image_dark = ""
            site_title = Lakeside Duluth Weather
            station_observations = barometer, visibility, cloudbase, dewpoint, outHumidity, rainWithRainRate, UV
            # beaufort_category = 0
            manifest_name = DuluthWeather
            manifest_short_name = DLH
            aeris_map = 1
            radar_html = <iframe width="650" height="360" src="https://embed.windy.com/embed2.html?lat=46.890&lon=-92.197&detailLat=47.212&detailLon=-91.637&width=650&height=360&zoom=7&level=surface&overlay=radar&product=radar&menu=&message=&marker=&calendar=24&pressure=&type=map&location=coordinates&detail=&metricWind=mph&metricTemp=%C2%B0F&radarRange=-1" frameborder="0"></iframe>    #  (default seems to center on your lat/lon)
            # radar_html_dark = None
            # aeris_map = 0
            # radar_html = ''   #  (default seems to center on your lat/lon)
            # radar_html_dark = None
            # radar_zoom = 8
            radar_marker = 1
            almanac_extras = 1
            highcharts_enabled = 1
            # graph_page_show_all_button = 1
            # graph_page_default_graphgroup = "day"
            # highcharts_homepage_graphgroup = "day"
            # highcharts_decimal = "auto"
            # highcharts_thousands = "auto"
            # googleAnalyticsId = ""
            # pi_kiosk_bold = "false"
            # pi_theme = "auto"
            # webpage_autorefresh = 0
            # reload_hook_images = 0
            # reload_images_radar = 300
            # reload_images_hook_asi = -1
            # reload_images_hook_af = -1
            # reload_images_hook_as = -1
            # reload_images_hook_ac = -1
            # show_last_updated_alert = 0
            # last_updated_alert_threshold = 1800
           
            #--- MQTT Websockets (for Real Time Streaming) Options ---
            # mqtt_websockets_enabled = 0
            # mqtt_websockets_host = ""
            # mqtt_websockets_port = 8080
            # mqtt_websockets_ssl = 0
            # mqtt_websockets_topic = ""
            # disconnect_live_website_visitor = 1800000
           
            #--- Forecast Options ---
            forecast_enabled = 1
            forecast_provider = aeris
            forecast_api_id = flatulence
            forecast_api_secret = cheekclappers
            forecast_units = us
            forecast_lang = en
            forecast_stale = 3540
            forecast_aeris_use_metar = 1
            forecast_interval_hours = 24
            forecast_alert_enabled = 1
            forecast_alert_limit = 1
            forecast_show_daily_forecast_link = 0
            # forecast_daily_forecast_link = ""
            aqi_enabled = 1
            #aqi_location_enabled = 0
            # forecast_enabled = 0
            # forecast_provider = "aeris"
            # forecast_api_id = ""
            # forecast_api_secret = ""
            # forecast_units = "us"
            # forecast_lang = "en"
            # forecast_stale = 3540
            # forecast_aeris_use_metar = 1
            # forecast_interval_hours = 24
            # forecast_alert_enabled = 0
            # forecast_alert_limit = 1
            # forecast_show_daily_forecast_link = 0
            # forecast_daily_forecast_link = ""
            # aqi_enabled = 0
            # aqi_location_enabled = 0
           
            #--- Earthquake Options ---
            earthquake_enabled = 1
            earthquake_maxradiuskm = 1000
            earthquake_stale = 10740
            earthquake_server = USGS
            geonet_mmi = 4
       
        #--- Social Options ---
        # facebook_enabled = 0
        # twitter_enabled = 0
        # twitter_hashtags = "weewx #weather"
        # social_share_html = ""
       
        #--- Kiosk Options ---
        # radar_html_kiosk = ""
        # radar_width_kiosk = 490
        # radar_height_kiosk = 362
        # mqtt_websockets_host_kiosk = ""
        # mqtt_websockets_port_kiosk = ""
        # mqtt_websockets_ssl_kiosk = ""
        # forecast_interval_hours_kiosk = 24
        # aqi_enabled_kiosk = 0
       
        [[[Labels]]]
            [[[[Generic]]]]
                # Footer Information
                footer_copyright_text = DuluthWeather.com
                footer_disclaimer_text = The weather is always better on your couch.
                # Default page headers
                home_page_header = Duluth Weather Conditions
                graphs_page_header = Weather Observation Graphs
                records_page_header = Weather Observation Records
                reports_page_header = Weather Observation Reports
                about_page_header = About This Weather Station
                powered_by = Observations are powered by an EcoWitt WittBoy
               
               
               
                #-------------------------------------------------------------
                #---
                #--- python's ConfigObj has a limitation in how it processes
                #--- comments, so we need to define an 'unused' variable below
                #--- to ensure that this whole stanza makes it into weewx.conf
                #---
                #--- please ignore the following 'unused' variable
                #---
                #-------------------------------------------------------------
                work_around_ConfigObj_limitations = true
   
    [[FTP]]
        # FTP'ing the results to a webserver is treated as just another report,
        # albeit one with an unusual report generator!
        skin = Ftp
       
        # If you wish to use FTP, set "enable" to "true", then fill out the
        # next four lines.
        # Use quotes around the password to guard against parsing errors.
        enable = false
        user = replace_me
        password = replace_me
        server = replace_me    # The ftp server name, e.g, www.myserver.org
        path = replace_me    # The destination directory, e.g., /weather
       
        # Set to True for an FTP over TLS (FTPS) connection. Not all servers
        # support this.
        secure_ftp = False
       
        # To upload files from something other than what HTML_ROOT is set
        # to above, specify a different HTML_ROOT here.
        #HTML_ROOT = /var/www/html/weewx
       
        # Most FTP servers use port 21.
        port = 21
       
        # Set to 1 to use passive mode, zero for active mode
        passive = 1
   
    [[RSYNC]]
        # rsync'ing to a webserver is treated as just another report.
        skin = Rsync
       
        # If you wish to use rsync, you must configure passwordless ssh using
        # public/private key authentication from the user account that weewx
        # runs to the user account on the remote machine where the files
        # will be copied.
        #
        # If you wish to use rsync, set "enable" to "true", then
        # fill out server, user, and path.
        # The server should appear in your .ssh/config file.
        # The user is the username used in the identity file.
        # The path is the destination directory, such as /var/www/html/weather.
        # Be sure that the user has write permissions on the destination!
        enable = true
       # server = 1.2.3.4
       # user = ubuntu
       # path = /var/www/html
        command = rsync --archive --stats -e "ssh -i /home/weewx/.ssh/id_rsa" /var/www/html/ LI...@1.2.3.4:/var/www/html
        delete = 0

        # To upload files from something other than what HTML_ROOT is set
        # to above, specify a different HTML_ROOT here.
        #HTML_ROOT = /var/www/html/weewx
       
        # Rsync can be configured to remove files from the remote server if
        # they don't exist under HTML_ROOT locally. USE WITH CAUTION: if you
        # make a mistake in the remote path, you could could unintentionally
        # cause unrelated files to be deleted. Set to 1 to enable remote file
        # deletion, zero to allow files to accumulate remotely.
        # delete = 0
   
And my log message:
ct 27 12:45:50 weatherbot weewxd[2980]: DEBUG weewx.reportengine: Report 'FTP' not enabled. Skipping.
Oct 27 12:45:50 weatherbot weewxd[2980]: DEBUG weewx.reportengine: Running report 'RSYNC'
Oct 27 12:45:50 weatherbot weewxd[2980]: DEBUG weewx.reportengine: Found configuration file /etc/weewx/skins/Rsync/skin.conf for report 'RSYNC'
Oct 27 12:45:50 weatherbot weewxd[2980]: DEBUG weewx.reportengine: Cannot read localization file /etc/weewx/skins/Rsync/lang/en.conf for report 'RSYNC': Config file not found: "/etc/weewx/skins/Rsync/lang/en.conf".
Oct 27 12:45:50 weatherbot weewxd[2980]: DEBUG weewx.reportengine: **** Using defaults instead.
Oct 27 12:45:50 weatherbot weewxd[2980]: DEBUG weewx.reportengine: Unable to set locale 'en': unsupported locale setting. Using default.
Oct 27 12:45:50 weatherbot weewxd[2980]: DEBUG weewx.reportengine: Running generators for report 'RSYNC' in directory '/etc/weewx/skins/Rsync' with locale 'en_GB.UTF-8'
Oct 27 12:45:50 weatherbot weewxd[2980]: DEBUG weewx.reportengine: rsyncgenerator: Rsync upload not requested. Skipped.

Thats on top of the new 1.4 Belchertown skin not generating completely. Im at a loss at this point. Considering formatting and starting from scratch again.

Sideshow Raheem

unread,
Oct 27, 2025, 4:18:27 PM (5 days ago) Oct 27
to weewx-user
Well my long nightmare is over. Typing this up for others as they may encounter the same thing.
My setup:
Raspberry Pi 4
Debian 13 trixie
t3.micro EC2 in AWS
EcoWitt Pippboy 
EcoWitt GW1000
WeeWx 5.2
Belchertown 1.4
GW1000 0.6.3
Python 3.13.5

The main issue was that WeeWX runs as the weewx system user, whose home directory is actually /var/lib/weewx (not /home/weewx like I had thought and assumed). SSH was looking for keys in /var/lib/weewx/.ssh, but my keys were in /home/weewx/.ssh. So when I had WeeWX try to rsync to my EC2 server, it couldn’t find any valid private key and I'd get a Permission denied (publickey) error.

Other issues I ran into and things I learned. New commands to check logging instead of using tail:
sudo systemctl status weewx
sudo journalctl -u weewx -f
Were both helpful especially when I had debug turned on. That helped me identify that at least the driver was polling the EcoWitt correctly.

I had to verify directory ownership and permissions:
ls -la /var/www/html
/var/www/html/weewx was owned by the weewx user and group.

I kept getting rsync errors:
DEBUG weeutil.rsyncupload: rsyncupload: cmd: [['rsync', '--archive', '--stats', '-e', 'ssh', '/var/www/html/', 'farts@toots:/var/www/html']]
Tested SSH directly:
sudo -u weewx ssh fart@toots "echo ok"
And got:
Permission denied (publickey)

Ran a verbose SSH check:
sudo -u weewx ssh -vvv farts@toots "echo ok"
And saw:
weewx user’s home directory is - /var/lib/weewx, not /home/weewx
SSH searched for keys in /var/lib/weewx/.ssh and saw NOTHING.

Created proper SSH directory:
sudo mkdir -p /var/lib/weewx/.ssh
sudo chown weewx:weewx /var/lib/weewx/.ssh
sudo chmod 700 /var/lib/weewx/.ssh

Copied the working private key:
sudo cp /home/weewx/.ssh/id_rsa /var/lib/weewx/.ssh/id_rsa
sudo chown weewx:weewx /var/lib/weewx/.ssh/id_rsa
sudo chmod 600 /var/lib/weewx/.ssh/id_rsa

Made sure my EC2 had the right key:
sudo -u weewx ssh-keygen -y -f /var/lib/weewx/.ssh/id_rsa
Pasted that line into /home/ubuntu/.ssh/authorized_keys on my EC2.
Fixed the permissions there:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown farty:pants ~/.ssh ~/.ssh/authorized_keys

Then retested - sudo -u weewx ssh tootsgalore@crappedmypants "echo ok" and got an OK.

After rsync was fixed I was getting this:
INFO weewx.cheetahgenerator: Generated N files for report Belchertown
INFO weewx.reportengine: Copied files to /var/www/html

But a sudo systemctl restart weewx fixed that issue.

OK Im done, whew. Time for other projects now.
Reply all
Reply to author
Forward
0 new messages