Monday, January 5, 2015

AcuRite Weather Station, Raspberry Pi, Fun Stuff, Part 8

Part 7 of this series is here <link>

I mentioned way back in part 1 that I visited a site and discussed a linux version of the AcuRite weather station interface with a guy on Valley Information Systems discussion board <link>.  The person was the professed author of the VIS sofware that is provided by AcuRite and he has a greatly expanded and pretty cotton pickin' slick version that can be subscribed to as well.  Michael Walsh is his name and he's pretty sharp, but very, very snarky.

You've all seen this, especially from some of the dweebs on the various forums that belittle every post that is put up on the site.  I'd show you the post so you could get a feel for what I'm talking about, but he removed it.  Yep, when I went back and posted about my success with reading the USB port on linux and starting to decode the various items, I got a subscription notice that my post had been moved to the archives.  Which generally means it can still be found by a search on the forum, but it doesn't appear in the lists of posts.

Today, I got another notice and when I clicked on it:

The topic or board you are looking for appears to be either missing or off limits to you.

Heh, it looks like it's off the board entirely.  When I looked for 'linux' on the board, there's been a couple of folk looking around for a linux version recently; I may have become competition for him.

Keep in mind, I don't know why he moved the posts, or why he eventually made them disappear, it could just be weird traffic or some accident.  But it is cool that the posts of a successful, FREE, version that reads the AcuRite console's USB output on a little Raspberry Pi that doesn't tie up your home PC have disappeared.

But, once it's on the internet, it gets read, copied, backed up, mailed about, etc.  Especially since a few folk have helped me on this project by finding bugs and running it a lot in their own home.  I just typed "acurite raspberry pi" into Goodle and guess what site came up as the first entry?  hee hee.

