ansible4ozw 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. data/lib/ansible.rb +47 -0
  2. data/lib/ansible/ansible_callback.rb +142 -0
  3. data/lib/ansible/ansible_device.rb +68 -0
  4. data/lib/ansible/ansible_value.rb +179 -0
  5. data/lib/ansible/config.rb +92 -0
  6. data/lib/ansible/devices/ansible_dimmer.rb +80 -0
  7. data/lib/ansible/devices/ansible_switch.rb +66 -0
  8. data/lib/ansible/knx/EIBConnection.rb +2371 -0
  9. data/lib/ansible/knx/dpt/canonical_1bit.rb +54 -0
  10. data/lib/ansible/knx/dpt/dpt1.rb +224 -0
  11. data/lib/ansible/knx/dpt/dpt10.rb +85 -0
  12. data/lib/ansible/knx/dpt/dpt11.rb +72 -0
  13. data/lib/ansible/knx/dpt/dpt12.rb +61 -0
  14. data/lib/ansible/knx/dpt/dpt13.rb +100 -0
  15. data/lib/ansible/knx/dpt/dpt14.rb +87 -0
  16. data/lib/ansible/knx/dpt/dpt15.rb +72 -0
  17. data/lib/ansible/knx/dpt/dpt16.rb +67 -0
  18. data/lib/ansible/knx/dpt/dpt17.rb +65 -0
  19. data/lib/ansible/knx/dpt/dpt18.rb +66 -0
  20. data/lib/ansible/knx/dpt/dpt19.rb +100 -0
  21. data/lib/ansible/knx/dpt/dpt2.rb +156 -0
  22. data/lib/ansible/knx/dpt/dpt3.rb +104 -0
  23. data/lib/ansible/knx/dpt/dpt4.rb +75 -0
  24. data/lib/ansible/knx/dpt/dpt5.rb +124 -0
  25. data/lib/ansible/knx/dpt/dpt6.rb +73 -0
  26. data/lib/ansible/knx/dpt/dpt7.rb +146 -0
  27. data/lib/ansible/knx/dpt/dpt8.rb +118 -0
  28. data/lib/ansible/knx/dpt/dpt9.rb +204 -0
  29. data/lib/ansible/knx/dpt/tests/test_dpt10.rb +45 -0
  30. data/lib/ansible/knx/dpt/tests/test_dpt9.rb +60 -0
  31. data/lib/ansible/knx/hexdump.rb +113 -0
  32. data/lib/ansible/knx/knx_dpt.rb +58 -0
  33. data/lib/ansible/knx/knx_dpt_scalar.rb +62 -0
  34. data/lib/ansible/knx/knx_eistypes.rb +76 -0
  35. data/lib/ansible/knx/knx_protocol.rb +99 -0
  36. data/lib/ansible/knx/knx_scene.rb +48 -0
  37. data/lib/ansible/knx/knx_tools.rb +76 -0
  38. data/lib/ansible/knx/knx_transceiver.rb +237 -0
  39. data/lib/ansible/knx/knx_value.rb +327 -0
  40. data/lib/ansible/openzwave/ozw_constants.rb +11 -0
  41. data/lib/ansible/openzwave/ozw_headers.rb +80 -0
  42. data/lib/ansible/openzwave/ozw_remote_manager.rb +7615 -0
  43. data/lib/ansible/openzwave/ozw_types.rb +406 -0
  44. data/lib/ansible/orbiter_proxy.rb +12 -0
  45. data/lib/ansible/transceiver.rb +63 -0
  46. data/lib/ansible/zwave/types/valuetype_bool.rb +74 -0
  47. data/lib/ansible/zwave/types/valuetype_button.rb +63 -0
  48. data/lib/ansible/zwave/types/valuetype_byte.rb +78 -0
  49. data/lib/ansible/zwave/types/valuetype_decimal.rb +64 -0
  50. data/lib/ansible/zwave/types/valuetype_int.rb +63 -0
  51. data/lib/ansible/zwave/types/valuetype_list.rb +64 -0
  52. data/lib/ansible/zwave/types/valuetype_short.rb +63 -0
  53. data/lib/ansible/zwave/types/valuetype_string.rb +61 -0
  54. data/lib/ansible/zwave/zwave_command_classes.rb +113 -0
  55. data/lib/ansible/zwave/zwave_node.rb +5 -0
  56. data/lib/ansible/zwave/zwave_protocol.rb +52 -0
  57. data/lib/ansible/zwave/zwave_transceiver.rb +435 -0
  58. data/lib/ansible/zwave/zwave_value.rb +193 -0
  59. metadata +108 -0
