Skip to content

Commit

Permalink
improved API interoperability between KNX and OZW
Browse files Browse the repository at this point in the history
  • Loading branch information
Elias Karakoulakis committed Jan 4, 2012
1 parent 41cccd0 commit 34625ec
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 23 deletions.
6 changes: 6 additions & 0 deletions knx/knx_transceiver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class NormalExit < Exception; end

def initialize(connURL)
begin
raise "Already initialized!" unless Ansible::KNX::KNXValue.transceiver.nil?
puts("KNX: init connection to #{connURL}")
@monitor_conn = EIBConnection.new()
@monitor_conn.EIBSocketURL(connURL)
Expand All @@ -66,6 +67,8 @@ def initialize(connURL)
@send_mutex = Mutex.new()
@knxbuf = EIBBuffer.new()
super()
# store reference to ourselves to the classes that use us
Ansible::KNX::KNXValue.transceiver = self
rescue Exception => e
puts "#{self}.initialize() EXCEPTION: #{e}\n\t" + e.backtrace.join("\n\t")
end
Expand Down Expand Up @@ -101,6 +104,9 @@ def run()
headers[fld.name] = CGI.escape(fldvalue)
}
@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)
#
end
Expand Down
13 changes: 9 additions & 4 deletions knx/knx_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ def KNXValue.id_generator
@@ids = @@ids + 1
return @@ids
end

# the transceiver responsible for all things KNX
@@transceiver = nil
def KNXValue.transceiver; return @@transceiver; end
def KNXValue.transceiver=(other);
@@transceiver = other if other.is_a? Ansible::KNX::KNX_Transceiver
end

#
# ----- INSTANCE VARIABLES & METHODS
Expand All @@ -61,9 +68,7 @@ def == (other)
attr_accessor :description

# initialize KNXValue
def initialize(transceiver, groups=[], flags=nil)
# the transceiver responsible for all things KNX
@transceiver = transceiver
def initialize(groups=[], flags=nil)

# array of group addresses associated with this datapoint
# only the first address is used in a write operation (TODO: CHECKME)
Expand Down Expand Up @@ -111,7 +116,7 @@ def set(new_val)
apdu = create_apdu()
puts "#{self}: Writing value to #{addr2str(dest)}"
#
@transceiver.send_apdu_raw(dest, apdu)
@@transceiver.send_apdu_raw(dest, apdu)
end

def group_primary=(grpaddr)
Expand Down
25 changes: 19 additions & 6 deletions test3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,18 @@
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]
if (frame.apci == 2) then # A_GroupValue_Write
case frame.apci
when 0 then # A_GroupValue_Read
#puts "read request for knx address #{addr2str(frame.dst_addr, frame.daf)}"
AnsibleValue[:groups => [frame.dst_addr]].each { |val|
if val.current_value then
#puts "==> responding with value #{val}"
KNX.send_apdu_raw(frame.dst_addr, val.to_apdu())
end
}
when 1 then # A_GroupValue_Response
# puts "response frame"
when 2 then # A_GroupValue_Write
AnsibleValue[:groups => [frame.dst_addr]].each { |v|
#puts "updating knx value #{v} from frame #{frame.inspect}"
v.update_from_frame(frame)
Expand All @@ -67,9 +78,10 @@
}