So, you weather station folk out there, folk that got one of these for Christmas, people that succumbed to the impulse of the cool packaging at Costco (I'm in that group) spread the word.  If enough folk get involved, this could lead to a great weather station package.  I just don't have the hardware, facilities, time, or diversity in my network to do a really good job.

But wouldn't it be cool

51 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Indeed it is cool - I've got your code hooked up and talking to Weather Underground! I did it by converting a perl script for a different weather station to upload the data read by your code. I'm running on a Mac currently but it will get put on to a RPi soon so I don't have to keep the AcuRite console wired up to my Mac.

    --dominic

    ReplyDelete
    Replies
    1. That perl script should run on the Pi. Have fun with it.

      Delete
  3. Hi!!! your blog is awesome!!!
    Let me introduce myself. My name is Lucid and working in WIZnet Technology.
    As you know that the WIZnet provided Arduion official Ethernet shield chip such as W5100.
    I would like to introduce WIZnet new product for your Home automation application.
    Specially, WizFi250 Wi-Fi soultion.
    If you interesting in WIZnet product, Please send e-mail to me (main8096@wiznettechnology.com)
    I'm looking forward to your reply.
    Have a nice day.
    Lucid.

    ReplyDelete
  4. good stuff! thanks for sharing.

    it looks like the second to last byte is the sensor strength. i started with console and sensor on channel B, then i changed the sensor switch to C and back to B a few times. this is what happened:

    01 8b fa 78 00 08 5c 27 03 ff
    01 8b fa 71 00 06 00 02 03 ff switch to C
    01 8b fa 78 00 08 75 24 03 00
    01 8b fa 78 00 08 75 24 01 00
    01 8b fa 78 00 08 75 24 00 00 switch to B
    01 8b fa 71 00 06 00 0c 01 00
    01 8b fa 78 00 08 75 23 02 00
    01 8b fa 71 00 06 00 0c 03 00
    01 8b fa 78 00 08 75 23 03 ff
    01 8b fa 71 00 06 00 0c 03 ff switch to C
    01 8b fa 71 00 06 00 0c 03 00
    01 8b fa 71 00 06 00 0c 02 00
    01 8b fa 71 00 06 00 0c 01 00
    01 8b fa 71 00 06 00 0c 00 00 switch to B
    01 8b fa 78 00 08 75 22 01 00
    01 8b fa 71 00 06 00 0c 02 00
    01 8b fa 78 00 08 75 22 03 00
    01 8b fa 71 00 06 00 0c 03 ff

    the value goes from 03 to 00 once the connection is lost. the firmware seems to do some smoothing, because it takes about 60 seconds to go from 03 to 00 and vice versa.

    the last byte shows ff only when a connection is established. i'm guessing that is a battery status indicator for the sensor batteries.

    i'll bet the second and third bytes (8b fa in this case) are the sensor id.

    m

    ReplyDelete
    Replies
    1. Yes, the sensor id is in the first bytes, but I haven't figured out what it it means. Actually, I can't think of a need for it unless you can receive more than one of the stations. The bytes at the end are promising. If the weather head was on my table, I bet we could get the RSSI (signal strength) and the battery level decoded. I may pull it down at some point and experiment with that.

      Good thinking about flipping the switch, I didn't think of that.

      Delete
    2. the sensor id is the lower part of the second byte plus the third byte. for example, from 0x8bfa we get 0xbfa, which is 3066 decimal. so your sensor id is 0x05c, or 92 decimal.

      Delete
    3. I'm feeling a bit dense today. How do you get from 0xbfa to to 0x5c?

      Delete
    4. the communication channel is encoded in the upper half of the second byte.

      channel a: C
      channel b: 8
      channel c: 0

      your station is using channel a. if you change to channel b your second and third bytes will be 80 5c. if you change to channel c your second and third bytes will be 00 5c.

      Delete
    5. an R1 message from my station is:

      01 0b fa 78 00 08 51 23 03 ff

      the 0 in 0b means channel c
      the b fa in 0b fa means serial number 0xbfa or decimal 3066

      you posted an R1 message:

      01 C0 5C 71 00 05 00 0C 03 FF

      the C in C0 means channel a
      the 0 4C in C0 5C means serial number 0x05c or decimal 92

      Delete
  5. another thing to try would be to power the sensors from a variable voltage power supply so you could see whether the battery status is binary or graduated.

    same for the console side of things. if you start with no batteries in the console and the consoled plugged in to AC and usb, then unplug the AC, you can still communicate via usb.

    however, if you start with no power to the console, plug in usb, the console shows up on the bus but you cannot talk to it. this might depend on whether your console defaults to mode 2 or mode 3. a 01036 i tested defaults to mode 2, but a 01035 i tested defaults to mode 3.

    m

    ReplyDelete
  6. Hi
    I can help you with decoding the barometer data
    In exchange for helping me..I was looking for a driver for raspberry pi and OSX for my existing software

    ReplyDelete
    Replies
    1. The usb code is already here. Go back to part one and step forward, the entire description and links to the code are there. I can't do OSX, I don't have a single apple product in the entire house. Nope, no ipods, ipads, iphone, or anything from that company. However, the code is written for linux and uses libusb which has an OSX port, so it shouldn't be any problem.

      Nope, I'm not an apple fan.

      Delete
  7. it looks like george (nincehelser?) figured out the pressure calculation in may 2013. he found that the pressure sensor is the HP03S, and the spec sheet details the calculation required to convert the raw temperature and pressure readings into corrected temperature and pressure. it looks like the last 4 bytes of the R2 message are the temperature and pressure values, and the other bytes are the calibration constants burned into the chip during fabrication. if acurite really does have a patent on this, then one should be able to look it up at the uspto as well.

    george's description is in the comments here:

    http://moderntoil.com/?p=794

    the sensor specs and original maths are here:

    http://www.hoperf.com/upload/sensor/HP03S.pdf

    list of chaney patents, according to chaney:

    http://www.acurite.com/patents

    thanks to this blog and the original 'modern toil' blog, there is now a weewx driver for acurite stations. it should run on macosx too, if you are into that kind of thing ;)

    ReplyDelete
    Replies
    1. Interesting, but not relevant. First, the chip is different which makes everything questionable. This may be totally correct for the ethernet bridge, but the AcuRite console is not the same. Next, nothing is as clear in the output of the acurite console. Go back a couple of posts and you'll see where bits have to be drug out of the data stream and put back together to get anything.

      Patents have never helped me find out how something works, they leave key information out of them.

      Delete
  8. Sounds familier. I asked a few questions there yesterday about my writing a Mac version and my posts were silently removed, and access to several forums was removed.

    Nice.

    ReplyDelete
    Replies
    1. Wow, that's really carrying it a long ways. If he doesn't want people to post, why have a forum?

      Very strange.

      Delete
  9. Thanks for this! I have it running on my pi and posting to weather underground.

    ReplyDelete
    Replies
    1. Congratulations Will. Glad it worked well for you.

      Delete
  10. I've seen a third report type 1


    01 7A 71 00 09 00

    This includes the ORIGINAL byte 0 indicating report type 1 or report type 2. It looks like data byte 0 has disappeared, as have a couple of others. The reading I took immediately before and after were:
    01 C2 7A 71 00 09 00 6C 03 FF
    01 C2 7A 78 00 07 11 37 03 FF

    And as I mentioned in a comment on post 4 (I think) of this series I am getting very different readings on wind speed from a R1 type 1 and R1 type 2, but all of the type 1 speeds are the same for a fairly good length of time, and all of the type 2 speeds are the same for a fairly good length of time, so I don't think it's just wind speed changing. It shouldn't be as consistent as it is if that's the case.

    ReplyDelete
    Replies
    1. Interesting, but beware of short or incomplete packets. On the forum I mentioned in this series, the owner mentions several times that he has to go to great lengths to make sure the packets are reasonable. I haven't seen many problems, but he claims short packets, packets with missing bytes, packets with weird values, etc. Since there isn't any checksum, we can't tell good from bad except by reasonable values. Make sure this isn't what you're getting.

      If you are getting short or malformed data from the thing, try and see how to detect it. We can simply skip bad ones and only pay attention to good ones. Currently I check the lengths and drop them if they are wrong. That may be why I'm not seeing the same thing.

      When the wind picks up, I'll take those checks out and take a look at what I get.

      Delete
  11. I have "ported" your code to python, basically modifying an existing weewx driver file to work with the USB console. I plan to go back and properly comment the code now that it's working and repost it here as well as submitting it to weewx (I saw a comment in an earlier post from a weewx developer, but nothing has made it into the development branch on github). Has any progress been made on the barometer since your comment on part 6 on 2/8 re: the 6.23 * - 20402 formula someone sent in email, and have you heard about anyone decoding the inside temp/humidity from report 2? I ran the numbers from the comment and it looks like -20413 actually gives a better match to the NOAA data in the comment, but it still seems like such an arbitrary formula that my stubborn mind doesn't want to accept it as correct. Even though weewx doesn't send inside temperature or humidity to wunderground it will log it to sqlite or mysql, and I for one think I'd like to have charts for it. No adjacent bytes in report 2 seem to yield a reasonable temperature using the formula you used for outside temperature, and I have to admit that I don't have a gift for pulling data out of unknown byte streams like this.

    ReplyDelete
    Replies
    1. Regarding the formula: Don't make it overly complex. Sure, if we had the correction factors from the chip to work with, then the math would be more complex, but we don't have that. The chip itself is linear in the reading, it's just that it needs to be adjusted to meet reality. The reason for the huge offset is to allow for digits after the decimal point for things like millibars. The reason the slope is weird is because it varies with the material used in the sensor. It's piezoelectric and each cut has unique properties. Normally the manufacturer supplies these values, but we don't get them from the console (at least I and some others don't), so this is the best approximation so far.

      From my experimenting with the formula, it's missing adjustment for altitude. When I adjusted the reading for altitude, it got very, very close and seems to track so far. I haven't started graphing it yet for comparison over a longer term, but I will soon. Altitude is probably why your number meets your area more closely. Take a look at the adjustment necessary to reach the sea-level correction that weather stations normally use; you'll probably find a close correlation.

      No one seems to care about the inside temperature. They can look at their thermostat. I personally don't care because I'm putting thermometers all over the house for that purpose. The only real interest I have in the barometer is mostly academic. I built a compensated barometer in about 20 minutes (after waiting for parts) that tracks the weather stations around me exactly, so the acurite one is just a decoration.

      Now, tell me (A LOT) more about porting it to python. I looked at that and couldn't find a linkage to libusb that I could trust. Did something change in the last couple of months?

      Delete
    2. I just started recording the console barometer along with my fence post barometer up to Xively, I added correction for altitude and now I'll just wait to see what the correlation is over a few days.

      Depending on how this works out, it may be the answer for folk that want to use the console readings. Remember, this is console only, the weather head does not have a barometer in it.

      Delete
    3. For inside temp I am interested in a historical graph (at least over a couple of nights) of what happens when my thermostat shuts off the heater. How long does it take to drop to the lower setting on the thermostat, how long does it take to heat up again when the thermostat changes in the morning (can I start it later than I currently do and still have it comfortable when I wake up) I haven't made the jump from a basic programmable thermostat to a "connected" thermostat yet so the cheapest way (money if not time-wise) to get the data will be from the accurite which, like you, I got from a big box warehouse club. Getting the data into weather underground, and keeping it in a local sql db where I can use very localized information to control a sprinkler system (sprinklerpi maybe) will make this a screamer of a deal, even if I do eventually upgrade to a modular weather station from one of the BIG names at roughly 10x the price.

      weewx uses pyusb (0.4.3), and I basically used what they had for other usb attached drivers. Their find device function is very similar to what you have, iterating through the attached USB devices until finding a match on the mfg & dev id's, the ctrlMsg was actually the most obnoxious part to translate, because the field orders are in a different order, and it's not well documented (at least the 0.4.3 version, 1.0 looks to be much better). The following is actually in different functions with a bunch more code around it. Again I'll post it all when it's properly documented. Because I am pulling both types of reports through a single function and passing the report through a couple of other functions I decided to leave the first byte in there to make sure I know which type of report I have. So my byte numbers should be off from what you used.

      From the openPort function:
      dev = self._findDevice()
      self.devh = dev.open()

      To get the reports:
      # I noticed that the faster I asked the console for a report the more frequently I
      # got back junk. So slow it down. There is probably a better way to ensure an
      # even spread of report 1 sub-types.
      time.sleep(5)
      # Continually loop, retrieving "USB reports". They are 10 or 25 bytes long each.
      if time.mktime(time.localtime()) % 18 < 9:
      report = self.devh.controlMsg(usb.TYPE_CLASS + usb.RECIP_INTERFACE + usb.ENDPOINT_IN, 0x01, 50, 0x01001, 0, 10000)
      else:
      report = self.devh.controlMsg(usb.TYPE_CLASS + usb.RECIP_INTERFACE + usb.ENDPOINT_IN, 0x01, 50, 0x01002, 0, 10000)


      def _R1_type1_packet(self, packet):

      # per desert-home.com there are two types of reports identified by 0x01
      # in the first byte of the report
      # The low order bits of the third byte in the report indicate:
      # 0001 = wind speed, direction (data bytes 3 and 4) & rain counter (data
      byte 6)
      # 1000 = wind speed, temperature and relative humidity
      #
      _record = {'windSpeed' : (((packet[4] & 0x1f) << 3) + ((packet[
      5] & 0x70) >> 4)) / 2.0,
      'windDir' : Hackurite_usb._winddir_dict[(packet[5] & 0x0f )]
      ,
      'totalRain' : (packet[7] & 0x7f) / 100.0,
      'dateTime' : time.mktime(time.localtime()),
      'usUnits' : weewx.US}

      Delete
    4. When you get it the way you want it, email it to me and I'll put together a blog post for it. This should show up in google search for other folk. That's assuming you don't have a blog, if you do, post it there and I'll post a pointer to it for other folk to discover.

      I hate 'secret' stuff from manufacturers and such. I'd buy their weather head in a minute if it had an open interface that was documented on their web site. I bet a ton of other folk would also.

      But, that's just me.

      Delete
  12. I already bought it without checking that first. And it sounds like you did too. :) Although I was considering returning it before I started getting weewx working for it. I know a couple of people who are holding off on buying it until I tell them that it is working reliably and accurately with weewx. Have you considered sending your code to the maintainers of wview? With the weewx support progressing, having the other major linux based weather center software supported would be nice (for others if not for me).

    ReplyDelete
    Replies
    1. Yes, I saw that it had a USB plug on it and that it could send data to the internet. Then, I thought, "How hard could it be?" The rest has been written on the blog. And actually, it really wasn't that hard. If I had known anything at all about USB when I started, it would have been a piece of cake. Also, if I had known the correct terms to feed to Google, I could have saved a ton of time decoding the cotton pickin' data.

      Delete
  13. I just realized how long it's been since I said I would upload my weewx driver for the USB acurite console. Here is the customized portion of weewx.con. Another post will follow with the driver itself. The config file is too big to post to the comments in full.

    [Station]
    # Set to type of station hardware. There must be a corresponding stanza
    # in this file with a 'driver' parameter indicating the driver to be used.
    station_type = Hackurite_usb

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

    [Hackurite_usb]
    # This section is for the weewx Acurite 5-in-1 Pro with USB CONSOLE
    # For the Aculink Bridge try the Hackulink driver from geekfun.com



    # The driver to use:
    driver = weewx.drivers.hackurite_usb

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

    ReplyDelete
  14. def closePort(self):
    try:
    self.devh.releaseInterface()
    except usb.USBError:
    pass
    try:
    self.devh.detachKernelDriver(self.interface)
    except usb.USBError:
    pass

    def genLoopPackets(self):
    """Generator function that continuously returns loop packets"""

    # Get a stream of raw packets, then convert them, depending on the
    # observation type.


    for _packet in self.genPackets():
    try:
    _packet_type = _packet[0] << 8 | (_packet[3] & 0x0f)

    #if ((_packet[0] == 1) and ((_packet[3] & 0x0f) == 1)):
    # _packet_type = '1_1'
    #if ((_packet[0] == '1') and ((_packet[3] & 0x0f) == '8')):
    # _packet_type = '1_2'
    #if (_packet[0] == '2'):
    # _packet_type = '2'
    #else:
    # _packet_type = '1_1'

    if _packet_type in Hackurite_usb._dispatch_dict:
    _record = Hackurite_usb._dispatch_dict[_packet_type](self, _packet)
    if _record is not None:
    yield _record
    except IndexError:
    syslog.syslog(syslog.LOG_ERR, "Hackurite_usb: Malformed packet.
    %s" % str(_packet))
    syslog.syslog(syslog.LOG_ERR, "Hackurite_usb: Packet type: %s" % str(_packet_type))

    def genPackets(self):
    """Generate measurement packets. These are 8 to 17 byte long packets containing
    the raw measurement data.

    """

    # Wrap the byte generator function in GenWithPeek so we
    # can peek at the next byte in the stream. The result, the variable
    # genBytes, will be a generator function.
    genBytes = weeutil.weeutil.GenWithPeek(self._genBytes_raw())

    # Start by throwing away any partial packets:

    #syslog.syslog(syslog.LOG_CRIT, "Hackurite_usb: usb packet: %s " % str(genBytes.peek()))
    buff = genBytes.peek()
    #buff = []
    # March through the bytes generated by the generator function genBytes:
    #for ibyte in genBytes:
    # syslog.syslog(syslog.LOG_CRIT, "Hackurite_usb: usb packet: %s " % str(ibyte))
    # # If both this byte and the next one are 0xff, then we are at the end of a record
    # buff.append(ibyte)
    #syslog.syslog(syslog.LOG_CRIT, "Hackurite_usb: usb packet: %s " % str(buff))
    yield buff

    @property
    def hardware_name(self):
    return self.model

    #===============================================================================
    # USB functions
    #===============================================================================

    def _findDevice(self):
    """Find the given vendor and product IDs on the USB bus"""
    for bus in usb.busses():
    for dev in bus.devices:
    if dev.idVendor == self.vendor_id and dev.idProduct == self.product_id:
    return dev

    ReplyDelete
  15. def _genBytes_raw(self):
    """Generates a sequence of bytes from the USB reports."""

    nerrors=0
    while True:
    try:
    time.sleep(5)
    # Continually loop, retrieving "USB reports". They are 8 bytes long each.
    if time.mktime(time.localtime()) % 18 < 9:
    #if True:
    syslog.syslog(syslog.LOG_DEBUG, "Hackurite_usb: retrieving report 1.")
    report = self.devh.controlMsg(usb.TYPE_CLASS + usb.RECIP_INTERFACE + usb.ENDPOINT_IN, 0x01, 50, 0x01001, 0, 10000)
    else:
    report = self.devh.controlMsg(usb.TYPE_CLASS + usb.RECIP_INTERFACE + usb.ENDPOINT_IN, 0x01, 50, 0x01002, 0, 10000)
    # If this is a report 1 check for type 1 or type 2 Maybe later? in genloop?
    # Throw out too short packets, result of querying too quickly.
    if (len(report)==10 or len(report)==25):
    #for i in range(0, len(report)-1):
    # yield report[i]
    yield report
    nerrors = 0
    except (IndexError, usb.USBError), e:
    syslog.syslog(syslog.LOG_DEBUG, "Hackurite_usb: Bad USB report received.")
    syslog.syslog(syslog.LOG_DEBUG, "***** %s" % e)
    global nerrors
    nerrors += 1
    if nerrors>self.max_tries:
    syslog.syslog(syslog.LOG_ERR, "Hackurite_usb: Max retries exceeded while fetching USB reports")
    raise weewx.RetriesExceeded("Max retries exceeded while fetching USB reports")
    time.sleep(self.wait_before_retry)

    #===============================================================================
    # LOOP packet decoding functions
    #===============================================================================

    def _R1_type1_packet(self, packet):

    # per desert-home.com there are two types of reports identified by 0x01
    # in the first byte of the report
    # The low order bits of the third byte in the report indicate:
    # 0001 = wind speed, direction (data bytes 3 and 4) & rain counter (data byte 6)
    # 1000 = wind speed, temperature and relative humidity
    #
    _record = {'windSpeed' : (((packet[4] & 0x1f) << 3) + ((packet[5] & 0x70) >> 4)) / 2.0,
    'windDir' : Hackurite_usb._winddir_dict[(packet[5] & 0x0f )],
    'totalRain' : (packet[7] & 0x7f) / 100.0,
    'dateTime' : time.mktime(time.localtime()),
    'usUnits' : weewx.US}

    #
    if self.last_totalRain is None:
    _record['rain'] = None
    elif _record['totalRain'] < self.last_totalRain:
    _record['rain'] = ((127-self.last_totalRain)+_record['totalRain'])
    elif _record['totalRain'] > self.last_totalRain:
    _record['rain'] = (_record['totalRain']-self.last_totalRain)
    # If the packet indicates there is no connection to the sensor then we should ignore any values we have derived
    if (packet[8] != 0x03):
    syslog.syslog(syslog.LOG_ERR, "Hackurite_usb: console can't see outdoor sensors %s" % str(packet))
    _record = {'windSpeed' : None, 'windDir' : None, 'totalRain' : None, 'rain' : None, 'dateTime' : time.mktime(time.localtime()), 'usUnits' : weewx.US}
    if _record['totalRain'] is not None:
    self.last_totalRain = _record['totalRain']
    return _record

    ReplyDelete
  16. def _R1_type2_packet(self, packet):
    _record = {'windSpeed' : (((packet[4] & 0x1f) << 3) + ((packet[5] & 0x70) >> 4)) / 2.0,
    'outHumidity' : (packet[7] & 0x7f),
    'dateTime' : time.mktime(time.localtime()),
    'outTemp' :((((packet[5] & 0x0f) << 7) | (packet[6] & 0x7f))-400) / 10.0,
    'usUnits' : weewx.US}
    # Temperature is offset by about 400, and the unit is tenths of degrees
    # This allows simply subtracting 400 to give proper negative degrees (theoretically)

    # If the packet indicates there is no connection to the sensor then we should ignore any values we have derived
    if (packet[8] != 0x03):
    syslog.syslog(syslog.LOG_ERR, "Hackurite_usb: console can't see outdoor sensors %s" % str(packet))
    _record = {'windSpeed' : None, 'windDir' : None, 'totalRain' : None, 'rain' : None, 'dateTime' : time.mktime(time.localtime()), 'usUnits' : weewx.US}

    return _record

    def _R2_packet(self, packet):
    # Attempt to use indoor sensor data for temperature, humidity and pressure
    #
    #_record = {'inTemp' : ((((packet[21] & 0x0f) <<7) + (packet[22] & 0x7f))-400) / 10.0,
    # 'inHumidity' : (packet[23] & 0x7f),
    _record = {'inTemp' : None,
    'inHumidity' : None,
    'dateTime' : time.mktime(time.localtime()),
    'usUnits' : weewx.US}
    # If anybody figures out the barometer in the 02032c with any definity
    # Then we can add code here to integrate it into weewx
    barometer = (6.23 * (packet[23]<<8 | packet[24])) - 21165
    #_record['pressure'] = barometer * 0.000295333727

    return _record


    # Dictionary that maps a measurement code, to a function that can decode it:
    _dispatch_dict = {257: _R1_type1_packet,
    264: _R1_type2_packet,
    512: _R2_packet}

    _winddir_dict = {0: 315, 1: 247.5, 2: 292.5, 3: 270, 4: 337.5, 5: 225, 6: 0, 7: 202.5 , 8: 67.5, 9: 135, 10: 90, 11: 112.5, 12: 45, 13: 157.5, 14: 22.5, 15: 180}

    class Hackurite_usbConfEditor(weewx.drivers.AbstractConfEditor):
    @property
    def default_stanza(self):
    return """
    [Hackurite_usb]
    # This section is for the Acurite USB consoles (02032C and others)

    # The station model, e.g., WMR100, WMR100N, WMRS200
    model = 02032c


    # The driver to use:
    driver = weewx.drivers.Hackurite_usb
    """

    ReplyDelete
  17. And shortly after posting my code I realized that weewx has officially included support for the acurite usb consoles since at least July. Indoor temp included, which I'd never gotten around to.

    ReplyDelete
  18. A couple of questions I have tried to bring this up on my raspi 2 and I am missing something.

    When it runs, i get
    pi@raspi-2 ~/acurite/Desert-Home-RPi/other-things $ ./weatherstation > weather.log
    libusbDebug = 0, noisy = 0
    0424:9514 (bus 1, device 2)
    1d6b:0002 (bus 1, device 1)
    0424:ec00 (bus 1, device 3)
    24c0:0003 (bus 1, device 7)
    Found the one I want
    got the device descriptor back
    I was able to open it
    trying clear halt on endpoint 81 ... [ 0.000000] [00004293] libusbx: error [op_clear_halt] clear_halt failed error -1 errno 16
    ./weatherstation: symbol lookup error: ./weatherstation: undefined symbol: libusb_strerror

    Which makes me think it is using the wrong libusb, but I can not find the conflicting one?
    I compiled by cut and pasting your suggested compile command

    cc -o weatherstation weatherstation.c -L/usr/local/lib -lusb-1.0

    Also Should the monitor be in USB mode 1 or USB mode 2?

    Rich

    ReplyDelete
    Replies
    1. libusb drove me nuts when I was working on this and it took a while to overcome the various problems I ran into. There's been a lot of water under the bridge since then and I simply don't know which one to use of the various changes that have been made. I can only suggest you keep poking around in the libusb code until you get a hint what might have changed.

      As for the USB mode, take a look at the manual and you'll see which mode to use, you want the one that sends data out the usb port. There were a number of weather stations sold that had a bug if you saved the data internally to the console and it would cause problems, so you may not want that setting.

      Mine was one of the bad ones and that was part of my decision to move away from the usb port to reading the RF signal directly. It has worked really well ever since I did that.

      Delete
  19. A couple of questions I have tried to bring this up on my raspi 2 and I am missing something.

    When it runs, i get
    pi@raspi-2 ~/acurite/Desert-Home-RPi/other-things $ ./weatherstation > weather.log
    libusbDebug = 0, noisy = 0
    0424:9514 (bus 1, device 2)
    1d6b:0002 (bus 1, device 1)
    0424:ec00 (bus 1, device 3)
    24c0:0003 (bus 1, device 7)
    Found the one I want
    got the device descriptor back
    I was able to open it
    trying clear halt on endpoint 81 ... [ 0.000000] [00004293] libusbx: error [op_clear_halt] clear_halt failed error -1 errno 16
    ./weatherstation: symbol lookup error: ./weatherstation: undefined symbol: libusb_strerror

    Which makes me think it is using the wrong libusb, but I can not find the conflicting one?
    I compiled by cut and pasting your suggested compile command

    cc -o weatherstation weatherstation.c -L/usr/local/lib -lusb-1.0

    Also Should the monitor be in USB mode 1 or USB mode 2?

    Rich

    ReplyDelete
    Replies
    1. Did you double post by accident? I've done that a few times on blogs.

      Anyway, I cant answer your question on the level of libusb that you need to use, they've changed things a lot in the last few months. You'll have to do some experimenting.

      As I mentioned in my first answer above, the usb mode is described in the manual and a lot of stations will have trouble saving the data internally because of a bug in the console firmware that fills up the device. I have that problem so I use usb mode 4. Mode 4 sends everything out the port and doesn't save it internally. If you want to save it internal to the console, use mode 3, but you might hit the bug and get an error on your display.

      dave

      Delete
    2. I just took a look at their latest operators manual for the console and they've changed things. Take a look at page 6 of the manual at

      https://www.acurite.com/media/manuals/120323-PC-Connect-Instructions.pdf

      This should help you. I'd still use mode 4 though.

      dave

      Delete
    3. Dave, Rich's problem is that if you just use the -L/usr/local/lib -lusb-1.0 command line option, you pick up the /usr/arm-linux-libusb-1.0.so library. To pick up the new library in .usr/local/lib, you must also add /usr/local/lib to the LD_RUN_PATH environment variable during linking. Make sure to export the LD_RUN_PATH variable. There are some other options, check the output of "sudo make install" when installing the libsub library for more details.

      Using the above, I have your code working with the version you used, version 19, and the current version, version 20, of libusb-1.0.

      You can check for missing symbols and which libraries were used with ldd -r weatherstation.

      Hope this helps,
      Glen

      Delete
  20. Thanks Dave, this is awesome work. A buddy & I both got the Costco deal for the AcuRite 5in1 sensors andhavebern looking for a way to stream data to weather underground usung a raspberry pi. I initially bought the AcuRite bridge, but after find your posts I think I'm going to send it back and just read from the panel itself.

    There are some other posts on getting weewx running on a raspberry pi connected to the AcuRite bridge, but I'd rather not fork over another $70 for a glorified single that only updates weather underground every 15 minutes and loses some calculations.

    Awesome job again, I'm going to dive into this very soon.

    ReplyDelete
    Replies
    1. Have fun with it. I stopped using the console because I didn't like the way they did the data delivery. It worked, but I like reading the RF better.

      Delete
  21. Thanks again Dave, I guess I missed the obvious, still very, very new to this. Sorry for the dumb question, but how are you reading the RF without going through the console?

    ReplyDelete
    Replies
    1. Take a look in February of last year (weird talking about last year already), I used a little radio dongle and plugged it into my Pi. I get all five sensors and only had to use my own barometer (yep, built that too) with it.

      I posted my experiences with it and the code is around somewhere if you need it.

      Delete
  22. I thoroughly enjoyed reading your eight posts on this weather station project. You have taken a complex task and presented it in a style a neophyte could follow. I shall return frequently as I endeavor to follow this lead.

    ReplyDelete
    Replies
    1. Glad to have you take a look. Have fun with it.

      Delete
  23. Has anyone tried to get the exe to run on pi with win 10 iot?

    ReplyDelete
    Replies
    1. er, uh, what exe? People have used python on windows and made it work, but I don't know of any other method that has been used.

      Delete
    2. I think he’s asking if the Windows app will run on the pi with Windows IOT

      Delete