Shop OBEX P1 Docs P2 Docs Learn Events
[Contest Entry] Real-Time Energy Price HVAC Controller — Parallax Forums

[Contest Entry] Real-Time Energy Price HVAC Controller

R PankauR Pankau Posts: 127
edited 2010-12-12 14:36 in Accessories
My plan is to use the 5100 as an HTTP client to get real-time electrical rates from my electric supplier. With this data I can allow the spinneret to raise or lower the temperature setpoint in my home. The threshold values (temperature vs prices) hopefully will come from a web page served by the 5100 on a form.

As a bonus the spinneret could control multiple relays for controlling things like a dehumidifier for instance. No need to run it during the day when electricity is expensive, it could do all of the dehumidifying necessary in the wee hours of the morning when a kwh is usually less than $0.02

Comments

  • R PankauR Pankau Posts: 127
    edited 2010-12-04 20:36
    I'm trying to devote some time to this, usually comes in bursts.
    My most recent brick wall was in the form of not being able to retrieve more than 8K of web page after issuing an HTTP GET request to a web server. As luck would have it the data I really need is somewhere past where the 5100's memory ends.

    It would be really great if there were a way to retrieve the remaining portion of the web page with a subsequent GET request. When I see this on page 5 of the 5100 datasheet it worries me. "Not support IP Fragmentation" I assume that is a show stopper.
    The HTTP syntax is relatively new to me so this may be a dumb question. Can I somehow issue the GET specifying where to start sending data? ie someplace not zero but more like byte 7,500 of the web page.

    I've toyed with the idea of renting server space (probably can be had for free) and writing some python maybe to get the small amount of data that I really need and make it available via another very small web page that the spinneret could then query in full. This is new territory to me also.

    thanks.
  • kuismakuisma Posts: 134
    edited 2010-12-05 00:16
    You do not need IP fragmentation to send a HTTP page larger then 8k. TCP is stream oriented, and you transmit an arbitrary sized page by issuing several consecutive transmits. There is no relation between network packet size and HTML page size.
  • GadgetmanGadgetman Posts: 2,436
    edited 2010-12-05 12:24
    kuisma wrote: »
    You do not need IP fragmentation to send a HTTP page larger then 8k.
    He's trying to RECEIVE a large packet.

    Have you checked if they have a 'minimal' interface for smartphones and the likes?
    Possibly even some sort of IRC system?
  • kuismakuisma Posts: 134
    edited 2010-12-05 13:07
    Gadgetman wrote: »
    He's trying to RECEIVE a large packet.

    Does not matter, same mechanisms. IP fragmentation is something completely different and got nothing to do with this. To avoid receive buffer overflow, TCP uses window size, forcing the sender to pause transmission until the receiver has processed its input queue. All this is handled by the TCP stack itself.
  • R PankauR Pankau Posts: 127
    edited 2010-12-05 17:14
    Ok so IP fragmentation hasn't anything to do with my 8K receive limit. Is there any way to limit what the servers sends back? for instance can I specify in my GET request that I'd like to have only the text and none of the Java? that may reduce the size a bit.

    I've checked a little into a smaller page for phones etc.. but have not really found anything. Our System operator MISO, Midwest Independent System Operator does this very well with a small xml page but I believe it is only for the commercial and industrial producers or large users. I have not been able to find the consumer price on that page.

    Here is where my consumer price is displayed
    http://www.powersmartpricing.org/

    Vs the place for showing the prices for each node at the source.
    http://www.midwestiso.org/page/LMP+Contour+Map+%28EOR%29
  • R PankauR Pankau Posts: 127
    edited 2010-12-05 17:42
    I may have overlooked a gold mine here.
    https://www2.ameren.com/RetailEnergy/rtpDownload.aspx?Company=19&Date=12/05/2010&ptype=D


    Not sure how this works. Seems like I thought about this once but the Download button is part of a POST command I'm guessing. So If I have to post back the entire page I'm out of luck because it's 56K in size.

    I wonder if I can just request the CSV page directly without all of the web pages? Is that a normal function of a web server? If I know the name of a file like this csv in which the name has the date embedded, then should I be able to request it from the server? Is that a GET request?
  • R PankauR Pankau Posts: 127
    edited 2010-12-05 17:48
    It's all coming back to me now. the link to the csv is on a secure page.
    What are the odds that I'm going to be able to request the csv with the 5100?
  • kuismakuisma Posts: 134
    edited 2010-12-05 23:22
    R Pankau wrote: »
    Ok so IP fragmentation hasn't anything to do with my 8K receive limit. Is there any way to limit what the servers sends back?

    Simple, you do not have any 8kb receive limit at all. :-)

    The 8kb buffer, means that after the sender has given you 8kb of data, you have to remove it from the 5100 before the sender delivers you the rest of the data you ordered. The 5100 continuously tells the sender the amount of space left in its receive buffer (via "TCP window size"), and you do not have to bother with this unless you are implementing your own TCP stack.

    The 8kb buffer size will only limit the performance, not the size of the data your are able to handle. In theory, you could send TCP data byte by byte, but it would be terrible inefficient, but still able to deliver gigabytes.

    You are describing a non existent problem. If you do not get it to work, there is something else you have overlooked.
  • kuismakuisma Posts: 134
    edited 2010-12-05 23:39
    I.e. if your first rxTCP() didn't deliver you enough, wait a short while and do another rxTCP() and you will get the rest, etc.
  • R PankauR Pankau Posts: 127
    edited 2010-12-07 09:08
    It is true that I'm only doing the RxTCP once. I'll investigate further... I know there is a value I'm reading from the 5100 that indicated the amount of data remaining in the buffer. I display it after the RxTCP completes and send it out via serial for debugging. It has been > 0 on occasion. I just assumed that I did not understand what that value meant. I guess I didn't . I should have read more from the 5100.

    Thanks, I'll let you know what happens...
  • R PankauR Pankau Posts: 127
    edited 2010-12-08 19:41
    I'm trying things out and so far not much luck.
    I created a second buffer in the prop for testing thinking that maybe it was taking too long to clear the contents of the first go-round before calling rxTCP (rxdata2 here) but I get to the same stopping point after the first rxTCP call and then never get more data after that.

    sock 0 status starts out as 0x17 in the repeat loop and then it eventually times out to 0x1C without giving me any more of the web page.

    ETHERNET.rxTCP(0, @rxdata) 'copy 5100 received data to prop
    PST.str(string("First Data in Buffer"))
    PST.Str(@rxdata)

    repeat
    ETHERNET.readSPI(ETHERNET#_S0_SR, @sock_0_status, 1)
    PST.str(string("Socket Zero Status Reg = "))
    PST.hex(sock_0_status,2)
    ETHERNET.rxTCP(0, @rxdata2) 'copy 5100 received data to prop 2nd time
    PST.Str(string(PST#NL))
    PST.str(string("Second Data in Buffer"))
    PST.Str(@rxdata2)
    bytefill (@rxdata2, 0, _bytebuffersize) 'clear prop buffer
    while (sock_0_status <> $1D) or (sock_0_status <> $1C)
  • R PankauR Pankau Posts: 127
    edited 2010-12-08 20:02
    Actually upon closer inspection there is some data coming in depending on which web site I try to get. However there appears to be missing data in the middle. I get one big contiguous chunk of data but the next chunks that arrive are not necessarily next in line on the page.
  • R PankauR Pankau Posts: 127
    edited 2010-12-08 20:25
    Found this on the Object Exchange for the 5100 SPI driver

    Known problems:
    *When using UDP, there are buffer problems on packets over 1472 bytes. Under investigation. This problem may also exist when using TCP.

    The data sheet is poorly written if you ask me, for the 5100 that is. I've been heavily relying upon the supplied driver because the 5100 datasheet was not user friendly. Maybe Timothy D. Swieter found this to be true also.

    Generating the proper address for received data is a real circus , I am looking at page 51 of the manual "receiving process" Maybe I should try to understand this.
  • Roy ElthamRoy Eltham Posts: 2,996
    edited 2010-12-08 21:48
    Ethernet packets (or frames) are typically not going to be larger than 1500 bytes total (the protocol headers take up some of that space so your actual maximum payload will always be smaller). They call this maximum size the MTU (maximum transmission unit). Here's a link explaining MTU: http://en.wikipedia.org/wiki/Maximum_transmission_unit

    So when you send data over Ethernet using IP protocols and it's larger than the MTU, then it will be broken up into smaller chunks. Your receiving code needs to put the payloads back together to get the full data.

    If you use TCP, then the packets you send/receive are guarranteed to be delivered in order. This is the easiest method for transmitting data between clients and servers.

    If you use UDP, then you may get packets out of order, and you may not even get all of the packets. It's up to you to put something into the packets to indicate order, and to detect when a packet is not received and resend (usually done with ack packets). It's better to just use TCP for things like transfering files or large chunks of data. UDP is usually used for small packets of data that can tolerate being out of order and sometimes not actually make it through the wire.

    Anyway, you are trying to use HTTP to get data, and it's likely that you just need to implement a little bit more of the HTTP protocol to get your stuff working. The headers can tell you more information about how the data is being transmitted. It may be in chunked format, which means you need to handle that. There are other things that can factor in also. Here is a link to a site that helped me get my HTTP demo working: http://www.jmarshall.com/easy/http/

    Hope this helped. :)
  • R PankauR Pankau Posts: 127
    edited 2010-12-09 11:50
    Since the receiving process is TCP my assumption is that the server is sending things in order. Or at least the 5100 is re-ordering upon reception. The data that I've been able to offload from the 5100 technically has been in order, albiet with missing chunks. Just as a wild guess it's sort of like while the prop is transferring the 7000 plus bytes of the first receive the 5100 is either receiving more data but I've lost track of where that data is OR the 5100 is just plain failing to receive some chunks of data.

    With TCP handshaking etc... I would think that if packets were lost the server and 5100 would work it out by retransmitting.

    The HTTP protocol has things like "keep alive" etc... that I'm not too familiar with.

    Haven't ruled anything out yet.
  • kuismakuisma Posts: 134
    edited 2010-12-09 15:18
    R Pankau,

    I was going to tell you to look at the TCP Echo server code in OBEX about how you iterate rxTCP to receive the stream in whole, but when checking, I found the W5100 Indirect Driver 00.6 was quite buggy and didn't handle it well at all. So I fixed it.

    Download the driver attached to this post, and look at the TCP Server Echo demo to see how to do it.
  • R PankauR Pankau Posts: 127
    edited 2010-12-09 17:21
    Cool, thanks, I'll take a look.
  • R PankauR Pankau Posts: 127
    edited 2010-12-09 18:06
    Here is what I did.
    I was unable to actually use the fixed driver since my prototype is a prop proto board wire wrapped to a wiz811mj. I wrapped the SPI connection, it was much easier that way.

    However I did use this
    repeat until RX_size := ETHERNET.rxTCP(0, @rxdata[0])
    ifnot ETHERNET.SocketTCPestablished(0)
    quit
    At first I found that the issue was that every time through the loop it appeared to grab the first part of the web page and spit it out again. So then I thought maybe I should not have increased the size of the receive buffer to 8K, One because it is not really necessary, and two the drivers assume the defaults.. so switching back to a normal 2K buffer (leaving _RMSR alone that is) it magically began working.

    Just received 8814 bytes of success from a single web page.
    Going into this fairly blind, the input buffer at 8K was actually a killer.

    The driver in use is Brilldea_W5100_SPI_Driver_Ver005.spin, now I'm wondering if there is a bug in this that I should address?

    Thanks for the help
  • kuismakuisma Posts: 134
    edited 2010-12-09 23:11
    Here is the updated version of the SPI driver as well.

    Bug fixes:
    - rxTCP return value may contain garbage.
    - txTCP will deadlock if trying to send too much data at one and the same invocation.

    R Pankau, keep in mind that TCP is stream oriented. No need fiddling around with buffer sizes and such, unless you know exactly what you are doing. But I guess you know that by now. :) Buffers, MTUs, IP packets, fragmentation etc are all handled by the lower lever drivers, thats why you are using TCP in the first place. As an application level programmer, all you see is a stream of data you pick and put your data from/to.

    This also implies rxTCP may only return parts of what you are considering "all" your data. If you want 500 bytes from a web server, it is up to you to iterate rxTCP until you get all you need. There is no guarantee that you get everything at the first call, not even if the data is small enough to fit in one IP datagram. It is perfectly possible rxTCP only returns one byte at a time, however unlikely.
  • R PankauR Pankau Posts: 127
    edited 2010-12-10 09:48
    All good info thanks. So the moral of the story is that originally my thinking was flawed in two main areas.
    1. thinking that the 5100 receive buffer size needed to be as big as the total data to receive.
    2. thus not realizing that repeated requests for more data would yield more data until the connection was closed by the server.

    Maybe this not worth a large discussion but when I changed the buffer size to 8K either I did not do it properly or the rxTCP routine was not able to handle the increase in buffer size. as the data I was receiving appeared to be a lot of repeated data from the beginning of the HTTP stream. Now I see no good reason to change the buffer size of course.
  • kuismakuisma Posts: 134
    edited 2010-12-10 10:24
    R Pankau wrote: »
    2. thus not realizing that repeated requests for more data would yield more data until the connection was closed by the server.

    Actually, you can not rely on a connection close neither. In HTTP, you have to check the "content-length" to know how much you are expecting, and other application protocols use similar mechanisms. HTTP/1.0 usually closes, but HTTP/1.1 may keep the connection open for reuse.
    R Pankau wrote: »
    Maybe this not worth a large discussion but when I changed the buffer size to 8K either I did not do it properly or the rxTCP routine was not able to handle the increase in buffer size. as the data I was receiving appeared to be a lot of repeated data from the beginning of the HTTP stream. Now I see no good reason to change the buffer size of course.

    The ethernet driver may require some work before perfection, but when you start changing the hardware parameters, it is up to you to do that work. :lol:
  • kuismakuisma Posts: 134
    edited 2010-12-10 10:35
    R Pankau wrote: »
    1. thinking that the 5100 receive buffer size needed to be as big as the total data to receive.

    This has nothing to do with the W5100, but with TCP. A TCP stream is infinite long, and you can never except to buffer it all, all the times. You always access TCP via a window into the stream.
  • R PankauR Pankau Posts: 127
    edited 2010-12-11 21:24
    Actually, you can not rely on a connection close neither. In HTTP, you have to check the "content-length" to know how much you are expecting,

    Should I expect to see this "content length" in the response? As far as I know the TCP headers are hidden but what shows up visible to the application is the HTTP header and there does not appear to be any length.

    The reason I ask is to know when to disconnect the socket. Would it suffice to keep checking for more data received, and if it returns zero for a specified time then disconnect? These are HTTP etiquette questions for which I should probably read up on.

    Actually looking back on this thread, this was suggested and appears to be very helpful on the topic
    http://www.jmarshall.com/easy/http/
    maybe the Header, Content-Length:, is optional. I don't see it from my particular web site.
  • kuismakuisma Posts: 134
    edited 2010-12-12 01:20
    R Pankau wrote: »
    Should I expect to see this "content length" in the response?

    If your request results in a message body, there should be a "Content-length".

    See http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 for HTTP/1.1 details.

    For HTTP/1.0, if there is no content-length field, you can determine content length by the server closing the TCP session.

    http://ftp.ics.uci.edu/pub/ietf/http/rfc1945.html#BodyLength
  • Mike GMike G Posts: 2,702
    edited 2010-12-12 08:28
    FYI, the page can contain many linked files. Each request requires its own header. For example, a web page might link to an image, css, and javascript file. Each is a request with headers which come down as part of the stream.

    The header takes up a certain number of bytes. The header length is not calculated in the "content-length:" line but the header is part of the transaction. A transaction is complete when the server closes the socket after serving up the requested resource(s).
  • R PankauR Pankau Posts: 127
    edited 2010-12-12 13:43
    so it would be a good practice to wait for the server to disconnect right? I'm assuming that the server cannot really close the socket but the application would do that after the connection was closed.
  • Mike GMike G Posts: 2,702
    edited 2010-12-12 14:36
    A web server invokes an asynchronous service to handle the request but continues to listen. Eventually the conversation is completed and the server has to free up the resource for use by another client request.
Sign In or Register to comment.