Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Some spring-time refactoring...

  • Loading branch information...
commit a7e7e03e01a782c55e7e819569808ac994c50716 1 parent b375b71
Elias Karakoulakis authored
29 ansible_utils.rb
View
@@ -0,0 +1,29 @@
+=begin
+Project Ansible - An extensible home automation scripting framework
+----------------------------------------------------
+Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
+
+SOFTWARE NOTICE AND LICENSE
+
+Project Ansible is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published
+by the Free Software Foundation, either version 3 of the License,
+or (at your option) any later version.
+
+Project Ansible is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+for more information on the LGPL, see:
+http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
+=end
+
+def dump_trace(ex, message, method_name)
+ msg = "#{message}: #{ex} while in #{method_name}\n"
+ dashes = ('-' * msg.length) + "\n"
+ puts dashes + msg + dashes + "\t" + ex.backtrace.join("\n\t")
+end
2  ansible_value.rb
View
@@ -117,7 +117,7 @@ def AnsibleValue.insert(newvalue)
#
# get a value's current state
- # returns: the value, if found in eibd's cache or nil otherwise
+ # returns: the value, if found in cache or nil otherwise
def get
return if write_only?
#
64 knx/knx_transceiver.rb
View
@@ -42,11 +42,13 @@ module KNX
class KNX_Transceiver < Transceiver
include AnsibleCallback
+
# a special exception to break the knx tranceiver loop
class NormalExit < Exception; end
attr_reader :stomp
+
# initialize a KNXTranceiver
#
# *params:
@@ -62,7 +64,13 @@ def initialize(connURL=KNX_URL)
# store reference to ourselves to the classes that use us
Ansible::KNX::KNXValue.transceiver = self
# register default handler for KNX frames
- add_callback(:onKNXtelegram) { | sender, cb, frame |
+ add_default_callback
+ end
+
+ # the default callback to be called on each KNX telegram.
+ # Needless to say this proc shouldn't take much long...
+ def add_default_callback
+ add_callback(:onKNXtelegram) { | sender, cb, frame|
puts(frame_inspect(frame)) if $DEBUG
case frame.apci.value
when 0 then # A_GroupValue_Read
@@ -73,21 +81,16 @@ def initialize(connURL=KNX_URL)
send_apdu_raw(frame.dst_addr, v.to_apdu(0x40))
end
}
- when 1 then # A_GroupValue_Response
+ when 1..2 then # A_GroupValue_Response, A_GroupValue_Write
puts "response frame by #{addr2str(frame.src_addr)} for knx address #{addr2str(frame.dst_addr, frame.daf)}"
AnsibleValue[:groups => [frame.dst_addr]].each { |v|
v.update_from_frame(frame)
puts "synchronized knx value #{v} from frame #{frame.inspect}" if $DEBUG
}
- when 2 then # A_GroupValue_Write
- AnsibleValue[:groups => [frame.dst_addr]].each { |v|
- v.update_from_frame(frame)
- puts "updated knx value #{v} from frame #{frame.inspect}" if $DEBUG
- }
end
}
end
-
+
# initialize eibd connection
def init_eibd(conn_symbol, conn_ok_symbol)
unless instance_variable_get(conn_ok_symbol)
@@ -138,24 +141,7 @@ def run()
# end
##### part 3: monitor KNX bus, post all activity to /knx/monitor
vbm = monitor_conn.EIBOpenVBusmonitor()
- loop do
- len = monitor_conn.EIBGetBusmonitorPacket(@knxbuf)
- #puts "knxbuffer=="+@knxbuf.buffer.inspect
- frame = L_DATA_Frame.read(@knxbuf.buffer.pack('c*'))
- #puts "frame:\n\t"
- headers = {}
- frame.field_names.each { |fieldname|
- field = frame.send(fieldname)
- #puts "\t#{fieldname} == #{field.value}"
- headers[fieldname] = CGI.escape(field.value.to_s)
- }
- @stomp.send(KNX_MONITOR_TOPIC, "KNX Activity", headers)
- #puts Ansible::KNX::APCICODES[frame.apci] + " packet from " +
- # addr2str(frame.src_addr) + " to " + addr2str(frame.dst_addr, frame.daf) +
- # " priority=" + Ansible::KNX::PRIOCLASSES[frame.prio_class]
- fire_callback(:onKNXtelegram, frame.dst_addr, frame)
- #
- end
+ knx2stomp_monitor
rescue Errno::ECONNRESET => e
@monitor_conn_ok = false
puts("EIBD disconnected! retrying in 10 seconds..")
@@ -164,9 +150,8 @@ def run()
rescue NormalExit => e
puts("KNX transceiver terminating gracefully...")
rescue Exception => e
- puts("Exception in KNX server thread: #{e}")
- puts("backtrace:\n " << e.backtrace.join("\n "))
- sleep(3)
+ dump_trace(e, "KNXTransceiver", "run")
+ sleep(3)
retry
# ensure
#puts "Closing EIB connection..."
@@ -176,6 +161,27 @@ def run()
end
end #def run()
+ def knx2stomp_monitor
+ loop do
+ len = monitor_conn.EIBGetBusmonitorPacket(@knxbuf)
+ #puts "knxbuffer=="+@knxbuf.buffer.inspect
+ frame = L_DATA_Frame.read(@knxbuf.buffer.pack('c*'))
+ #puts "frame:\n\t"
+ headers = {}
+ frame.field_names.each { |fieldname|
+ field = frame.send(fieldname)
+ #puts "\t#{fieldname} == #{field.value}"
+ headers[fieldname] = CGI.escape(field.value.to_s)
+ }
+ @stomp.send(KNX_MONITOR_TOPIC, "KNX Activity", headers)
+ #puts Ansible::KNX::APCICODES[frame.apci] + " packet from " +
+ # addr2str(frame.src_addr) + " to " + addr2str(frame.dst_addr, frame.daf) +
+ # " priority=" + Ansible::KNX::PRIOCLASSES[frame.prio_class]
+ fire_callback(:onKNXtelegram, frame.dst_addr, frame)
+ #
+ end
+ end
+
# send a raw APDU to the KNX bus.
#
# * Arguments:
2  transceiver.rb
View
@@ -25,6 +25,8 @@
require 'rubygems'
require 'onstomp'
+require 'ansible_utils'
+
module Ansible
# Generic Ansible tranceiver
4 zwave/types/valuetype_bool.rb
View
@@ -66,6 +66,10 @@ def explain
puts "cv = #{@current_value}"
return(@current_value? "ON":"OFF")
end
+
+ # probably very useful
+ def on; set true; end
+ def off; set false; end
end
end
65 zwave/zwave_transceiver.rb
View
@@ -34,7 +34,7 @@
module Ansible
module ZWave
-
+
# the ZWave transceiver is responsible for communication with the ZWave network
# uses ozwd, a Thrift wrapper around the OpenZWave library
class ZWave_Transceiver < Transceiver
@@ -69,7 +69,7 @@ def initialize(stompURL, thriftURL)
end
def init_stomp
- unless @stomp_ok
+ unless @stomp_ok
begin
# initialize connection to STOMP server
@stompserver = OnStomp::Client.new(@stompURL)
@@ -82,7 +82,7 @@ def init_stomp
@stompserver.connect
rescue Errno::ECONNREFUSED => e
@stomp_ok = false
- puts "#{e}"
+ dump_trace(e, "STOMP", "init_stomp")
end
end
return @stompserver
@@ -111,8 +111,8 @@ def init_thrift()
@thrift_transport.open()
@manager = ::OpenZWave::RemoteManager::Client.new(@thrift_protocol)
@thrift_ok = true
- # the heartbeat thread sends a controller node query every 2 seconds
- @thrift_heartbeat = thriftHeartbeat()
+ # the heartbeat thread sends a controller node query every 10 seconds
+ @thrift_heartbeat = thriftHeartbeat(10)
# fetch all known ValueID's from the server
@manager.SendAllValues
else
@@ -120,24 +120,22 @@ def init_thrift()
end
rescue Exception => e
@thrift_ok = false
- puts "#{e}"
+ dump_trace(e, "THRIFT", "init_thrift")
end
end
return @manager
end
- def thriftHeartbeat
+ def thriftHeartbeat(period)
return Thread.new {
puts "Thrift: New heartbeat thread, #{Thread.current}"
while (@thrift_ok) do
- sleep(2)
+ sleep(period)
@thriftMutex.synchronize {
begin
- #print 'ping...'
- @manager.ping()
- #puts 'pong!'
+ @manager.ping()
rescue Exception => e
- puts e
+ dump_trace("Thrift heartbeat", e, "ping")
@thrift_ok = false
end
}
@@ -163,18 +161,18 @@ def manager_send(meth, *args)
rescue Thrift::TransportException => e
# mark connection as not OK so as to reconnect at next call
@thrift_ok = false
- puts "Thrift transport exception, in method #{meth.inspect}"
- puts "--------------------------, callers=\n\t\t" + caller[0..4].join("\n\t\t")
+ dump_trace(e, "Thrift transport exception", meth.inspect)
sleep(1)
retry
rescue Exception => e
- puts "OpenZWave exception: #{e}, in method #{meth.inspect}"
- puts "--------------------, callers=\n\t\t" + caller[0..4].join("\n\t\t")
+ dump_trace(e, "Other exception", meth.inspect)
end
}
return(result)
end
-
+
+
+
#
# transceiver main loop, runs in its own Ruby thread
#
@@ -187,10 +185,9 @@ def run
begin
value = getValueFrom(msg)
rescue Exception => e
- puts "ZWaveTransceiver::decode_monitor() exception: #{e}"
- puts "\t"+e.backtrace[0..3].join("\n\t")
+ dump_trace("ZWaveTransceiver",e, "decode_monitor")
end
- end # do subscribe
+ end
# 2) Sleep forever (how pretty)
while true #@alive #FIXME
sleep(1)
@@ -210,10 +207,15 @@ def getValueFrom(msg)
h = homeID.to_i(16)
if Ansible::ZWave.const_defined?(:HomeID) then
raise "HomeID changed from 0x#{Ansible::ZWave::HomeID.to_s(16)} to #{homeID}" unless h == Ansible::ZWave::HomeID
- elsif h > 0 then
- puts "------ SETTING HOME ID: #{homeID}"
- Ansible::ZWave.const_set("HomeID", h)
- end
+ else
+ # ZWave homeID not yet set
+ if h > 0 then
+ puts "------ SETTING HOME ID: #{homeID}"
+ Ansible::ZWave.const_set("HomeID", h)
+ else
+ raise "HomeID not set by controller - This shouldn't happen since all controllers come with the HomeID set in firmware"
+ end
+ end
# get or create ValueID object
value = Ansible::ZWave::ValueID.get_or_create(homeID, valueID)
end
@@ -284,8 +286,8 @@ def notification_ValueRemoved(nodeId, byte, value)
# A node value has been updated from the Z-Wave network.
def notification_ValueChanged(nodeId, byte, value)
# node monitor phase 2:
- if value.get
- @ValueMonitorMutex.synchronize do
+ #if value.get
+ @ValueMonitorMutex.synchronize {
sleep(2)
AnsibleValue[:_nodeId => nodeId].each { |val|
val.get()
@@ -294,7 +296,7 @@ def notification_ValueChanged(nodeId, byte, value)
@ValueMonitors[nodeId] = false
fire_callback(:onMonitorStop)
puts "==> trigger change monitor ENDED<=="
- end
+ }
end
# A node value has been refreshed from the Z-Wave network.
@@ -412,7 +414,7 @@ def notification_AllNodesQueried(nodeId, byte, value); end
=end
def trigger_node_monitor(nodeId)
- @ValueMonitorMutex.synchronize do
+ @ValueMonitorMutex.synchronize {
# define a node monitor proc then spawn a new thread to run it
unless @ValueMonitors[nodeId] then
puts "==> spawning trigger change monitor thread for #{nodeId}<=="
@@ -425,10 +427,8 @@ def trigger_node_monitor(nodeId)
# then declare the handler to run upon NodeQueriesComplete notification
@ValueMonitors[nodeId] = true
# node monitor phase 2: see notification_NodeQueriesComplete
- end # unless
-
- end # do
-
+ end # unless
+ }
end #def
end #class
@@ -437,4 +437,3 @@ def trigger_node_monitor(nodeId)
end # module Ansible
-end
Please sign in to comment.
Something went wrong with that request. Please try again.