Bill,

Try the attached file in place of your existing cwxn.py.This version will 
calculate rain24 and dayRain by querying the database if rain24 and dayRain 
fields are not in the packet received from your station.  To install:

1. rename your existing cwxn.py to cwxn_orig.py (it will be in 
/home/weewx/bin/user or /usr/share/weewx/user)
2. download the attached cwxn.py and save in place of your current cwxn.py
3. restart WeeWX
4. monitor the log and once a report cycle is complete check wxnow.txt

If any issues post a copy of the WeeWX log from startup showing any errors. 
If you need to revert to the old version just delete cwxn.py and rename 
cwxn_orig.py back to cwxn.py and restart WeeWX.

Gary



On Wednesday, 26 February 2020 03:53:36 UTC+10, Bill Arthur wrote:
>
> Hi Gary,
>
> Thanks for the quick response. This is my second week with Weewx so I 
> assumed it was something I overlooked. And I'm glad a solution is 
> relatively close.
> I am using a Ambient Weather WS-2902 array with an Ecowitt GW1000 and 
> using the interceptor 0.53.  cwxn is 0.4
>
>
>
>
> On Tuesday, February 25, 2020 at 7:42:31 AM UTC-6, gjr80 wrote:
>>
>> Hi,
>>
>> Looking at the cwxn service code there are three rain related values 
>> included in the output, these are (named in the code) hourRain, rain24 
>> and dayRain. Presumably these are total rainfalls in the last hour, the 
>> last 24 hours and since midnight respectively. The cwxn service calculates 
>> hourRain by querying the database so hourRain should always be correct. 
>> However, rain24 and dayRain are not calculated by querying the database, 
>> rather they are pulled directly from fields of the same name in either the 
>> loop packets or archive records (depending on whether you bind to loop or 
>> archive) emitted by your station. Unfortunately, not all stations emit 
>> these fields and I am guessing that is the case with your station. You 
>> didn't mention what (weather) station you are using?
>>
>> As for the data on your web page, if that is the Standard or Seasons skin 
>> that is shipped with WeeWX then in all likelihood you will find that the 
>> WeeWX tag system is being used and something like $day.rain.sum is being 
>> used to calculate and display the days rainfall by querying the database. 
>> Unfortunately the WeeWX tag system is only available in WeeWX reports and 
>> is not available in services such as cwxn.
>>
>> Don't worry, all is not lost, if it is a case of your station not 
>> emitting rain24 and dayRain it will be a fairly straightforward job to 
>> modify the cwxn service to calculate these fields from the database just as 
>> is done with hourRain. I know the cwxn author is a bit busy with the 
>> WeeWX 4.0 release at the moment but let me see if I have some time tomorrow 
>> to make the necessary changes (or perhaps some other enthusiastic WeeWX 
>> user will come along and do the same before then) :)
>>
>> Gary
>>
>>
>> On Tuesday, 25 February 2020 10:33:29 UTC+10, Bill Arthur wrote:
>>>
>>> I recently added the cwxn extension so that I could pass the weather to 
>>> my APRS/CWOP app
>>>
>>> Its working fairly well, but it only reports the current rain rate. The 
>>> 1hr and 12hr (p and P) are always 000  
>>> We had 1.03" today so I had plenty of opportunities to test. The weewx 
>>> html page shows the rain.
>>>
>>> Here's my example:
>>> Feb 24 2020 18:20
>>> 129/002g004t052r000p000P000h096b10067
>>>
>>> I put "binding = archive"  in  weewx.conf
>>>
>>> I'm missing something here, any ideas?
>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups 
"weewx-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/weewx-user/92ce3ff0-dda8-4fb4-ba6e-d81d47cdb2ad%40googlegroups.com.
# $Id: cwxn.py 1280 2015-03-01 17:01:56Z mwall $
# Copyright 2014 Matthew Wall
"""Emit loop data to wxnow.txt file with Cumulus format:
   http://wiki.sandaysoft.com/a/Wxnow.txt

Put this file in bin/user/cwxn.py, then add this to your weewx.conf:

[CumulusWXNow]
    filename = /path/to/wxnow.txt

[Engine]
    [[Services]]
        process_services = ..., user.cwxn.CumulusWXNow
"""

# FIXME: when value is None, we insert a 0.  but is there something in the
#        aprs spec that is more appropriate?

import math
import time
import syslog

import weewx
import weewx.wxformulas
import weeutil.weeutil
import weeutil.Sun
from weewx.engine import StdService

VERSION = "0.5a"

if weewx.__version__ < "3":
    raise weewx.UnsupportedFeature("weewx 3 is required, found %s" %
                                   weewx.__version__)

def logmsg(level, msg):
    syslog.syslog(level, 'cwxn: %s' % msg)

def logdbg(msg):
    logmsg(syslog.LOG_DEBUG, msg)

def loginf(msg):
    logmsg(syslog.LOG_INFO, msg)

