ansible4ozw 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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)