Пример #1
0
 def download_archive_interval(self):
     logdbg('downloading archive interval')
     data = self.get_data("http://weatherlink.com/webdl.php"
                          "?timestamp=0&user=%s&pass=%s&action=headers" %
                          (self.username, self.password))
     if data is None:
         raise weewx.WeeWxIOError("download of archive interval failed")
     for line in data.splitlines():
         if line.find('ArchiveInt=') >= 0:
             logdbg('found archive interval: %s' % line)
             return int(line[11:])
     raise weewx.WeeWxIOError("cannot determine archive interval from %s" %
                              data)
Пример #2
0
 def get_data(url):
     try:
         request = Request(url)
         request.add_header('User-Agent', 'WeeWX/%s' % weewx.__version__)
         response = urlopen(request, timeout=4)
     except URLError as e:
         logerr("get_data(): Unable to open weather station %s or %s" % (url, e))
         raise weewx.WeeWxIOError("get_data(): Socket error or timeout for weather station %s or %s" % (url, e))
     except (socket.error, socket.timeout) as e:
         logerr("get_data(): Socket error or timeout for weather station %s or %s" % (url, e))
         raise weewx.WeeWxIOError("get_data(): Socket error or timeout for weather station %s or %s" % (url, e))
     if response.getcode() != 200:
         raise weewx.WeeWxIOError("get_data(): Bad response code returned: %d." % response.code)
     content_length = int(response.info().get('Content-Length'))
     return response.read(content_length).decode('utf-8')
Пример #3
0
 def get_data(url):
     try:
         response = six.moves.urllib.request.urlopen(url)
         return response.read()
     except (socket.error, socket.timeout, six.moves.urllib.error.HTTPError,
             six.moves.urllib.error.URLError) as e:
         raise weewx.WeeWxIOError("get data failed: %s" % e)
Пример #4
0
 def genLoopPackets(self):
     ntries = 0
     while ntries < self.max_tries:
         ntries += 1
         try:
             # Poll on poll_interval boundaries.
             if self.poll_interval != 0:
                 time.sleep(self.time_to_next_poll())
             data = IP100Station.get_data(self.station_url)
             log.debug("data: %s" % data)
             pkt = IP100Station.parse_data(data)
             log.debug("raw packet: %s" % pkt)
             ntries = 0
             packet = {'dateTime': int(time.time() + 0.5)}
             if pkt['base_units'] == 'English':
                 packet['usUnits'] = weewx.US
             else:
                 packet['usUnits'] = weewx.METRICWX
             for k in self.sensor_map:
                 if self.sensor_map[k] in pkt:
                     packet[k] = pkt[self.sensor_map[k]]
             if 'day_rain_total' in packet:
                 packet['rain'] = self._rain_total_to_delta(
                     packet['day_rain_total'], self.previous_rain_total)
                 self.previous_rain_total = packet['day_rain_total']
             else:
                 log.debug("no rain in packet: %s" % packet)
             log.debug("packet: %s" % packet)
             yield packet
         except weewx.WeeWxIOError as e:
             log.info("failed attempt %s of %s: %s" %
                    (ntries, self.max_tries, e))
             time.sleep(self.retry_wait)
     else:
         raise weewx.WeeWxIOError("max tries %s exceeded" % self.max_tries)
Пример #5
0
 def _get_with_retries(self):
     for n in range(self.max_tries):
         try:
             return self.sensor.get_data()
         except (IOError, ValueError, TypeError) as e:
             loginf("failed attempt %s of %s: %s" %
                    (n + 1, self.max_tries, e))
             time.sleep(self.retry_wait)
     else:
         raise weewx.WeeWxIOError("%s: max tries %s exceeded" %
                                  (method, self.max_tries))
Пример #6
0
 def __init__(self, **stn_dict):
     loginf('driver version is %s' % DRIVER_VERSION)
     self.model = stn_dict.get('model', 'MS-120')
     loginf("model is %s" % self.model)
     port = stn_dict.get('port', Tracer.DEFAULT_PORT)
     loginf("port is %s" % port)
     baud_rate = int(stn_dict.get('baud_rate', Tracer.DEFAULT_BAUD_RATE))
     timeout = int(stn_dict.get('timeout', Tracer.DEFAULT_TIMEOUT))
     self.poll_interval = int(stn_dict.get('poll_interval', 10))
     loginf("poll interval is %s" % self.poll_interval)
     self.sensor_map = dict(TracerDriver.DEFAULT_MAP)
     if 'sensor_map' in stn_dict:
         self.sensor_map.update(stn_dict['sensor_map'])
     loginf("sensor map: %s" % self.sensor_map)
     self.max_tries = int(stn_dict.get('max_tries', 3))
     self.retry_wait = int(stn_dict.get('retry_wait', 5))
     self.station = Tracer(port, baud_rate, timeout)
     if not self.station.connect():
         raise weewx.WeeWxIOError("cannot connect to device")
     loginf('device info: %s' % self.station.get_info())