@@ -0,0 +1,45 @@
1
+ require 'bindata'
2
+
3
+ class DPT10 < BinData::Record
4
+ bit3 :dayofweek, {
5
+ :display_name => "Day of week",
6
+ :range => 0..7, :data_desc => {
7
+ 0 => "(no day set)",
8
+ 1 => "Monday",
9
+ 2 => "Tuesday",
10
+ 3 => "Wednesday",
11
+ 4 => "Thursday",
12
+ 5 => "Friday",
13
+ 6 => "Saturday",
14
+ 7 => "Sunday"
15
+ }
16
+ }
17
+ bit5 :hour, {
18
+ :display_name => "Hour", :range => 0..23
19
+ }
20
+ #
21
+ bit2 :unused1
22
+ bit6 :minutes, {
23
+ :display_name => "Minutes", :range => 0..59
24
+ }
25
+ #
26
+ bit2 :unused2
27
+ bit6 :seconds, {
28
+ :display_name => "Seconds", :range => 0..59
29
+ }
30
+ end
31
+ [
32
+ [0x8e, 0x21, 0x00]
33
+ ].each {|arr|
34
+ f = DPT10.read(arr.pack('C*'))
35
+ puts arr.inspect + " ==> " + f.inspect
36
+ # f.data = -10
37
+ # puts "after set() ==> " + f.inspect + " serialized as " + f.to_binary_s.unpack("H*").join('0x')
38
+ #f.dayofweek.get_parameter(:range)
39
+ }
40
+ =begin
41
+ [
42
+ # DPT11.001 date
43
+ [0x17, 0x01, 0x0C] # 23/Jan/2012
44
+ ].each {|arr|
45
+ =end
@@ -0,0 +1,60 @@
1
+ require 'bindata'
2
+
3
+ class DPT9_Float < BinData::Primitive
4
+ endian :big
5
+ #
6
+ bit1 :sign, :display_name => "Sign"
7
+ bit4 :exp, :display_name => "Exponent"
8
+ bit11 :mant, :display_name => "Mantissa"
9
+ #
10
+ def get
11
+ puts "get, sign=#{sign} exp=#{exp} mant=#{mant}"
12
+ mantissa = (self.sign==1) ? ~(self.mant^2047) : self.mant
13
+ return Math.ldexp((0.01*mantissa), self.exp)
14
+ end
15
+ #
16
+ def set(v)
17
+ mantissa, exponent = Math.frexp(v)
18
+ puts "#{self}.set(#{v}) with initial mantissa=#{mantissa}, exponent=#{exponent}"
19
+ # find the minimum exponent that will upsize the normalized mantissa (0,5 to 1 range)
20
+ # in order to fit in 11 bits (-2048..2047)
21
+ max_mantissa = 0
22
+ minimum_exp = exponent.downto(-15).find{ | e |
23
+ max_mantissa = Math.ldexp(100*mantissa, e).to_i
24
+ max_mantissa.between?(-2048, 2047)
25
+ }
26
+ self.sign = (mantissa < 0) ? 1 : 0
27
+ self.mant = (mantissa < 0) ? ~(max_mantissa^2047) : max_mantissa
28
+ self.exp = exponent - minimum_exp
29
+ puts "... set(#{v}) finished: sign=#{sign}, mantissa=#{mant}, exponent=#{exp}"
30
+ end # set
31
+ end
32
+
33
+ class DPT9 < BinData::Record
34
+ dpt9_float :data
35
+ end
36
+
37
+ {
38
+ #forward test (raw data to float)
39
+ DPT9.read([0x00, 0x02].pack('C*')).data => 0.02,
40
+ DPT9.read([0x87, 0xfe].pack('C*')).data => -0.02,
41
+ DPT9.read([0x5c, 0xc4].pack('C*')).data => 24980..25000,
42
+ DPT9.read([0xdb, 0x3c].pack('C*')).data => -25000..-24980,
43
+ DPT9.read([0x7f, 0xfe].pack('C*')).data => 670400..670760,
44
+ DPT9.read([0xf8, 0x02].pack('C*')).data => -670760..-670400,
45
+ #backward test (float to raw data)
46
+ "----" => "----",
47
+ DPT9_Float.new(0.02).to_binary_s.unpack("C*") => [0x00, 0x02],
48
+ DPT9_Float.new(-0.02).to_binary_s.unpack("C*") => [0x87, 0xfe],
49
+ DPT9_Float.new(25000).to_binary_s.unpack("C*") => [0x5c, 0xc4],
50
+ DPT9_Float.new(-25000).to_binary_s.unpack("C*") => [0xdb, 0x3c],
51
+ DPT9_Float.new(670760).to_binary_s.unpack("C*") => [0x7f, 0xfe],
52
+ DPT9_Float.new(-670760).to_binary_s.unpack("C*") => [0xf8, 0x02],
53
+ }.each {|arr, test|
54
+ #f = DPT9.read(arr.pack('C*'))
55
+ puts arr.inspect + " ==> " + test.inspect + " \t TEST: " + (test === arr ? 'ok':"\t---FAIL---")
56
+ # f.data = -30
57
+ # puts "after set() ==> " + f.inspect + " serialized as " + f.to_binary_s.unpack('B*').join(' ') + " (0x" + f.to_binary_s.unpack("H*").join('') + ")"
58
+ }
59
+
60
+
@@ -0,0 +1,113 @@
1
+ # ==============================================================================
2
+ # EXTENDING CLASS STRING
3
+ # ==============================================================================
4
+ #
5
+ # (C) Copyright 2004 by Tilo Sloboda <tools@unixgods.org>
6
+ #
7
+ # License:
8
+ # Freely available under the terms of the OpenSource "Artistic License"
9
+ # in combination with the Addendum A (below)
10
+ #
11
+ # In case you did not get a copy of the license along with the software,
12
+ # it is also available at: http://www.unixgods.org/~tilo/artistic-license.html
13
+ #
14
+ # Addendum A:
15
+ # THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU!
16
+ # SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
17
+ # REPAIR OR CORRECTION.
18
+ #
19
+ # IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
20
+ # SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY
21
+ # TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
22
+ # INACCURATE OR USELESS OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
23
+ # TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF THE COPYRIGHT HOLDERS OR OTHER PARTY HAS BEEN
24
+ # ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
25
+
26
+
27
+ class String
28
+ #
29
+ # prints out a good'ol hexdump of the data contained in the string
30
+ #
31
+ # parameters: sparse: true / false do we want to print multiple lines with zero values?
32
+
33
+ def hexdump(sparse = false)
34
+ selfsize = self.size
35
+ first = true
36
+
37
+ print "\n index 0 1 2 3 4 5 6 7 8 9 A B C D E F\n\n"
38
+
39
+ lines,rest = selfsize.divmod(16)
40
+ address = 0; i = 0 # we count them independently for future extension.
41
+
42
+ while lines > 0
43
+ str = self[i..i+15]
44
+
45
+ # we don't print lines with all zeroes, unless it's the last line
46
+
47
+ if str == "\0"*16 # if the 16 bytes are all zero
48
+
49
+ if (!sparse) || (sparse && lines == 1 && rest == 0)
50
+ str.tr!("\000-\037\177-\377",'.')
51
+ printf( "%08x %8s %8s %8s %8s %s\n",
52
+ address, self[i..i+3].unpack('H8'), self[i+4..i+7].unpack('H8'),
53
+ self[i+8..i+11].unpack('H8'), self[i+12..i+15].unpack('H8'), str)
54
+ else
55
+ print " .... 00 .. 00 00 .. 00 00 .. 00 00 .. 00 ................\n" if first
56
+ first = false
57
+ end
58
+
59
+ else # print string which is not all zeros
60
+
61
+ str.tr!("\000-\037\177-\377",'.')
62
+ printf( "%08x %8s %8s %8s %8s %s\n",
63
+ address, self[i..i+3].unpack('H8'), self[i+4..i+7].unpack('H8'),
64
+ self[i+8..i+11].unpack('H8'), self[i+12..i+15].unpack('H8'), str)
65
+ first = true
66
+ end
67
+ i += 16; address += 16; lines -= 1
68
+ end
69
+
70
+ # now do the remaining bytes, which don't fit a full line..
71
+ # yikes - this is truly ugly! REWRITE THIS!!
72
+
73
+ if rest > 0
74
+ chunks2,rest2 = rest.divmod(4)
75
+ j = i; k = 0
76
+ if (i < selfsize)
77
+ printf( "%08x ", address)
78
+ while (i < selfsize)
79
+ printf "%02x", self[i]
80
+ i += 1; k += 1
81
+ print " " if ((i % 4) == 0)
82
+ end
83
+ for i in (k..15)
84
+ print " "
85
+ end
86
+ str = self[j..selfsize]
87
+ str.tr!("\000-\037\177-\377",'.')
88
+ print " " * (4 - chunks2+1)
89
+ printf(" %s\n", str)
90
+ end
91
+ end
92
+ end
93
+
94
+ end
95
+
96
+
97
+
98
+ __END__
99
+
100
+ require 'hexdump'
101
+
102
+ s = "some random long string"
103
+
104
+ t = s << "\0"*40 << s << "\0"*32 << s << "bla bla bla!"
105
+ t.hexdump(true)
106
+ t.hexdump(false)
107
+
108
+ 4.times {t.chop!}
109
+
110
+ t.hexdump(true)
111
+ t.hexdump(false)
112
+
113
+
@@ -0,0 +1,58 @@
1
+ =begin
2
+ Project Ansible - An extensible home automation scripting framework
3
+ ----------------------------------------------------
4
+ Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
5
+
6
+ SOFTWARE NOTICE AND LICENSE
7
+
8
+ Project Ansible is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU Lesser General Public License as published
10
+ by the Free Software Foundation, either version 3 of the License,
11
+ or (at your option) any later version.
12
+
13
+ Project Ansible is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General Public License
19
+ along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ for more information on the LGPL, see:
22
+ http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
23
+ =end
24
+
25
+ require 'bindata'
26
+
27
+ module Ansible
28
+
29
+ module KNX
30
+
31
+ # a base class for DPT data structures.
32
+ # derives from BinData::Record,
33
+ # implements some common stuff
34
+ class DPTFrame < BinData::Record
35
+ # endianness in KNX is big
36
+ endian :big
37
+
38
+ # make sure all frame fields are valid (within min,max range)
39
+ def validate_ranges()
40
+ # range checking is global: applies to all subtypes
41
+ field_names.each { |fieldname|
42
+ # skip padding fields
43
+ next if /pad/.match(fieldname)
44
+ field = self.send(fieldname)
45
+ if range = field.get_parameter(:range) then
46
+ raise "#{self}: field #{fieldname} value (#{field.value}) out of range #{range}" unless range === field.value
47
+ end
48
+ }
49
+ end
50
+ end
51
+
52
+ #
53
+ # load all known DPT modules
54
+ Dir["knx/dpt/*.rb"].each { |f| load f }
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,62 @@
1
+ =begin
2
+ Project Ansible - An extensible home automation scripting framework
3
+ ----------------------------------------------------
4
+ Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
5
+
6
+ SOFTWARE NOTICE AND LICENSE
7
+
8
+ Project Ansible is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU Lesser General Public License as published
10
+ by the Free Software Foundation, either version 3 of the License,
11
+ or (at your option) any later version.
12
+
13
+ Project Ansible is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General Public License
19
+ along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ for more information on the LGPL, see:
22
+ http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
23
+ =end
24
+
25
+ module Ansible
26
+
27
+ module KNX
28
+
29
+ # KNX specification declares some special DPTs (5.001 and 5.003) that need
30
+ # scalar adjustment functions to get the true value contained in a DPT frame.
31
+ module ScalarValue
32
+
33
+ # convert value to its scalar representation
34
+ # e.g. in DPT5.001, 0x7F => 50(%), 0xFF => 100(%)
35
+ def to_scalar(val, data_range, scalar_range)
36
+ if data_range.is_a?(Range) and scalar_range.is_a?(Range) then
37
+ a = (scalar_range.max - scalar_range.min).to_f / (data_range.max - data_range.min)
38
+ b = (scalar_range.min - data_range.min)
39
+ return (a*val + b).round
40
+ else
41
+ return val
42
+ end
43
+ end
44
+
45
+ # convert value from its scalar representation
46
+ # e.g. in DPT5.001, 50(%) => 0x7F , 100(%) => 0xFF
47
+ def from_scalar(val, data_range, scalar_range)
48
+ if data_range.is_a?(Range) and scalar_range.is_a?(Range) then
49
+ a = (scalar_range.max - scalar_range.min).to_f / (data_range.max - data_range.min)
50
+ b = (scalar_range.min - data_range.min)
51
+ #puts "a=#{a} b=#{b}"
52
+ return ((val - b) / a).round
53
+ else
54
+ return val
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,76 @@
1
+ =begin
2
+ Project Ansible - An extensible home automation scripting framework
3
+ ----------------------------------------------------
4
+ Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
5
+
6
+ SOFTWARE NOTICE AND LICENSE
7
+
8
+ Project Ansible is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU Lesser General Public License as published
10
+ by the Free Software Foundation, either version 3 of the License,
11
+ or (at your option) any later version.
12
+
13
+ Project Ansible is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General Public License
19
+ along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ for more information on the LGPL, see:
22
+ http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
23
+ =end
24
+
25
+ module Ansible
26
+
27
+ module KNX
28
+
29
+ # the skeleton class for the datatypes in use by the KNX standard
30
+ class EISType
31
+
32
+ # singleton hash holding all known EISType instances
33
+ # key => primary_type (integer 1 to 255)
34
+ # value => hash of secondary types (secondary_type => instance)
35
+ # -- NOTE: the contained secondary types hash can be set
36
+ # to report a default instance that holds a generic EISType.
37
+ # Thus we define datatypes with great granularity.
38
+ @@alltypes = {}
39
+
40
+ # method for getting all known EIS types as a flat array
41
+ def EISType.all
42
+ return @@alltypes.values.collect{ |st| st.values + st.default}.flatten.compact
43
+ end
44
+
45
+ # initializes a new datatype
46
+ def initialize(primary_type, secondary_type)
47
+ puts "Initializing new EISType pri=#{primary_type} sec=#{secondary_type}"
48
+ @primary_type , @secondary_type = primary_type , secondary_type
49
+ @@alltypes[primary_type] = {} unless @@alltypes[primary_type].is_a? Hash
50
+ # store ourselves in the big hash of types
51
+ if secondary_type.nil? then
52
+ puts "==> Redeclaring default EISType for primary=#{primary_type}" if @@alltypes[primary_type]
53
+ @@alltypes[primary_type].default = self
54
+ else
55
+ @@alltypes[primary_type][secondary_type] = self
56
+ end
57
+ end
58
+
59
+ # return a human-readable description for this EISType
60
+ def to_s
61
+ return 'EIS' + @primary_type.to_s + (@secondary_type.nil? ? "" : ".#{@secondary_type}")
62
+ end
63
+
64
+ # takes a KNX value and abstracts its data
65
+ # usage: eis1.abstractor {|value| value.to_s }
66
+
67
+ def abstractor=(&block)
68
+ # in its most basic form, abstract_value just returns the value
69
+ return(value.get()
70
+ end
71
+
72
+ end # class
73
+
74
+ end #module KNX
75
+
76
+ end #module Ansible
@@ -0,0 +1,99 @@
1
+ =begin
2
+ Project Ansible - An extensible home automation scripting framework
3
+ ----------------------------------------------------
4
+ Copyright (c) 2011 Elias Karakoulakis <elias.karakoulakis@gmail.com>
5
+
6
+ SOFTWARE NOTICE AND LICENSE
7
+
8
+ Project Ansible is free software: you can redistribute it and/or modify
9
+ it under the terms of the GNU Lesser General Public License as published
10
+ by the Free Software Foundation, either version 3 of the License,
11
+ or (at your option) any later version.
12
+
13
+ Project Ansible is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU Lesser General Public License for more details.
17
+
18
+ You should have received a copy of the GNU Lesser General Public License
19
+ along with Project Ansible. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ for more information on the LGPL, see:
22
+ http://en.wikipedia.org/wiki/GNU_Lesser_General_Public_License
23
+ =end
24
+
25
+ require 'bindata'
26
+
27
+ module Ansible
28
+
29
+ module KNX
30
+
31
+ # the basic Control field structure for KNX/TP (Twisted Pair) telegrams
32
+ # contains only low-level transmission medium data
33
+ class TP_ControlField < BinData::Record
34
+ bit2 :lpdu_code, { :display_name => "LPDU (2bit) 2=L_DATA.req 3=L_Poll_data.req" }
35
+ bit1 :rep_flag, { :display_name => "Repeat flag"}
36
+ bit1 :ack_not, { :display_name => "0 = Acknowledge frame, 1 = standard frame"}
37
+ bit2 :prio_class,{ :display_name => "Priority class (0=highest .. 3=lowest)"}
38
+ bit2 :unused1, { :display_name => "two unused bits (should be 00)"}
39
+ end
40
+
41
+ # same as TP_ControlField, plus network- and application-layer data
42
+ # also known as APDU (Application Datagram Unit)
43
+ class L_DATA_Frame < BinData::Record
44
+ endian :big
45
+ # octet 0: TP1 control field
46
+ bit2 :lpdu_code, { :display_name => "LPDU (2bit) 2=L_DATA.req 3=L_Poll_data.req"}
47
+ bit1 :rep_flag, { :display_name => "Repeat flag"}
48
+ bit1 :ack_not, { :display_name => "0 = Acknowledge frame, 1 = standard frame"}
49
+ bit2 :prio_class,{ :display_name => "Priority class (0=highest .. 3=lowest)"}
50
+ bit2 :unused1, { :display_name => "two unused bits (should be 00)"}
51
+ # octet 1+2: source
52
+ uint16 :src_addr, { :display_name => "Source Address"}
53
+ # octet 3+4: destination
54
+ uint16 :dst_addr, { :display_name => "Destination Address"}
55
+ # octet 5: control fields
56
+ bit1 :daf, { :display_name => "Dest.Address flag 0=physical 1=group"}
57
+ bit3 :ctrlfield, { :display_name => "Network control field"}
58
+ bit4 :datalength,{ :display_name => "Data length (bytes after octet #6)"}
59
+ # octet 6 + octet 7: TPCI+APCI+6-bit data
60
+ bit2 :tpci, { :display_name => "TPCI control bits 8+7"}
61
+ bit4 :seq, { :display_name => "Packet sequence"}
62
+ bit4 :apci, { :display_name => "APCI control bits"}
63
+ bit6 :apci_data, { :display_name => "APCI/Data combined"}
64
+ # octet 8 .. end
65
+ string :data, {
66
+ :read_length => lambda { datalength - 1 },
67
+ :display_nane => "rest of frame"
68
+ }
69
+ end
70
+
71
+ #########################################################
72
+
73
+ # APCI codes array
74
+ APCICODES = "A_GroupValue_Read A_GroupValue_Response A_GroupValue_Write \
75
+ A_PhysicalAddress_Write A_PhysicalAddress_Read A_PhysicalAddress_Response \
76
+ A_ADC_Read A_ADC_Response A_Memory_Read A_Memory_Response A_Memory_Write \
77
+ A_UserMemory A_DeviceDescriptor_Read A_DeviceDescriptor_Response A_Restart \
78
+ A_OTHER".split()
79
+
80
+ # TPDU codes array
81
+ TPDUCODES = "T_DATA_XXX_REQ T_DATA_CONNECTED_REQ T_DISCONNECT_REQ T_ACK".split()
82
+
83
+ # Priority classes
84
+ PRIOCLASSES = "system alarm high low".split()
85
+
86
+ #########################################################
87
+
88
+ end #module KNX
89
+
90
+ end #module
91
+
92
+ #~ data = [188, 17, 200, 18, 1, 242, 0, 128, 80, 171] .pack("c*")
93
+ #~ knxpacket = KNX_L_DATA_Frame.new(data)
94
+ #~ knxpacket.fields.each { |a|
95
+ #~ puts "#{a.name} == #{a.inspect_in_object(knxpacket, :default)}"
96
+ #~ }
97
+ #puts knxpacket.inspect_detailed
98
+ #~ require 'knx_tools'
99
+ #puts addr2str(knxpacket.src_addr)