def logerr(msg):
    logmsg(syslog.LOG_ERR, msg)

def convert(v, metric, group, from_unit_system, to_units):
    ut = weewx.units.getStandardUnitType(from_unit_system, metric)
    vt = (v, ut[0], group)
    v = weewx.units.convert(vt, to_units)[0]
    return v

def nullproof(key, data):
    if key in data and data[key] is not None:
        return data[key]
    return 0

def calcRainHour(dbm, ts):
    sts = ts - 3600
    val = dbm.getSql("SELECT SUM(rain) FROM %s "
                     "WHERE dateTime>? AND dateTime<=?" % dbm.table_name,
                     (sts, ts))
    if val is None:
        return None
    return val[0]

def calcRain24(dbm, ts):
    sts = ts - 86400
    val = dbm.getSql("SELECT SUM(rain) FROM %s "
                     "WHERE dateTime>? AND dateTime<=?" % dbm.table_name,
                     (sts, ts))
    if val is None:
        return None
    return val[0]

def calcDayRain(dbm, ts):
    sts = weeutil.weeutil.startOfDay(ts)
    val = dbm.getSql("SELECT SUM(rain) FROM %s "
                     "WHERE dateTime>? AND dateTime<=?" % dbm.table_name,
                     (sts, ts))
    if val is None:
        return None
    return val[0]

class CumulusWXNow(StdService):

    def __init__(self, engine, config_dict):
        super(CumulusWXNow, self).__init__(engine, config_dict)
        loginf("service version is %s" % VERSION)
        d = config_dict.get('CumulusWXNow', {})
        self.filename = d.get('filename', '/var/tmp/wxnow.txt')
        binding = d.get('binding', 'loop').lower()
        if binding == 'loop':
            self.bind(weewx.NEW_LOOP_PACKET, self.handle_new_loop)
        else:
            self.bind(weewx.NEW_ARCHIVE_RECORD, self.handle_new_archive)

        loginf("binding is %s" % binding)
        loginf("output goes to %s" % self.filename)

    def handle_new_loop(self, event):
        self.handle_data(event.packet)

    def handle_new_archive(self, event):
        self.handle_data(event.record)

    def handle_data(self, event_data):
        try:
            dbm = self.engine.db_binder.get_manager('wx_binding')
            data = self.calculate(event_data, dbm)
            self.write_data(data)
        except Exception, e:
            weeutil.weeutil.log_traceback('cwxn: **** ')

    def calculate(self, packet, archive):
        pu = packet.get('usUnits')
        data = dict()
        data['dateTime'] = packet['dateTime']
        data['windDir'] = nullproof('windDir', packet)
        v = nullproof('windSpeed', packet)
        data['windSpeed'] = convert(v, 'windSpeed', 'group_speed', pu, 'mile_per_hour')
        v = nullproof('windGust', packet)
        data['windGust'] = convert(v, 'windGust', 'group_speed', pu, 'mile_per_hour')
        v = nullproof('outTemp', packet)
        data['outTemp'] = convert(v, 'outTemp', 'group_temperature', pu, 'degree_F')
        v = calcRainHour(archive, data['dateTime'])
        if v is None:
            v = 0
        data['hourRain'] = convert(v, 'rain', 'group_rain', pu, 'inch')
        if 'rain24' in packet:
            v = nullproof('rain24', packet)
        else:
            v = calcRain24(archive, data['dateTime'])
            v = 0 if v is None else v
        data['rain24'] = convert(v, 'rain', 'group_rain', pu, 'inch')
        if 'dayRain' in packet:
            v = nullproof('dayRain', packet)
        else:
            v = calcDayRain(archive, data['dateTime'])
            v = 0 if v is None else v
        data['dayRain'] = convert(v, 'rain', 'group_rain', pu, 'inch')
        data['outHumidity'] = nullproof('outHumidity', packet)
        v = nullproof('barometer', packet)
        data['barometer'] = convert(v, 'pressure', 'group_pressure', pu, 'mbar')
        return data

    def write_data(self, data):
        fields = []
        fields.append("%03d" % int(data['windDir']))
        fields.append("/%03d" % int(data['windSpeed']))
        fields.append("g%03d" % int(data['windGust']))
        fields.append("t%03d" % int(data['outTemp']))
        fields.append("r%03d" % int(data['hourRain'] * 100))
        fields.append("p%03d" % int(data['rain24'] * 100))
        fields.append("P%03d" % int(data['dayRain'] * 100))
        if data['outHumidity'] < 0 or 100 <= data['outHumidity']:
            data['outHumidity'] = 0
        fields.append("h%03d" % int(data['outHumidity']))
        fields.append("b%05d" % int(data['barometer'] * 10))
        with open(self.filename, 'w') as f:
            f.write(time.strftime("%b %d %Y %H:%M\n",
                                  time.localtime(data['dateTime'])))
            f.write(''.join(fields))
            f.write("\n")

Reply via email to