Пример #7
0
 def parse_data(data):
     """Parse the XML data which is a flat non-hierarchical record and return 
     a two-level dictionary hierarchy where each key is the field group and 
     associated with that, a dictionary with the fields and values associated 
     with that group."""
     import re
     pkt_grp = dict()
     # If closing tag is truncated or has excess junk like null bytes, 
     # fix before parsing.
     if data.startswith('<oriondata') and not data.endswith('</oriondata>'):
         data = re.sub('</ori(ondata)?.*$','</oriondata>', data)
         logerr("parse_data(): attempted to correct truncated data: %s" % data[-19:-1])
     try:
         elements = ElementTree.fromstring(data)
         if elements.tag == 'oriondata' and elements[0].tag == 'meas':
             for child in elements:
                 name = child.attrib['name']
                 # Ensure the correct tag and attribute is one to be recorded
                 if child.tag == 'meas' and name in ColumbiaMicroServerStation.XML_INPUT_ELEMENTS:
                     # Get the associated packet group for this field
                     pkt_type = ColumbiaMicroServerStation.XML_INPUT_ELEMENTS[name]
                     # Initialize a new dictionary for a packet group
                     if not pkt_type in pkt_grp:
                         pkt_grp[pkt_type] = dict()
                     # If the field is in the list to use for the unit type,
                     # save the unit type as the field 'base_units'.
                     if name in ColumbiaMicroServerStation.XML_INPUT_UNIT_ELEMENTS:
                         # If the packet type is 'generic' then it's a unit type that's
                         # neither US or metric such as degrees for wind direction.
                         if pkt_type == 'generic':
                             pkt_grp[pkt_type]['base_units'] = 'generic'
                         else:  
                             pkt_grp[pkt_type]['base_units'] = child.attrib['unit']
                     # Store the field and value in the dictionary for the associated packet type.
                     pkt_grp[pkt_type][name] = float(child.text)
         else:
             raise ElementTree.ParseError("invalid XML file. Missing <oriondata> and/or <meas/> tags detected.")
     except ElementTree.ParseError as e:
         logerr("ElementTree ParseError: %s for data: %s" % (e, data))
         raise weewx.WeeWxIOError(e)
     return pkt_grp
Пример #8
0
 def genLoopPackets(self):
     while True:
         try:
             buf = self.station.read()
             if buf:
                 pkt = Station.decode(buf)
                 if buf[0] in [0xd3, 0xd4, 0xd5, 0xd6, 0xdb, 0xdc]:
                     # send ack for most data packets
                     # FIXME: what is last number in the ACK?
                     # observed: 0x00 0x20 0xc1 0xc7 0xa0 0x99
                     cmd = [
                         0x41, 0x43, 0x4b, buf[0], buf[7],
                         _lo(self.last_record)
                     ]
                     self.station.write(cmd)
                     packet = self.convert_loop(pkt)
                     self.cached.update(packet)
                     yield self.cached
             if time.time() - self.last_a6 > self.heartbeat:
                 logdbg("request station status: %s (%02x)" %
                        (self.last_record, _lo(self.last_record)))
                 cmd = [0xa6, 0x91, 0xca, 0x45, 0x52, _lo(self.last_record)]
                 self.station.write(cmd)
                 self.last_a6 = time.time()
             if self.last_7x == 0:
                 # FIXME: what are the 72/73 messages?
                 # observed:
                 # 73 e5 0a 26 0e c1
                 # 73 e5 0a 26 88 8b
                 # 72 a9 c1 60 52 00
                 #                    cmd = [0x72, 0xa9, 0xc1, 0x60, 0x52, 0x00]
                 cmd = [0x73, 0xe5, 0x0a, 0x26, 0x88, 0x8b]
                 #                    cmd = [0x73, 0xe5, 0x0a, 0x26, 0x0e, 0xc1]
                 self.station.write(cmd)
                 self.last_7x = time.time()
         except usb.USBError, e:
             if not e.args[0].find('No data available'):
                 raise weewx.WeeWxIOError(e)
         except (WrongLength, BadChecksum), e:
             loginf(e)
Пример #9
0
            pkt['pm2_5'] = pm2_5
            pkt['pm10_0'] = pm10_0
            yield pkt
            if self.poll_interval:
                time.sleep(self.poll_interval)

    def _get_with_retries(self):
        for n in range(self.max_tries):
            try:
                return self.sensor.get_data()
            except (IOError, ValueError, TypeError), e:
                loginf("failed attempt %s of %s: %s" %
                       (n + 1, self.max_tries, e))
                time.sleep(self.retry_wait)
        else:
            raise weewx.WeeWxIOError("%s: max tries %s exceeded" %
                                     (method, self.max_tries))


