Dear friends, 
I'm considering an upgrade to V5 . 
In order to keep my existing weewx 4.1 running whilst working on a fresh V5 
installation I wanted to solve a problem. 
I use a wifi station, an alecto WS-5500 which sends to 
weewx.aslaets.be:8000 , or if you want 192.168.1.55:8000 . 
But I need to have this information sent to my production weewx  AND to my 
weewx being configured.
That is why I wrote this tool I share with you. It can listen, forward to 
an arbitrary list of servers or none and save the data from the wifi 
console to a text file. 
I hope it is helpful for you too. 

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/weewx-user/e2f300ca-a560-4df4-a778-c9616cf80d9dn%40googlegroups.com.
# Ecowitt Proxy Server
# Developed by Alex Slaets
#
# This Python script functions as a proxy server designed to receive HTTP POST requests
# and forward them to one or more specified target servers. It's particularly useful for
# applications like WeeWX where data from weather stations like Ecowitt needs to be
# sent to multiple endpoints for processing and analysis.
# A typical use case would be an upgrade situation where you need to keep running the old weewx installation while configuring new one or to test changes
# #
# The script supports command line arguments for specifying the listening port, target servers,
# and options for verbose output and logging received data to a file. It's designed to be
# easy to use and integrate into existing WeeWX setups, aiding in weather data collection and testing.
# Command Line Arguments:
# -p, --port: Specifies the port on which the server listens (default is 8000).
# -t, --targets: A list of target servers to which the POST requests will be forwarded.
#                This argument is optional; if not provided, the script will only log the received data.
# -v, --verbose: Enables verbose mode, printing the received data to the console.
# -o, --output: Specifies a file to which the received data will be logged. This is useful for analyzing the data.
#
# Example usage:
# python ecowitt_proxy.py -p 8000 -t http://weewx.home:8000 http://weewxdevel.home:8000 -v
# This command will start the server on port 8000, forward data to two target servers, and enable verbose mode.
# python ecowitt_proxy.py -p 8012 -o ~/stationdata.txt  
# this command will listen to a console that transmits to port 8012 on your server and log the data without forwarding


import argparse
import requests
from http.server import BaseHTTPRequestHandler, HTTPServer
import signal

class ProxyHandler(BaseHTTPRequestHandler):
    def __init__(self, target_urls, verbose, output_file, *args, **kwargs):
        self.target_urls = target_urls
        self.verbose = verbose
        self.output_file = output_file
        super().__init__(*args, **kwargs)

    def do_POST(self):
        # Read incoming request
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)

        # Write data to file if asked
        if self.output_file:
            with open(self.output_file, 'ab') as file:
                file.write(post_data)
                file.write(b'\n')  # add a newline

        # process targets and verbose option
        if self.target_urls:
            for url in self.target_urls:
                try:
                    response = requests.post(url, data=post_data)
                    if self.verbose:
                        print(f"Data sent to {url}, status code: {response.status_code}")
                except requests.exceptions.RequestException as e:
                    print(f"Error transmitting to {url}: {e}")
        elif self.verbose:
            print("Received data:", post_data)

        # Send a simpele response back to client
        self.send_response(200)
        self.end_headers()

def run(server_class=HTTPServer, handler_class=ProxyHandler, port=8000, target_urls=None, verbose=False, output_file=None):
    server_address = ('', port)
    handler = lambda *args, **kwargs: handler_class(target_urls, verbose, output_file, *args, **kwargs)

    try: 
        httpd = server_class(server_address, handler)
        print(f"Server listening on port {port}...")
    except  OSError as e:
        print(f"Error: Cannot listen on port {port}. This port may be in use (weewx running on this host?). System error: {e}")
        exit(1)

    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nStopping server ...")
        httpd.server_close()
        print("Server stopped.")

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="HTTP Proxy Server")
    parser.add_argument('-p', '--port', type=int, default=8000, help='Port listening')
    parser.add_argument('-t', '--targets', nargs='*', help='List of urls to forward to')
    parser.add_argument('-v', '--verbose', action='store_true', help='Verbose')
    parser.add_argument('-o', '--output', help='File to store station data')
    args = parser.parse_args()

    run(port=args.port, target_urls=args.targets, verbose=args.verbose, output_file=args.output)

Reply via email to