source: EcnlProtoTool/trunk/prototool/src/main.rb@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 10.5 KB
Line 
1# TOPPERSプロジェクト
2$MAKER_CODE = "\x00\x00\xB3"
3
4# ノードプロファイルオブジェクト
5class LocalNode < ECNL::ENode
6 def initialize(eojx3)
7 # 動作状æ…
8‹
9 @operation_status = "\x30"
10 # Ve
11rsion情
12å ±
13 @version_information = "\x01\x0A\x01\x00"
14 # 識別番号
15 @identification_number =
16 # 下位通信層IDフィールド
17 "\xFE" +
18 # メーカーコード
19 $MAKER_CODE +
20 # ユニークID部(メーカー独自)
21 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
22 # 異常内
23容
24 @fault_content = "\x00\x00"
25 # メーカーコード
26 @manufacturer_code = $MAKER_CODE
27
28 # インスタンス数
29 @inst_count = "\x00\x00\x01"
30 # クラス数
31 @class_count = "\x00\x02"
32 # インスタンスリスト
33 @inst_list = "\x01\x05\xff\x01"
34 # クラスリスト
35 @class_list = "\x01\x05\xff"
36 # アナウンスプロパティマップ
37 @anno_prpmap = "\x01\xd5"
38 # SETプロパティマップ
39 @set_prpmap = "\x01\x80"
40 # GETプロパティマップ
41 @get_prpmap = "\x0c\x80\x82\x83\x89\x8a\x9d\x9e\x9f\xd3\xd4\xd6\xd7"
42 # プロパティ定義
43 eprpinib_table = [
44 ECNL::EProperty.new(0x80, (ECNL::EPC_RULE_SET | ECNL::EPC_RULE_GET), @operation_status.length, :@operation_status, :onoff_prop_set, :data_prop_get),
45 ECNL::EProperty.new(0x82, (ECNL::EPC_RULE_GET), @version_information.length, :@version_information, :data_prop_set, :data_prop_get),
46 ECNL::EProperty.new(0x83, (ECNL::EPC_RULE_GET), @identification_number.length, :@identification_number, :data_prop_set, :data_prop_get),
47 ECNL::EProperty.new(0x89, (ECNL::EPC_RULE_GET), @fault_content.length, :fault_content, :@node_profile_object_fault_content_set, :data_prop_get),
48 ECNL::EProperty.new(0x8A, (ECNL::EPC_RULE_GET), @manufacturer_code.length, :@manufacturer_code, :data_prop_set, :data_prop_get),
49 ECNL::EProperty.new(0x9D, (ECNL::EPC_RULE_GET), @anno_prpmap.length, :@anno_prpmap, nil, :data_prop_get),
50 ECNL::EProperty.new(0x9E, (ECNL::EPC_RULE_GET), @set_prpmap.length, :@set_prpmap, nil, :data_prop_get),
51 ECNL::EProperty.new(0x9F, (ECNL::EPC_RULE_GET), @get_prpmap.length, :@get_prpmap, nil, :data_prop_get),
52 ECNL::EProperty.new(0xD3, (ECNL::EPC_RULE_GET), @inst_count.length, :@inst_count, nil, :data_prop_get),
53 ECNL::EProperty.new(0xD4, (ECNL::EPC_RULE_GET), @class_count.length, :@class_count, nil, :data_prop_get),
54 ECNL::EProperty.new(0xD5, (ECNL::EPC_RULE_ANNO), @inst_list.length, :@inst_list, nil, :data_prop_get),
55 ECNL::EProperty.new(0xD6, (ECNL::EPC_RULE_GET), @inst_list.length, :@inst_list, nil, :data_prop_get),
56 ECNL::EProperty.new(0xD7, (ECNL::EPC_RULE_GET), @class_list.length, :@class_list, nil, :data_prop_get)
57 ]
58
59 super(eojx3, eprpinib_table)
60 end
61
62 # 異常内
63容設定関数
64 def node_profile_object_fault_content_set(prop, src)
65 # サイズが2以外は受け付けない
66 if (src.bytesize != 2) then
67 return 0
68 end
69
70 if (prop.anno) then
71 prop.set_anno(prop.exinf != src)
72 end
73
74 val = src.getbyte(0) << 8 | src.getbyte(1)
75
76 if ((val >= 0x0) && (val <= 0x3ec)) then
77 prop.set_exinf(val)
78 # TODO: このの場合の処理
79 # 上記以外は受け付けない
80 else
81 return 0
82 end
83
84 return 2
85 end
86
87 # 動作状æ…
88‹ON/OFF設定関数(0x30, 0x31のみ受け付け)
89 def onoff_prop_set(prop, src)
90 return 0
91 end
92end
93
94# コントローラークラス
95class Controller < ECNL::EObject
96 def initialize(eojx3, enod)
97 # 動作状æ…
98‹
99 @operation_status = "\x30"
100 # 設置場所
101 @installation_location = "\x01\x0A\x01\x00"
102 # 規格Ve
103rsion情
104å ±
105 @standard_version_information = "\x00\x00C\x00"
106 # 異常発生状æ…
107‹
108 @fault_status = "\x41"
109 # メーカーコード
110 @manufacturer_code = $MAKER_CODE
111
112 # アナウンスプロパティマップ
113 @anno_prpmap = "\x03\x80\x81\x88"
114 # SETプロパティマップ
115 @set_prpmap = "\x04\x80\x81\x97\x98"
116 # GETプロパティマップ
117 @get_prpmap = "\x0a\x80\x81\x82\x88\x8a\x97\x98\x9d\x9e\x9f"
118 # プロパティ定義
119 eprpinib_table = [
120 ECNL::EProperty.new(0x80, (ECNL::EPC_RULE_SET | ECNL::EPC_RULE_GET | ECNL::EPC_ANNOUNCE), @operation_status.length, :@operation_status, :onoff_prop_set, :data_prop_get),
121 ECNL::EProperty.new(0x81, (ECNL::EPC_RULE_SET | ECNL::EPC_RULE_GET | ECNL::EPC_ANNOUNCE), @installation_location.length, :@installation_location, :data_prop_set, :data_prop_get),
122 ECNL::EProperty.new(0x82, (ECNL::EPC_RULE_GET), @standard_version_information.length, :@standard_version_information, :data_prop_set, :data_prop_get),
123 ECNL::EProperty.new(0x88, (ECNL::EPC_RULE_GET | ECNL::EPC_ANNOUNCE), @fault_status.length, :@fault_status, :alarm_prop_set, :data_prop_get),
124 ECNL::EProperty.new(0x8A, (ECNL::EPC_RULE_GET), @manufacturer_code.length, :@manufacturer_code, :data_prop_set, :data_prop_get),
125 ECNL::EProperty.new(0x97, (ECNL::EPC_RULE_SET | ECNL::EPC_RULE_GET), (2), nil, :time_prop_set, :time_prop_get),
126 ECNL::EProperty.new(0x98, (ECNL::EPC_RULE_SET | ECNL::EPC_RULE_GET), (4), nil, :date_prop_set, :date_prop_get),
127 ECNL::EProperty.new(0x9D, (ECNL::EPC_RULE_GET), @anno_prpmap.length, :@anno_prpmap, nil, :data_prop_get),
128 ECNL::EProperty.new(0x9E, (ECNL::EPC_RULE_GET), @set_prpmap.length, :@set_prpmap, nil, :data_prop_get),
129 ECNL::EProperty.new(0x9F, (ECNL::EPC_RULE_GET), @get_prpmap.length, :@get_prpmap, nil, :data_prop_get)
130 ]
131
132 super(0x05, 0xFF, eojx3, enod, eprpinib_table)
133 end
134
135 # 動作状æ…
136‹ON/OFF設定関数(0x30, 0x31のみ受け付け)
137 def onoff_prop_set(prop, src)
138 # サイズが1以外は受け付けない
139 if (src.bytesize != 1) then
140 return 0
141 end
142
143 if (prop.anno) then
144 prop.set_anno(prop.exinf != src)
145 end
146
147 case (src.getbyte(0))
148 # ONの場合
149 when 0x30 then
150 prop.set_exinf(src)
151 # LEDの"."をON
152 digitalWrite(1, 1)
153 # OFFの場合
154 when 0x31 then
155 prop.set_exinf(src)
156 # LEDの"."をOFF
157 digitalWrite(1, 0)
158 # 0x30か0x31以外は受け付けない
159 else
160 return 0
161 end
162
163 return 1
164 end
165
166 # 異常発生状æ…
167‹è¨­å®šé–¢æ•°ï¼ˆ0x41, 0x42のみ受け付け)
168 def alarm_prop_set(prop, src)
169 # サイズが1以外は受け付けない
170 if (src.bytesize != 1) then
171 return 0
172 end
173
174 if (prop.anno) then
175 prop.set_anno(prop.exinf != src)
176 end
177
178 case (src.getbyte(0))
179 # 異常発生あり/なしの場合
180 when 0x41,0x42 then
181 prop.set_exinf(src)
182 # 0x41か0x42以外は受け付けない
183 else
184 return 0
185 end
186
187 return 1
188 end
189
190 # 現在年月日取得関数
191 def date_prop_get(prop, size)
192 # サイズが4以外は受け付けない
193 if (size != 4) then
194 return 0
195 end
196
197 time = Rtc.getTime
198
199 return ((time[0] & 0xFF00) >> 8).chr + (time[0] & 0xFF).chr + time[1].chr + time[2].chr
200 end
201
202 # 現在年月日設定関数
203 def date_prop_set(prop, src)
204 # サイズが4以外は受け付けない
205 if (src.bytesize != 4) then
206 return 0
207 end
208
209 time = Rtc.getTime
210 time[0] = (src.getbyte(0) << 8) | src.getbyte(1)
211 time[1] = src.getbyte(2)
212 time[2] = src.getbyte(3)
213 Rtc.setTime time[0], time[1], time[2], time[3], time[4], time[5]
214
215 return 4
216 end
217
218 # 現在時刻取得関数
219 def time_prop_get(prop, size)
220 # サイズが2以外は受け付けない
221 if (size != 2) then
222 return 0
223 end
224
225 time = Rtc.getTime
226
227 return time[3].chr + time[4].chr
228 end
229
230 # 現在時刻設定関数
231 def time_prop_set(prop, src)
232 # サイズが2以外は受け付けない
233 if (src.bytesize != 2) then
234 return 0
235 end
236
237 time = Rtc.getTime
238 time[3] = src.getbyte(0)
239 time[4] = src.getbyte(1)
240 Rtc.setTime time[0], time[1], time[2], time[3], time[4], time[5]
241
242 return 2
243 end
244end
245
246class EcnlTask < ECNL::SvcTask
247 def initialize()
248 @profile = LocalNode.new(0x01)
249 @devices = [ Controller.new(0x01, @profile) ]
250 @enodadrb_table = []
251
252 super()
253
254 # LEDをOFF
255 pinMode(TargetBoard::LED_USER, 1)
256 digitalWrite(TargetBoard::LED_USER, 0)
257 digitalWrite(TargetBoard::LED_BLUE, 0)
258
259 set_timer(1000)
260 end
261
262 def recv_esv(esv)
263 if (esv.esv != ECNL::ESV_GET_RES) && (esv.esv != ECNL::ESV_GET_SNA) then
264 return
265 end
266
267 itr = esv.itr_ini()
268 itr.itr_nxt()
269 until itr.is_eof do
270 if itr.epc == 0xD6 then
271 # LEDをON
272 digitalWrite(TargetBoard::LED_USER, 1)
273 end
274 itr.itr_nxt()
275 end
276 end
277
278 def break_wait(data)
279 end
280
281 def timeout()
282 esv = esv_get(nil, 0xD6)
283 snd_esv(esv)
284
285 set_timer(10000)
286 end
287
288 def snd_msg(ep, data)
289 # 通信レイヤーへ送信
290 TargetBoard::snd_msg(ep, data)
291 end
292
293 def is_local_addr(ep)
294 TargetBoard::is_local_addr(ep)
295 end
296
297 def is_multicast_addr(ep)
298 TargetBoard::is_multicast_addr(ep)
299 end
300
301 def is_valid_addrid(id)
302 (id >= 0) && ((id - ECNL::ENOD_REMOTE_ID) < @enodadrb_table.length)
303 end
304
305 def get_local_addr()
306 TargetBoard::get_local_addr()
307 end
308
309 def get_multicast_addr()
310 TargetBoard::get_multicast_addr()
311 end
312
313 def get_remote_addr(id)
314 index = id - ECNL::ENOD_REMOTE_ID
315 if (index < 0) || (index >= @enodadrb_table.length)
316 nil
317 else
318 @enodadrb_table[index]
319 end
320 end
321
322 # 通信レイヤーアドレスの同じものを検索
323 def get_remote_id(ep)
324 id = ECNL::ENOD_REMOTE_ID - 1
325 for ea in @enodadrb_table do
326 id += 1
327 if !ea then
328 next
329 end
330 if !TargetBoard::equals_addr(ea, ep) then
331 next
332 end
333
334 return id
335 end
336
337 return ECNL::ENOD_NOT_MATCH_ID
338 end
339
340 # 対応するリモートノードを検索
341 def set_remote_addr(edata, ep)
342 id = ECNL::ENOD_REMOTE_ID - 1
343 for ea in @enodadrb_table do
344 id += 1
345 if !ea then
346 next
347 end
348 if !is_match(svc, edata, ep) then
349 next
350 end
351
352 # 対応するリモートノードがあれば通信レイヤーアドレスを設定
353 @enodadrb_table[id - ECNL::ENOD_REMOTE_ID] = ep
354
355 return id
356 end
357
358 return ECNL::ENOD_NOT_MATCH_ID
359 end
360
361 # 空き領域を探して自動登録
362 def add_remote_addr(edata, ep)
363 id = ECNL::ENOD_REMOTE_ID - 1
364 for ea in @enodadrb_table do
365 id += 1
366 if ea then
367 next
368 end
369
370 @enodadrb_table[id - ECNL::ENOD_REMOTE_ID] = ep
371
372 return id
373 end
374
375 if @enodadrb_table.length >= 100 then
376 return ECNL::ENOD_NOT_MATCH_ID
377 end
378
379 id = @enodadrb_table.length;
380 @enodadrb_table[id] = ep
381
382 return id + ECNL::ENOD_REMOTE_ID
383 end
384end
385
386ctrl = EcnlTask.new()
387
388# メインループ
389while (true) do
390 # メッセージ待
391ち
392 ret = TargetBoard::wait_msg(ctrl.timer)
393 if !ret then
394 break;
395 end
396
397 # 経過時間の計算
398 ctrl.progress ret[0]
399
400 # 戻り値が2つなら
401 if ret.length == 2 then
402 # 内
403部イベント
404 case (ret[1])
405 when 1 then
406 TargetBoard::restart
407 when 2 then
408 ctrl.ntf_inl
409 end
410 # 戻り値が3つなら
411 elsif ret.length == 3 then
412 # 通信レイヤーからのメッセージ(通信端点と電文)
413 ctrl.recv_msg(ret[1], ret[2])
414 end
415
416 # タイムアウトの処理があれば行う
417 ctrl.call_timeout
418end
Note: See TracBrowser for help on using the repository browser.