Moved Docker stuff to "Docker" folder
Created k8s folder for k8s stuff Added early-stage service.yaml for K8s deployment
This commit is contained in:
18
Docker/src/bin/acurite-redirect.sh
Executable file
18
Docker/src/bin/acurite-redirect.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script configures the eb/ip tables rules to redirect traffic
|
||||
# from the bridge to a different port on the local machine. It gets
|
||||
# run by adding this line to /etc/network/interfaces
|
||||
#
|
||||
# pre-up /home/ted/proj/tHome/bin/acurite-redirect.sh
|
||||
#
|
||||
|
||||
# Redirect traffic on the bridge to port 22041 which must match the port
|
||||
# specified in tHome/conf/acurite.py.
|
||||
PORT=22041
|
||||
|
||||
# Tell the bridge to push the packet to iptables.
|
||||
ebtables -t broute -A BROUTING -p IPv4 --ip-protocol 6 --ip-destination-port 80 -j redirect --redirect-target ACCEPT
|
||||
|
||||
# Redirect the packet to the other port.
|
||||
iptables -t nat -A PREROUTING -i br0 -p tcp --dport 80 -j REDIRECT --to-port $PORT
|
||||
65
Docker/src/bin/dbg-msgHub.py
Executable file
65
Docker/src/bin/dbg-msgHub.py
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# dbg-msgHub.py -s "radio" "power/battery"
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import pprint
|
||||
import time
|
||||
import StringIO
|
||||
import tHome.util as util
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
p = argparse.ArgumentParser( prog=sys.argv[0],
|
||||
description="Msg Hub debug output" )
|
||||
p.add_argument( "-p", "--port", type=int, default=1883,
|
||||
help="Broker port number to connect to." )
|
||||
p.add_argument( "-b", "--broker", type=str, default='127.0.0.1',
|
||||
help="Broker host name to connect to." )
|
||||
p.add_argument( "-s", "--skip", nargs="*", default=[] )
|
||||
c = p.parse_args( sys.argv[1:] )
|
||||
|
||||
class Client ( mqtt.Client ):
|
||||
def __init__( self ):
|
||||
mqtt.Client.__init__( self )
|
||||
# Restore callbacks overwritten by stupid mqtt library
|
||||
self.on_connect = Client.on_connect
|
||||
self.on_message = Client.on_message
|
||||
|
||||
def on_connect( self, userData, flags, rc ):
|
||||
self.subscribe( '#' )
|
||||
|
||||
def on_message( self, userData, msg ):
|
||||
for k in c.skip:
|
||||
if msg.topic.startswith( k ):
|
||||
return
|
||||
|
||||
data = util.json.loads( msg.payload )
|
||||
s = StringIO.StringIO()
|
||||
|
||||
t = time.time()
|
||||
dt = t - data['time']
|
||||
s.write( "dt: %d " % dt )
|
||||
|
||||
keys = data.keys()
|
||||
keys.remove( 'time' )
|
||||
for k in sorted( keys ):
|
||||
s.write( "%s: %s " % ( k, data[k] ) )
|
||||
|
||||
print "Recv time: %.0f %-30s %s" % ( t, msg.topic, s.getvalue() )
|
||||
#pprint.pprint( data )
|
||||
#print data
|
||||
|
||||
|
||||
print "Connecting to %s:%d" % ( c.broker, c.port )
|
||||
client = Client()
|
||||
client.connect( c.broker, c.port )
|
||||
|
||||
# loop_forever() and loop() block ctrl-c signals so it's hard to stop.
|
||||
# So start in a thread so we can ctrl-c out of this.
|
||||
client.loop_start()
|
||||
|
||||
while True:
|
||||
pass
|
||||
|
||||
client.loop_stop( force=True )
|
||||
90
Docker/src/bin/tHome-acurite.py
Executable file
90
Docker/src/bin/tHome-acurite.py
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#===========================================================================
|
||||
#
|
||||
# Eagle posting server
|
||||
#
|
||||
#===========================================================================
|
||||
|
||||
__doc__ = """
|
||||
Starts a small web server to read packets sent from an Acurite Bridgek.
|
||||
|
||||
The Acurite must be redirected to post messages to server instead of
|
||||
it's main server. This assumes the Bridge is connected to a raspberry
|
||||
pi using a USB network adaptor with it's network bridged to the main
|
||||
network. NOTE: The last port number in the iptables command must
|
||||
match the port configured in conf/acurite.py for the acurite web
|
||||
server.
|
||||
|
||||
ebtables -t broute -A BROUTING -p IPv4 --ip-protocol 6 --ip-destination-port 80 -j redirect --redirect-target ACCEPT
|
||||
iptables -t nat -A PREROUTING -i br0 -p tcp --dport 80 -j REDIRECT --to-port 22041
|
||||
|
||||
Scripts uses the tHome.acurite package to decode the bridge posts and
|
||||
converts them to JSON dictionaries which get sent out as MQTT
|
||||
messages.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import bottle as B
|
||||
import sys
|
||||
import json
|
||||
import tHome as T
|
||||
|
||||
#===========================================================================
|
||||
@B.post( '/' )
|
||||
@B.post( '/messages/' )
|
||||
def bridge_post():
|
||||
content = B.request.body.read( B.request.content_length )
|
||||
|
||||
log.info( "Read: %s" % content )
|
||||
|
||||
# Convert the line to messages. Returns a list of tuples of
|
||||
# ( topic, dict ).
|
||||
msgs = T.acurite.cmdLine.process( cfg, content, sensorMap )
|
||||
|
||||
# Send the messages out.
|
||||
for topic, data in msgs:
|
||||
log.info( "Publish: %s: %s" % ( topic, data ) )
|
||||
|
||||
payload = json.dumps( data )
|
||||
client.publish( topic, payload )
|
||||
|
||||
# Standard acurite web site reply - found by watching traffic to
|
||||
# the acurite web site.
|
||||
return { "success" : 1, "checkversion" : "126" }
|
||||
|
||||
#===========================================================================
|
||||
#
|
||||
# Main applications script
|
||||
#
|
||||
#===========================================================================
|
||||
|
||||
p = argparse.ArgumentParser( prog=sys.argv[0],
|
||||
description="T-Home Acurite Server" )
|
||||
p.add_argument( "-c", "--configDir", metavar="configDir",
|
||||
default="/etc/tHome",
|
||||
help="Configuration file directory." )
|
||||
p.add_argument( "-l", "--log", metavar="logFile",
|
||||
default=None, help="Logging file to use. Input 'stdout' "
|
||||
"to log to the screen." )
|
||||
c = p.parse_args( sys.argv[1:] )
|
||||
|
||||
# Parse the eagle config file.
|
||||
cfg = T.acurite.config.parse( c.configDir )
|
||||
log = T.acurite.config.log( cfg, c.log )
|
||||
|
||||
# Create a sensor map from the configuration file.
|
||||
sensorMap = {}
|
||||
for s in cfg.sensors:
|
||||
sensorMap[s.id] = s
|
||||
|
||||
# Create the MQTT client and connect it to the broker.
|
||||
client = T.broker.connect( c.configDir, log )
|
||||
|
||||
# Start the MQTT as a background thread. This way we can run the web
|
||||
# server as the main thread here.
|
||||
client.loop_start()
|
||||
|
||||
log.info( "Starting web server at port %d" % cfg.httpPort )
|
||||
B.run( host='0.0.0.0', port=cfg.httpPort, quiet=True )
|
||||
|
||||
112
Docker/src/bin/tHome-eagle.py
Executable file
112
Docker/src/bin/tHome-eagle.py
Executable file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#===========================================================================
|
||||
#
|
||||
# Eagle posting server
|
||||
#
|
||||
#===========================================================================
|
||||
|
||||
__doc__ = """
|
||||
Starts a small web server. The Rain Forest Eagle is configured with
|
||||
this web server as it's 'cloud' provider so it posts messages to the
|
||||
server as XML data packets.
|
||||
|
||||
Scripts uses the tHome.eagle package to decode the XML packets and
|
||||
converts them to JSON dictionaries which get sent out as MQTT
|
||||
messages.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import bottle as B
|
||||
import sys
|
||||
import json
|
||||
import tHome as T
|
||||
|
||||
#===========================================================================
|
||||
def meter( client, data, cfg ):
|
||||
msg = {
|
||||
"time" : data.TimeUnix,
|
||||
"consumed" : data.Consumed, # kWh
|
||||
"produced" : data.Produced, # kWh
|
||||
}
|
||||
|
||||
return ( cfg.mqttEnergy, msg )
|
||||
|
||||
#===========================================================================
|
||||
def instant( client, data, cfg ):
|
||||
msg = {
|
||||
"time" : data.TimeUnix,
|
||||
"power" : data.Power * 1000, # W
|
||||
}
|
||||
|
||||
return ( cfg.mqttPower, msg )
|
||||
|
||||
#===========================================================================
|
||||
handlers = {
|
||||
#"BlockPriceDetail" :
|
||||
"CurrentSummation" : meter,
|
||||
#"DeviceInfo" :
|
||||
#"FastPollStatus" :
|
||||
"InstantaneousDemand" : instant,
|
||||
#"MessageCluster" :
|
||||
#"MeterInfo" :
|
||||
#"NetworkInfo" :
|
||||
#"PriceCluster" :
|
||||
#"Reading" :
|
||||
#"ScheduleInfo" :
|
||||
#"TimeCluster" :
|
||||
}
|
||||
|
||||
#===========================================================================
|
||||
|
||||
@B.post( '/' )
|
||||
def root_post():
|
||||
data = B.request.body.read( B.request.content_length )
|
||||
try:
|
||||
obj = T.eagle.parse( data )
|
||||
except:
|
||||
log.exception( "Error parsing Eagle posted data" )
|
||||
return "ERROR"
|
||||
|
||||
log.info( "Read packet: %s" % obj.name )
|
||||
|
||||
func = handlers.get( obj.name, None )
|
||||
if func:
|
||||
topic, msg = func( client, obj, cfg )
|
||||
if msg:
|
||||
log.info( "Publish: %s: %s" % ( topic, msg ) )
|
||||
|
||||
payload = json.dumps( msg )
|
||||
client.publish( topic, payload )
|
||||
|
||||
return "ok"
|
||||
|
||||
#===========================================================================
|
||||
#
|
||||
# Main applications script
|
||||
#
|
||||
#===========================================================================
|
||||
|
||||
p = argparse.ArgumentParser( prog=sys.argv[0],
|
||||
description="T-Home Eagle Server" )
|
||||
p.add_argument( "-c", "--configDir", metavar="configDir",
|
||||
default="/etc/tHome",
|
||||
help="Configuration file directory." )
|
||||
p.add_argument( "-l", "--log", metavar="logFile",
|
||||
default=None, help="Logging file to use. Input 'stdout' "
|
||||
"to log to the screen." )
|
||||
c = p.parse_args( sys.argv[1:] )
|
||||
|
||||
# Parse the eagle config file.
|
||||
cfg = T.eagle.config.parse( c.configDir )
|
||||
log = T.eagle.config.log( cfg, c.log )
|
||||
|
||||
# Create the MQTT client and connect it to the broker.
|
||||
client = T.broker.connect( c.configDir, log )
|
||||
|
||||
# Start the MQTT as a background thread. This way we can run the web
|
||||
# server as the main thread here.
|
||||
client.loop_start()
|
||||
|
||||
log.info( "Starting web server at port %d" % cfg.httpPort )
|
||||
B.run( host='0.0.0.0', port=cfg.httpPort, quiet=True )
|
||||
6
Docker/src/bin/tHome-sma.py
Executable file
6
Docker/src/bin/tHome-sma.py
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import tHome.sma
|
||||
|
||||
tHome.sma.cmdLine.run( sys.argv )
|
||||
80
Docker/src/bin/tHome-thermostat.py
Executable file
80
Docker/src/bin/tHome-thermostat.py
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#===========================================================================
|
||||
#
|
||||
# Radio thermostats reader
|
||||
#
|
||||
#===========================================================================
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import time
|
||||
import json
|
||||
import tHome as T
|
||||
|
||||
#===========================================================================
|
||||
|
||||
#===========================================================================
|
||||
#
|
||||
# Main applications script
|
||||
#
|
||||
#===========================================================================
|
||||
|
||||
p = argparse.ArgumentParser( prog=sys.argv[0],
|
||||
description="T-Home Thermostats" )
|
||||
p.add_argument( "-c", "--configDir", metavar="configDir",
|
||||
default="/etc/tHome",
|
||||
help="Configuration file directory." )
|
||||
p.add_argument( "-l", "--log", metavar="logFile",
|
||||
default=None, help="Logging file to use. Input 'stdout' "
|
||||
"to log to the screen." )
|
||||
c = p.parse_args( sys.argv[1:] )
|
||||
|
||||
# Parse the thermostat config file.
|
||||
cfg = T.thermostat.config.parse( c.configDir )
|
||||
log = T.thermostat.config.log( cfg, c.log )
|
||||
|
||||
# Create the MQTT client and connect it to the broker.
|
||||
client = T.broker.connect( c.configDir, log )
|
||||
|
||||
# Handle set messages being set to the thermostats.
|
||||
def on_message( client, userData, msg ):
|
||||
for t in cfg.thermostats:
|
||||
if mqtt.topic_matches_sub( t.mqttSetTopic, msg.topic ):
|
||||
t.processSet( client, msg )
|
||||
return
|
||||
|
||||
client.on_message = on_message
|
||||
|
||||
# Subscribe to the set messages.
|
||||
for t in cfg.thermostats:
|
||||
print t
|
||||
client.subscribe( t.mqttSetTopic )
|
||||
|
||||
# Start the MQTT as a background thread. This way we can run the web
|
||||
# server as the main thread here.
|
||||
client.loop_start()
|
||||
|
||||
while True:
|
||||
t0 = time.time()
|
||||
for t in cfg.thermostats:
|
||||
try:
|
||||
# Poll the thermostat for status.
|
||||
t.status()
|
||||
|
||||
# Publish any messages.
|
||||
msgs = t.messages()
|
||||
for topic, msg in msgs:
|
||||
payload = json.dumps( msg )
|
||||
client.publish( topic, payload )
|
||||
|
||||
except Exception as e:
|
||||
# This prints a stack trace which is more than we really want.
|
||||
#log.exception( "Error getting thermostat status." )
|
||||
log.error( "Error getting thermostat status: " + str( e ) )
|
||||
|
||||
dt = time.time() - t0
|
||||
delay = max( cfg.pollTime, cfg.pollTime-dt )
|
||||
time.sleep( delay )
|
||||
|
||||
|
||||
6
Docker/src/bin/tHome-wug.py
Executable file
6
Docker/src/bin/tHome-wug.py
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import tHome.weatherUnderground
|
||||
|
||||
tHome.weatherUnderground.cmdLine.run( sys.argv )
|
||||
Reference in New Issue
Block a user