AnsibleValue.insert( Ansible::KNX::KNXValue_DPT1.new(KNX, "1/0/20") ).declare_callback(:onUpdate) { |sender, cb, args|
AnsibleValue.insert( Ansible::KNX::KNXValue_DPT1.new("1/0/20") ).declare_callback(:onUpdate) { |sender, cb, args|
puts "KNX value 1/0/20 updated! args=#{args}"
Tree.set(args) # FIXME convert value domains
zwval = sender.current_value == 0 ? 0 : 1
Switch.set(zwval) # FIXME convert value domains
}
Switch.declare_callback(:onUpdate) { | sender, cb, args|
puts "ZWave Switch HAS CHANGED #{args}"
Expand All @@ -78,9 +90,10 @@
}


AnsibleValue.insert( Ansible::KNX::KNXValue_DPT1.new(KNX, "1/0/40") ).declare_callback(:onUpdate) { |sender, cb, args|
AnsibleValue.insert( Ansible::KNX::KNXValue_DPT1.new("1/0/40") ).declare_callback(:onUpdate) { |sender, cb, args|
puts "KNX value 1/0/40 updated! args=#{args}"
Dimmer.set(args) # FIXME convert value domains
zwval = sender.current_value == 0 ? 0 : 99
Dimmer.set(zwval) # FIXME convert value domains
}
Dimmer.declare_callback(:onUpdate) { | sender, cb, args|
puts "ZWave DimerOnOff HAS CHANGED #{args}"
Expand All @@ -89,7 +102,7 @@
}


AnsibleValue.insert( Ansible::KNX::KNXValue_DPT5.new(KNX, "1/0/42") ).declare_callback(:onUpdate) { |sender, cb, args|
AnsibleValue.insert( Ansible::KNX::KNXValue_DPT5.new("1/0/42") ).declare_callback(:onUpdate) { |sender, cb, args|
puts "KNX value 1/0/42 updated! args=#{args}"
zwval = sender.current_value * 99 / 255
DimmerAbsolute.set(zwval.round) # FIXME convert value domains
Expand Down
5 changes: 4 additions & 1 deletion zwave/zwave_transceiver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@ class ZWave_Transceiver < Transceiver
attr_reader :stompURL, :thriftURL

def initialize(stompURL, thriftURL)
raise "Already initialized!" unless OpenZWave::ValueID::transceiver.nil?
puts "#{self}: initializing" if $DEBUG
@stompURL, @thriftURL = stompURL, thriftURL
#@stompMutex = Mutex.new
@thriftMutex = Mutex.new
@stomp_ok, @thrift_ok = false, false
@alive = true
super()
# store reference to ourselves to the classes that use us
OpenZWave::ValueID.transceiver = self
end

# initialize connection to STOMP server
Expand Down Expand Up @@ -200,7 +203,7 @@ def decode_monitor(msg)
valueID = msg.headers["ValueID"]
# lookup or create value
# pass self as an argument so as to receive manager operations
value = AnsibleValue.insert(OpenZWave::ValueID.new(self, homeID, valueID))
value = AnsibleValue.insert(OpenZWave::ValueID.new(homeID, valueID))
end
#
if msg.headers["NotificationType"] then
Expand Down
25 changes: 13 additions & 12 deletions zwave/zwave_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ class ValueID < RemoteValueID
# ------ CLASS VARIABLES & METHODS
#
@@NodesPolled = {}


@@transceiver = nil
def ValueID.transceiver; return @@transceiver; end
def ValueID.transceiver=(other);
@@transceiver = other if other.is_a? Ansible::ZWave_Transceiver
end

#
# ----- INSTANCE VARIABLES & METHODS
#
Expand All @@ -71,9 +75,7 @@ def == (other)
end

# initialize ValueID by home and value id (both hex strings)
def initialize(transceiver, homeid, valueid)
@transceiver = transceiver

def initialize( homeid, valueid)
raise 'both arguments must be strings' unless ((homeid.is_a?String) and (valueid.is_a?String))

@_homeId = homeid.to_i(16)
Expand All @@ -94,7 +96,7 @@ def initialize(transceiver, homeid, valueid)
puts "NEW ZWAVE VALUE CREATED: #{self.inspect}" if $DEBUG

# fill in some useful info so as not to query OpenZWave all the time
@readonly = @transceiver.manager_send(:IsValueReadOnly, self)
@readonly = @@transceiver.manager_send(:IsValueReadOnly, self)

# time of last update
@last_update = nil
Expand Down Expand Up @@ -124,7 +126,7 @@ def get()
#FIXME: when RemoteValueType::ValueType_Schedule
else raise "unknown/uninitialized value type! #{inspect}"
end
result = @transceiver.manager_send(operation, self)
result = @@transceiver.manager_send(operation, self)
if result and result.retval then
puts "get() result=#{result.o_value}, curr=#{@current_value.inspect} Refreshed=#{RefreshedNodes[@_nodeId]}"
# call succeeded, let's see what we got from OpenZWave
Expand Down Expand Up @@ -160,7 +162,7 @@ def set(new_val)
if [TrueClass, FalseClass].include?(new_val.class)
new_val = new_val ? 1 : 0
end
if result = @transceiver.manager_send(operation, self, new_val) then
if result = @@transceiver.manager_send(operation, self, new_val) then
fire_callback(:onAfterSet)
# update the current value
update(new_val)
Expand All @@ -180,7 +182,7 @@ def changed
# reported by OpenZWave is unchanged. Thus we need to poll the
# device using :RequestNodeDynamic, wait for NodeQueriesComplete
# then re-get the value
trigger_change_monitor unless @poll_delayed
trigger_change_monitor
else
# update the current value
update(result)
Expand All @@ -200,11 +202,10 @@ def trigger_change_monitor
begin
fire_callback(:onChangeMonitorStart, @_nodeId)
# request node status update after 1 sec
sleep(1)
@transceiver.manager_send(:RequestNodeDynamic, Ansible::HomeID, @_nodeId)
sleep(2)
@@transceiver.manager_send(:RequestNodeDynamic, Ansible::HomeID, @_nodeId)
#@transceiver.manager_send(:RefreshNodeInfo, Ansible::HomeID, @_nodeId)
sleep(1)

fire_callback(:onChangeMonitorComplete, @_nodeId)
puts "==> trigger change monitor thread (#{Thread.current} ENDED<=="
@@NodesPolled[@_nodeId] = false
Expand Down

0 comments on commit 34625ec

Please sign in to comment.