def _fmt(x):
    return ' '.join(["%0.2X" % ord(c) for c in x])


class SDS011(object):
    DEFAULT_PORT = '/dev/ttyUSB0'
    DEFAULT_BAUDRATE = 9600
    DEFAULT_TIMEOUT = 3.0  # seconds
    CMD_MODE = 2
    CMD_QUERY_DATA = 4
    CMD_DEVICE_ID = 5
    CMD_SLEEP = 6
    CMD_FIRMWARE = 7
Пример #10
0
 def get_data(url):
     try:
         response = urllib2.urlopen(url)
         return response.read()
     except (socket.error, socket.timeout, urllib2.HTTPError), e:
         raise weewx.WeeWxIOError("get data failed: %s" % e)
Пример #11
0
                if pkt['base_units'] == 'English':
                    packet['usUnits'] = weewx.US
                else:
                    packet['usUnits'] = weewx.METRICWX
                for k in self.sensor_map:
                    if self.sensor_map[k] in pkt:
                        packet[k] = pkt[self.sensor_map[k]]
                yield packet
                if self.poll_interval:
                    time.sleep(self.poll_interval)
            except weewx.WeeWxIOError, e:
                loginf("failed attempt %s of %s: %s" %
                       (ntries, self.max_tries, e))
                time.sleep(self.retry_wait)
        else:
            raise weewx.WeeWxIOError("max tries %s exceeded" % self.max_tries)


class IP100Station(object):
    @staticmethod
    def get_data(url):
        try:
            response = urllib2.urlopen(url)
            return response.read()
        except (socket.error, socket.timeout, urllib2.HTTPError), e:
            raise weewx.WeeWxIOError("get data failed: %s" % e)

    @staticmethod
    def parse_data(data):
        pkt = dict()
        try:
Пример #12
0
 def genStartupRecords(self, since_ts):
     loginf("reading records since %s" % timestamp_to_string(since_ts))
     hbuf = None
     last_ts = None
     cnt = 0
     while True:
         try:
             buf = self.station.read()
             if buf:
                 if buf[0] == 0xd2:
                     hbuf = buf
                     buf = None
                 elif buf[0] == 0x7f and hbuf is not None:
                     # FIXME: need better indicator of second half history
                     buf = hbuf + buf
                     hbuf = None
             if buf and buf[0] == 0xd2:
                 self.last_record = Station.get_record_index(buf)
                 ts = Station._extract_ts(buf[4:9])
                 if ts is not None and ts > since_ts:
                     keep = True if last_ts is not None else False
                     pkt = Station.decode(buf)
                     packet = self.convert_historical(pkt, ts, last_ts)
                     last_ts = ts
                     if keep:
                         logdbg("historical record: %s" % packet)
                         cnt += 1
                         yield packet
             if buf and buf[0] == 0x57:
                 idx = Station.get_latest_index(buf)
                 msg = "count=%s last_index=%s latest_index=%s" % (
                     cnt, self.last_record, idx)
                 if self.last_record + 1 >= idx:
                     loginf("catchup complete: %s" % msg)
                     break
                 loginf("catchup in progress: %s" % msg)
             if buf and buf[0] == 0x41 and buf[3] == 0x65:
                 nxtrec = Station.get_next_index(self.last_record)
                 logdbg("request records starting with %s" % nxtrec)
                 cmd = [0xcd, 0x18, 0x30, 0x62, _hi(nxtrec), _lo(nxtrec)]
                 self.station.write(cmd)
             if time.time() - self.last_a6 > self.heartbeat:
                 logdbg("request station status: %s (%02x)" %
                        (self.last_record, _lo(self.last_record)))
                 cmd = [0xa6, 0x91, 0xca, 0x45, 0x52, _lo(self.last_record)]
                 self.station.write(cmd)
                 self.last_a6 = time.time()
             if self.last_7x == 0:
                 # FIXME: what does 72/73 do?
                 cmd = [0x73, 0xe5, 0x0a, 0x26, 0x88, 0x8b]
                 self.station.write(cmd)
                 self.last_7x = time.time()
             if time.time() - self.last_65 > self.history_retry:
                 logdbg("initiate record request: %s (%02x)" %
                        (self.last_record, _lo(self.last_record)))
                 cmd = [0x65, 0x19, 0xe5, 0x04, 0x52, _lo(self.last_record)]
                 self.station.write(cmd)
                 self.last_65 = time.time()
         except usb.USBError, e:
             if not e.args[0].find('No data available'):
                 raise weewx.WeeWxIOError(e)
         except (WrongLength, BadChecksum), e:
             loginf(e)