sqlite> select * from archive_day_outTemp order by dateTime desc limit 1; dateTime |min |mintime |max |maxtime |sum |count|wsum |sumtime 1536040800|55.1999999999999|1536065400|87.5|1536097806|18741.1237726958|263 |5622337.13180874|78900
sqlite> select * from archive_day_l2_volt order by dateTime desc limit 10; dateTime |min |mintime |max |maxtime |sum |count|wsum |sumtime 1536040800|115.15|1536117900|125.74|1536079200|32513.28|263 |9753984.0|78900Hopefully this request makes sense, and thank you for your help!http://carlincomputing.duckdns.org/weewx/index.html
--
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 weewx-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Thank you for your replies.
A couple points of clarification: The main datasource for my station is a Vantage Pro2, and it is using weewx as designed, LOOP packets, etc. I have added a second data source as described here http://www.weewx.com/docs/customizing.htm#Adding_2nd_source, which specifically discusses adding data to the record dictionary.
Weewx is currently configured to get the hilo data from the loop packets as described, and this is working for the Pro2. My question is specifically about the additional custom service that has been added to the data_services section as described in the doc linked above.
Does that clarify anything?
Based on the comments it sounds like there is no way to add the hilo data manually as part of the additional service, correct?
Is there a way to have my custom service run as part of a loop, rather than the record without reinventing the wheel, or disrupting the Pro2 and its data?
Thomas
#!/usr/bin/env python
import weewx
import syslog
from weewx.engine import StdService
import schemas.wview
import requests
class add_esp_records(StdService):
def __init__(self, engine, config_dict):
# Initialize my superclass first:
super(add_esp_records, self).__init__(engine, config_dict)
# Bind to any new archive record events:
self.bind(weewx.NEW_ARCHIVE_RECORD, self.new_archive_packet)
try:
# Dig the needed options out of the configuration dictionary.
# If a critical option is missing, an exception will be raised and
# the alarm will not be set.
self.devices = config_dict['ESP8266']
#print "Devices: "
#print self.devices
syslog.syslog(syslog.LOG_INFO, "ESP8266: Setup for devices")
except KeyError as e:
syslog.syslog(syslog.LOG_INFO, "ESP8266: Not configured. Missing parameter: %s" % e)
def new_archive_packet(self, event):
for device, value in self.devices.iteritems():
self.url = device
#print "URL: "
#print self.url
self.sensors = value
#print "Sensors: "
#print self.sensors
#Pass the URL and the expected values to the read function.
esp_records = read_esp_json(self.url);
if esp_records != 0:
#print self.sensors['mac']
#print esp_records['UID']
if self.sensors['mac'] == esp_records['UID']:
#print "Sensor ID matches, continue"
for sensor in self.sensors:
if sensor != 'mac':
print "DB Entry: " + self.sensors[sensor]
try:
value = esp_records[sensor]
except KeyError:
value = None
print "Value: " + str(value)
event.record[self.sensors[sensor]] = value
#Reads the data from the ESP and pass it back to be added to the database.
def read_esp_json(url):
#Fetch the data, read, and do some basic sanitization on the output.
try:
response = requests.get(url, timeout=2)
except (requests.exceptions.RequestException) as err:
syslog.syslog(syslog.LOG_INFO, "ESP8266: Unable to access " + url + ": %s" %err)
return 0
data = response.json()
print data
# print data['KWh']
result = {}
for key in data:
# print key
if key == 'UID':
result[key] = data[key]
else:
if data[key] == 'nan':
result[key] = None
else:
result[key] = float(data[key])
return result
#Add extra fields to the schema.
schema_with_esp = schemas.wview.schema + [('DoorOpen1', 'REAL'), ('DoorClosed1', 'REAL'), ('DoorOpen2', 'REAL'), ('DoorClosed2', 'REAL'), ('IrrigationFlow', 'REAL'), ('IrrigationPressure', 'REAL'),('esp1Signal', 'REAL'), ('esp2Signal', 'REAL'), ('esp3Signal', 'REAL'), ('esp3LIPOVoltage', 'REAL'), ('esp3LIPOCurrent', 'REAL'), ('esp3SolarVoltage', 'REAL'), ('esp3SolarCurrent', 'REAL'), ('esp3OutputVoltage', 'REAL'), ('esp3OutputCurrent', 'REAL'), ('extraHumid3', 'REAL'), ('esp4Signal', 'REAL'), ('esp4LIPOVoltage', 'REAL'), ('l1_watt', 'REAl'), ('l1_volt', 'REAl'), ('l1_amp', 'REAl'), ('l2_watt', 'REAl'), ('l2_volt', 'REAl'), ('l2_amp', 'REAl'), ('kwh', 'REAL')]
##############################################################################
# This section configures the internal weewx engine.
[Engine]
[[Services]]
# This section specifies the services that should be run. They are
# grouped by type, and the order of services within each group
# determines the order in which the services will be run.
prep_services = weewx.engine.StdTimeSynch
data_services = user.esp8266.add_esp_records,
process_services = weewx.engine.StdConvert, weewx.engine.StdCalibrate, weewx.engine.StdQC, weewx.wxservices.StdWXCalculate, user.cmon.Computer\
Monitor
archive_services = weewx.engine.StdArchive
restful_services = weewx.restx.StdStationRegistry, weewx.restx.StdWunderground, weewx.restx.StdPWSweather, weewx.restx.StdCWOP, weewx.restx.St\
dWOW, weewx.restx.StdAWEKAS
report_services = weewx.engine.StdPrint, weewx.engine.StdReport
##############################################################################
# This section is for information about the additional ESP8266 Sensors that are in use.
[ESP8266]
[[http://192.168.2.104]]
mac = 5C:CF:7F:02:0C:17
Temp = extraTemp1
Humid = extraHumid1
doorOpen = DoorOpen1
doorClosed = DoorClosed1
Signal = esp1Signal
[[http://192.168.2.107]]
mac = 5C:CF:7F:07:5B:90
Temp = extraTemp2
Humid = extraHumid2
doorOpen = DoorOpen2
doorClosed = DoorClosed2
Signal = esp2Signal
[[http://192.168.2.105]]
mac = F8:F0:05:E7:A2:7B
Flow = IrrigationFlow
Pressure = IrrigationPressure
Signal = esp3Signal
LIPO_Voltage = esp3LIPOVoltage
LIPO_Current = esp3LIPOCurrent
Solar_Voltage = esp3SolarVoltage
Solar_Current = esp3SolarCurrent
Output_Voltage = esp3OutputVoltage
Output_Current = esp3OutputCurrent
[[http://192.168.2.112]]
mac = F8:F0:05:E7:A2:89
Signal = esp4Signal
L1_apparentPower = l1_watt
L1_volt = l1_volt
L1_amp = l1_amp
L2_apparentPower = l2_watt
L2_volt = l2_volt
L2_amp = l2_amp
KWh = kwh
##############################################################################
# Options for extension 'cmon'
[ComputerMonitor]
data_binding = cmon_binding
Perfect Thank you Gary! That gets me what I need. Now I just need to reprogram all my sensors and my driver, or create another service to collect and queue data. I'm leaning towards MQTT, for its simplicity, speed, and scalability. This sounds more like a winter project to me!
A couple quick questions before we wrap this up:I have seen rumblings about MQTT drivers in the forums, but some of them look like they are so Weewx provides MQTT data for something else. Is there anything that you are aware of that could act as a second service with MQTT being the data source? Has anything been blessed by the weewx development crew? I would hate to reinvent the wheel if someone else figured it out for me!
Second, just for my piece of mind, did i miss the NEW_LOOP_PACKET in the documentation, or was it not mentioned? If it is the latter, I think this would be a valuable addition.
Traceback (most recent call last): File "/usr/bin/weewxd", line 64, in <module> weewx.engine.main(options, args) File "/usr/share/weewx/weewx/engine.py", line 877, in main engine.run() File "/usr/share/weewx/weewx/engine.py", line 191, in run self.dispatchEvent(weewx.Event(weewx.NEW_LOOP_PACKET, packet=packet)) File "/usr/share/weewx/weewx/engine.py", line 224, in dispatchEvent callback(event) File "/usr/share/weewx/user/esp8266.py", line 105, in new_loop_packet event.record[self.subscriptions[topic]] = valueAttributeError: 'Event' object has no attribute 'record'
Perfect! thank you Gary! I knew it had to be something simple like that. Everything is up and running now, and I'll just need to catch the necessary exceptions, and optimize the collection as much as possible. Is there a target time I should shoot for, or just try to make it as fast as possible?