Created
December 10, 2012 22:52
-
-
Save mangrovemike/4254071 to your computer and use it in GitHub Desktop.
XTIDE to MQTT Bridge
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/python | |
| # | |
| # MangroveMike (www.merewether.com.au) | |
| # | |
| # Get tides, moonrise, moonset, sunrise and sut set from XTIDE and publish to local MQTT server. | |
| # We publish when the actual event occurs to the /now/ topic and the next 6 hours worth of activity to the /future/ topic. | |
| # | |
| # 10/12/2012 Initially created. | |
| # | |
| # | |
| # Subscribe output looks similar to: | |
| # astronomy/harrington_inlet/future/low_tide 0.35 m | |
| # astronomy/harrington_inlet/future/low_tide/time 2012-12-11 13:56 | |
| # astronomy/merewether/future/low_tide 0.26 m | |
| # astronomy/merewether/future/low_tide/time 2012-12-11 13:38 | |
| import time | |
| import mosquitto | |
| import subprocess | |
| import sys | |
| import csv | |
| import re | |
| import string | |
| # Global Definitions | |
| gtideprog = "/usr/local/bin/tide" | |
| gtideargs = ' -fc -df"%Y-%m-%d" -tf"%H:%M"' | |
| # | |
| # MQTT Callbacks | |
| # | |
| ticks = time.time(); | |
| mqttc = mosquitto.Mosquitto("python_pub_local_tides" + str(ticks)) | |
| def on_connect(mosq, obj, rc): | |
| if rc ==0: | |
| print("Connect local rc: "+str(rc)) | |
| else: | |
| raise Exception | |
| def on_message(mosq, obj, msg): | |
| print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) | |
| def on_publish(mosq, obj, mid): | |
| print("mid: "+str(mid)) | |
| localtime = time.asctime( time.localtime(time.time()) ) | |
| print "Local current time :", localtime | |
| def on_subscribe(mosq, obj, mid, granted_qos): | |
| print("Subscribed: "+str(mid)+" "+str(granted_qos)) | |
| def on_log(mosq, obj, level, string): | |
| print(string) | |
| def on_disconnect (mosq, obj, rc): | |
| if rc == 0: | |
| print("Disconnected local successfully.") | |
| else: | |
| print("Disconnected local unexpectantly. Result code: "+str(rc)) | |
| # | |
| # General Program Modules | |
| # | |
| def cleanup(): | |
| print "Ending and cleaning up" | |
| mqttc.disconnect() | |
| def delete_file(filename): | |
| try: | |
| retcode = subprocess.call("rm -f " + filename, shell=True) | |
| if retcode < 0: | |
| print >>sys.stderr, "Child was terminated by signal", -retcode | |
| else: | |
| print >>sys.stderr, "Child returned", retcode | |
| except OSError as e: | |
| print >>sys.stderr, "Execution failed:", e | |
| def generate_tide(tlocation, toutfile, tstarttime, tendtime): | |
| location = '"' + tlocation + '"' | |
| starttime = '"' + tstarttime + '"' | |
| endtime = '"' + tendtime + '"' | |
| try: | |
| delete_file(toutfile) | |
| tcommand = gtideprog + gtideargs + " -l" + location + " -b" + starttime + " -e" + endtime + " -o" + toutfile | |
| print tcommand | |
| retcode = subprocess.call(tcommand, shell=True) | |
| if retcode < 0: | |
| print >>sys.stderr, "Child was terminated by signal", -retcode | |
| else: | |
| print >>sys.stderr, "Child returned", retcode | |
| except OSError as e: | |
| print >>sys.stderr, "Execution failed:", e | |
| def process_and_publish(voutfile, vlocation_simple, vmode): | |
| # Read the CSV | |
| csvfile = csv.reader( open(voutfile, 'rb'), delimiter=',', quotechar='"') | |
| for row in csvfile: | |
| tdate = row[1] | |
| ttime = row[1] + " " + row[2] | |
| tcommand = re.sub(" ","_",string.lower(row[4])) | |
| tvalue = row[3] | |
| print "Date:" + tdate + " Time:" + ttime + " Command:" + tcommand + " Value:" +tvalue | |
| # Now publish the data | |
| if tcommand == "high_tide" or tcommand == "low_tide": | |
| mqttValue = tvalue | |
| else: | |
| mqttValue = ttime | |
| # Publish | |
| mqttc.publish("astronomy/" + vlocation_simple + "/" + vmode + "/" + tcommand, mqttValue) | |
| mqttc.publish("astronomy/" + vlocation_simple + "/" + vmode + "/" + tcommand + "/time" , ttime) | |
| # mqttc.disconnect() | |
| def connectAndSetupLocal(): | |
| mqttc.on_message = on_message | |
| mqttc.on_connect = on_connect | |
| mqttc.on_publish = on_publish | |
| mqttc.on_subscribe = on_subscribe | |
| # Uncomment to enable debug messages | |
| mqttc.on_log = on_log | |
| mqttc.connect("127.0.0.1", 1883, 60) | |
| # This gets very cool system stats | |
| # mqttc.subscribe("$SYS/#", 0) | |
| # mqttc.subscribe("#", 0) | |
| def main_processing(): | |
| vdate = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time())) | |
| vdate2mins = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()+(2*60))) | |
| vdate6hrs = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()+(6*60*60))) | |
| # vdate1hr2mins = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()+(62*60))) | |
| print "Vdate :", vdate | |
| print "Vdate2mins :", vdate2mins | |
| print "Vdate6hrs :", vdate6hrs | |
| # Generate tide files | |
| outfile = "/usr/local/scripts/tides/harrington_tides_now.csv" | |
| generate_tide("Harrington Inlet, Australia",outfile, vdate, vdate2mins) | |
| process_and_publish(outfile, "harrington_inlet", "now") | |
| # Generate tide files for next 6 hours | |
| outfile = "/usr/local/scripts/tides/harrington_tides_future.csv" | |
| generate_tide("Harrington Inlet, Australia",outfile, vdate2mins, vdate6hrs) | |
| process_and_publish(outfile, "harrington_inlet", "future") | |
| # Generate tide files | |
| outfile = "/usr/local/scripts/tides/merewether_tides_now.csv" | |
| generate_tide("Newcastle, Australia",outfile, vdate, vdate2mins) | |
| process_and_publish(outfile, "merewether", "now") | |
| # Generate tide files for next 6 hours | |
| outfile = "/usr/local/scripts/tides/merewether_tides_future.csv" | |
| generate_tide("Newcastle, Australia",outfile, vdate2mins, vdate6hrs) | |
| process_and_publish(outfile, "merewether", "future") | |
| def mainloop(): | |
| try: | |
| rc = 0 | |
| while rc == 0: | |
| rc = mqttc.loop() | |
| main_processing() | |
| time.sleep(60) | |
| except (KeyboardInterrupt): | |
| print "Keyboard Interrupt received" | |
| cleanup() | |
| raise | |
| except (RuntimeError): | |
| print "The candle that burns twice as bring only burns half as long. " | |
| cleanup() | |
| raise | |
| except: | |
| print "Unexpected error in mainloop(). Result code 1 is "+str(rc) | |
| raise | |
| localtime = time.asctime( time.localtime(time.time()) ) | |
| print "Local current time :", localtime | |
| print(re.sub(" ","_","Low Tide")) | |
| connectAndSetupLocal() | |
| mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment