source: uKadecot/trunk/tools/EcnlControllerUI/EcnlControllerUI/CtrlUI.cs

Last change on this file was 125, checked in by coas-nagasima, 9 years ago

ECHONET Lite規格に準拠していない動作を修正。
WebSocketの接続先URLを/webapi.ashxから/webapiに変更。
DHCPのリトライ処理が行われていなかったのを修正。
DHCPの有効/無効設定を追加し、固定IPアドレスを設定できるよう変更。

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csharp
File size: 38.6 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2015 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id: CtrlUI.cs 125 2015-07-23 06:21:02Z coas-nagasima $
36 */
37
38using System;
39using System.Collections;
40using System.Collections.Generic;
41using System.Diagnostics;
42using System.Html;
43using System.Linq;
44using System.Net.WebSockets;
45using System.Serialization;
46using System.Text;
47using System.Text.RegularExpressions;
48using System.Web;
49using System.Xml;
50using control;
51using ctrlui;
52using jQueryApi;
53using Kadecot;
54
55public class CtrlUI
56{
57 public static CtrlUI Page;
58 public static Information Info;
59
60 public static void Main()
61 {
62 if (Page == null) {
63 Page = new CtrlUI();
64 Info = new Information();
65 }
66
67 jQuery.Document.On("pageinit", "#index", Page.InitClassGroups);
68 }
69
70 private static Element page;
71 private Dictionary<DeviceController.DeviceInfo, DeviceController.DeviceInfo> Read = new Dictionary<DeviceController.DeviceInfo, DeviceController.DeviceInfo>();
72
73 public static Element GetPage(Element ele)
74 {
75 var page = ele;
76 if (jQuery.Select(page).Is("[data-role=\"page\"]")) {
77 return page;
78 }
79 if (jQuery.Select(page).Parents("[data-role=\"page\"]").Length == 1) {
80 return jQuery.Select(page).Parents("[data-role=\"page\"]").GetElement(0);
81 }
82 return null;
83 }
84
85 /// <summary>クラスグループ(ClassGroupList.json)</summary>
86 static JsonClassGroupInfo[] m_ClassGroups;
87
88 /// <summary>クラス</summary>
89 static JsonClassInfo m_ProfileClassInfo;
90 static List<JsonClassInfo> m_Classes;
91
92 WampClient m_WampClient;
93 /// <summary>現在接続中の機器</summary>
94 DeviceController m_DeviceController;
95
96 private DeviceController.DeviceInfo _m_CurrentNode;
97
98 /// <summary>現在選択中のノード</summary>
99 DeviceController.DeviceInfo m_CurrentNode
100 {
101 get { return _m_CurrentNode; }
102 set
103 {
104 bool flag = (_m_CurrentNode != value) || (_m_CurrentNode == null && value == null);
105 _m_CurrentNode = value;
106
107 if (flag)
108 jQuery.Document.Trigger(UIEventNames.CurrentNodeChange);
109 }
110 }
111
112 /// <summary>
113 /// コンストラクタ
114 /// </summary>
115 public CtrlUI()
116 {
117 m_WampClient = new WampClient();
118 m_WampClient.addOpenCallback(WampClientConnected);
119 m_WampClient.addCloseCallback(WampClientDisconnected);
120 m_WampClient.connect("ws://" + Window.Location.Host + "/webapi");
121 }
122
123 /// <summary>
124 /// #indexページ読み込み時に実行
125 /// </summary>
126 /// <param name="ele"></param>
127 /// <param name="ev"></param>
128 private void InitClassGroups(jQueryEvent eve)
129 {
130 page = eve.Target;
131 SetEvent();
132
133 if (m_ClassGroups != null)
134 return;
135
136 DeviceController.GetClassInfo = GetClassInfoHandler;
137 m_CurrentNode = null;
138 string ClassGroupListUrl = "devices/ClassGroupList.json";
139 jQuery.Ajax(ClassGroupListUrl).Success(InitClassGroups).Error(
140 (request, textStatus, error) => {
141 AjaxError(request, textStatus, error, ClassGroupListUrl);
142 });
143 }
144
145 private void SetEvent()
146 {
147 jQuery.Document.On(UIEventNames.LoadingShow, UIEventHandler.LoadingShow);
148 jQuery.Document.On(UIEventNames.LoadingHide, UIEventHandler.LoadingHide);
149 jQuery.Document.On(UIEventNames.CurrentNodeChange, this.CurrentNodeChange);
150 jQuery.Document.On(UIEventNames.SearchStart, this.SearchStart);
151 jQuery.Document.On(UIEventNames.SearchEnd, this.SearchEnd);
152 jQuery.Document.On(UIEventNames.SearchError, this.SearchError);
153 jQuery.Document.On(UIEventNames.PropertyWriteStart, this.PropertyWriteStart);
154 jQuery.Document.On(UIEventNames.PropertyWriteEnd, this.PropertyWriteEnd);
155 ConnectionSwt.Change(Connect);
156 SetPropertyBtn.Click(SetProperty);
157 GetPropertyBtn.Click(GetProperty);
158 SetGetPropertyBtn.Click(SetGetProperty);
159 KadecotBtn.Click(KadecotClick);
160 PropertyList.Change(PropertyChange);
161 SetInitParamsBtn.Click(SetInitParams);
162 GetInitParamsBtn.Click(GetInitParams);
163 }
164
165 /// <summary>
166 /// "devices/ClassGroupList.json"ファイルの読み込みに成功したとき実行します
167 /// </summary>
168 /// <param name="data">ファイルのデータ</param>
169 private void InitClassGroups(object data)
170 {
171 List<JsonClassGroupInfo> classGroups = data.ToJSClassGroupInfoList();
172 //初期化
173 m_Classes = new List<JsonClassInfo>();
174 m_ClassGroups = classGroups.ToArray();
175 GetClassInfoHandler(T_ECN_EOJ.X1_PROFILE, T_ECN_EOJ.X2_NODE_PROFILE, GetClassInfoCallback);
176 }
177
178 /// <summary>
179 /// コールバック関数
180 /// </summary>
181 /// <param name="di"></param>
182 private void GetClassInfoCallback(JsonClassInfo di)
183 {
184 m_ProfileClassInfo = di;
185 }
186
187 /// <summary>
188 /// devices/ClassListxx.jsonファイルの読み込み
189 /// </summary>
190 /// <param name="x1">クラスグループコード</param>
191 /// <param name="x2">クラスコード</param>
192 /// <param name="cb">コールバック関数</param>
193 private void GetClassInfoHandler(byte x1, byte x2, DeviceController.GetClassInfoCallback cb)
194 {
195 JsonClassInfo eclass = m_Classes.FirstOrDefault(p => (p.classGroup.classGroupCode == x1) && (p.classCode == x2));
196
197 //すでにjsonファイルが読み込まれているので、ファイルを読み込まない。
198 if (eclass != null) {
199 if (eclass.properties == null)
200 GetPropertyList(eclass, cb);
201 else
202 cb(eclass);
203 return;
204 }
205 //eclass==nullの場合
206 JsonClassGroupInfo classGroup = m_ClassGroups.FirstOrDefault(p => (p.classGroupCode == x1));
207
208 string classListUrl = "devices/ClassList" + x1.ToString("X2").ToUpper() + ".json";
209
210 jQuery.Ajax(classListUrl).Success((data) => {
211 Debug.WriteLine(classListUrl + "読み込み成功");
212 GetClassInfoSuccess(data, x1, x2, classGroup, cb);
213 }).Error((request, textStatus, error) => {
214 Debug.WriteLine(classListUrl + "読み込み失敗");
215 GetClassInfoError(request, textStatus, error, eclass, cb, classListUrl);
216 });
217 }
218
219 /// <summary>
220 /// devices/ClassListxx.jsonファイルの取得に成功した時実行します。
221 /// </summary>
222 /// <param name="data"></param>
223 private void GetClassInfoSuccess(object data, byte x1, byte x2, JsonClassGroupInfo classGroup, DeviceController.GetClassInfoCallback cb)
224 {
225 List<JsonClassInfo> classes = data.ToJSClassInfoList(classGroup);
226 m_Classes.AddRange(classes);
227 JsonClassInfo eclass = m_Classes.FirstOrDefault(p => (p.classGroup.classGroupCode == x1) && (p.classCode == x2));
228 GetPropertyList(eclass, cb);
229 }
230
231 /// <summary>
232 /// devices/PropertyListxxxx.jsonファイルの取得
233 /// </summary>
234 /// <param name="data"></param>
235 private void GetPropertyList(JsonClassInfo eclass, DeviceController.GetClassInfoCallback cb)
236 {
237 string PropertyListUrl = "devices/PropertyList" + eclass.classGroup.classGroupCode.ToString("X2").ToUpper() + eclass.classCode.ToString("X2").ToUpper() + ".json";
238 Debug.WriteLine(PropertyListUrl + "読み込み");
239
240 jQuery.Ajax(PropertyListUrl).Success((data1) => {
241 Debug.WriteLine(PropertyListUrl + "読み込み成功");
242 GetPropertyListSuccess(data1, eclass);
243 }).Error((request, textStatus, error) => {
244 Debug.WriteLine(PropertyListUrl + "読み込み失敗");
245 PropertyListAjaxError(request, textStatus, error, eclass, cb, PropertyListUrl);
246 }).Complete((request, textStatus) => {
247 GetPropertyListComplete(request, textStatus, eclass, cb);
248 });
249 }
250
251 /// <summary>
252 /// devices/PropertyListxxxx.jsonファイルの取得に成功
253 /// </summary>
254 /// <param name="data"></param>
255 private void GetPropertyListSuccess(object data, JsonClassInfo eclass)
256 {
257 List<JsonPropertyInfo> properties = data.ToJSPropertyInfoList();
258 eclass.properties = properties.ToArray();
259 }
260
261 /// <summary>
262 /// devices/PropertyListxxxx.jsonファイルの取得後の処理
263 /// </summary>
264 /// <param name="request"></param>
265 /// <param name="textStatus"></param>
266 private void GetPropertyListComplete(jQueryXmlHttpRequest request, string textStatus, JsonClassInfo eclass, DeviceController.GetClassInfoCallback cb)
267 {
268 if (request.StatusText.Equals("OK")) {
269 cb(eclass);
270 }
271 }
272
273 /// <summary>
274 /// devices/ClassListxx.jsonファイルがなかった場合
275 /// </summary>
276 /// <param name="request"></param>
277 /// <param name="textStatus"></param>
278 /// <param name="error"></param>
279 private void GetClassInfoError(jQueryXmlHttpRequest request, string textStatus, Exception error,
280 JsonClassInfo eclass, DeviceController.GetClassInfoCallback cb, string url)
281 {
282 AjaxError(request, textStatus, error, url);
283 cb(eclass);
284 }
285
286 /// <summary>
287 /// PropertyListxxxx.jsonファイル読み込みエラー
288 /// </summary>
289 /// <param name="request"></param>
290 /// <param name="textStatus"></param>
291 /// <param name="error"></param>
292 private void PropertyListAjaxError(jQueryXmlHttpRequest request, string textStatus, dynamic error, JsonClassInfo eclass, DeviceController.GetClassInfoCallback cb, string url)
293 {
294 string PropertyListBaseUrl = "devices/PropertyListBase.json";
295 jQuery.Ajax(PropertyListBaseUrl).Success((data1) => {
296 Debug.WriteLine(PropertyListBaseUrl + "読み込み成功");
297 GetPropertyListSuccess(data1, eclass);
298 }).Error((request1, textStatus1, error1) => {
299 Debug.WriteLine(PropertyListBaseUrl + "読み込み失敗");
300 AjaxError(request1, textStatus1, error1, url);
301 }).Complete((request1, textStatus1) => {
302 GetPropertyListComplete(request1, textStatus1, eclass, cb);
303 });
304 }
305
306 /// <summary>
307 ///
308 /// </summary>
309 private void sendHello()
310 {
311 m_WampClient.sendHello("default", "{\"roles\":{\"caller\":{},\"subscriber\":{}}}", OnWelcom);
312 }
313
314 private void OnWelcom(object args)
315 {
316 m_WampClient.sendSubscribe("{}", "com.sonycsl.kadecot.echonetlite.topic.GeneralLighting.OperationStatus", OnSubscribed, OnSubscribed);
317 }
318
319 private void OnSubscribed(object args)
320 {
321 }
322
323 /// <summary>
324 /// 機器検索ボタンを押下したとき実行
325 /// </summary>
326 /// <param name="args"></param>
327 private void OnDevListed(object args)
328 {
329 int cmd = (int)((dynamic[])args)[0];
330 if (cmd != (int)WAMP_MSG_TYPE.RESULT) {
331 jQuery.Document.Trigger(UIEventNames.SearchError);
332 return;
333 }
334
335 //初期化
336 List<WampApiKadecotDevice> alldevs = args.GetAllDevices();
337 GetDeviceInfo(alldevs, 0, new List<DeviceController.NodeInfo>());
338 }
339
340 /// <summary>
341 /// 接続されている機器の設定値を取得
342 /// </summary>
343 /// <param name="alldevs"></param>
344 /// <param name="pos"></param>
345 private void GetDeviceInfo(List<WampApiKadecotDevice> alldevs, int pos, List<DeviceController.NodeInfo> m_NodeList)
346 {
347 WampApiKadecotDevice device = alldevs[pos];
348
349 WampClientCore.WampCallbackArgs callback = (args) => {
350 int cmd = (int)((dynamic[])args)[0];
351 if (cmd != (int)WAMP_MSG_TYPE.RESULT) {
352 jQuery.Document.Trigger(UIEventNames.SearchError);
353 return;
354 }
355
356 WebApiObjectInfo dev = new WebApiObjectInfo(device.deviceId, ((dynamic[])args)[4], false);
357
358 GetClassInfoHandler(dev.x1, dev.x2, (dc) => {
359 DeviceController.DeviceInfo di = dc.GetDeviceInfo(dev, device);
360 DeviceController.NodeInfo node = m_NodeList.FirstOrDefault((ni) => { return (string)ni.Data == device.ip_addr; });
361 if (node == null) {
362 var profile = new DeviceController.DeviceInfo(m_ProfileClassInfo, true, T_ECN_EOJ.X1_PROFILE, T_ECN_EOJ.X2_NODE_PROFILE, 1, dev.enodid);
363 node = new DeviceController.NodeInfo((ENOD_ID)dev.enodid, profile);
364 node.Data = device.ip_addr;
365 m_NodeList.Add(node);
366 }
367 node.Devices.Add(di);
368
369 pos++;
370 if (pos < alldevs.Count) {
371 GetDeviceInfo(alldevs, pos, m_NodeList);
372 }
373 else {
374 jQuery.Document.Trigger(UIEventNames.SearchEnd);
375 m_DeviceController = new DeviceController(m_NodeList);
376 UpdateUI();
377 }
378 });
379 };
380
381 if (device.protocol == "arduino") {
382 var arg = new
383 {
384 x1 = 0x0E,
385 x2 = 0xF0,
386 x3 = 0x01,
387 enodid = 0x01,
388 properties = new[] {
389 new{epc = 0x00, flag = "RULE_SET,RULE_GET", size = 0x01},
390 new{epc = 0x01, flag = "RULE_SET,RULE_GET", size = 0x01},
391 new{epc = 0x02, flag = "RULE_SET,RULE_GET", size = 0x01},
392 new{epc = 0x03, flag = "RULE_SET,RULE_GET", size = 0x01},
393 new{epc = 0x04, flag = "RULE_SET,RULE_GET", size = 0x01},
394 new{epc = 0x05, flag = "RULE_SET,RULE_GET", size = 0x01},
395 new{epc = 0x06, flag = "RULE_SET,RULE_GET", size = 0x01},
396 new{epc = 0x07, flag = "RULE_SET,RULE_GET", size = 0x01},
397 new{epc = 0x08, flag = "RULE_SET,RULE_GET", size = 0x01},
398 new{epc = 0x09, flag = "RULE_SET,RULE_GET", size = 0x01},
399 new{epc = 0x0A, flag = "RULE_SET,RULE_GET", size = 0x01},
400 new{epc = 0x0B, flag = "RULE_SET,RULE_GET", size = 0x01},
401 new{epc = 0x0C, flag = "RULE_SET,RULE_GET", size = 0x01},
402 new{epc = 0x0D, flag = "RULE_SET,RULE_GET", size = 0x01},
403 new{epc = 0x0E, flag = "RULE_GET", size = 0x01},
404 new{epc = 0x0F, flag = "RULE_GET", size = 0x01},
405 new{epc = 0x10, flag = "RULE_GET", size = 0x01},
406 new{epc = 0x11, flag = "RULE_GET", size = 0x01},
407 new{epc = 0x12, flag = "RULE_GET", size = 0x01},
408 new{epc = 0x13, flag = "RULE_GET", size = 0x01},
409 }
410 };
411 callback(new object[] { 50, 0, new { deviceId = 1 }, new object[0], arg });
412 }
413 else {
414 m_WampClient.sendCall("{\"deviceId\":" + device.deviceId + "}", "jp.toppers.ecnl.procedure.getDeviceInfo", null, null, callback);
415 }
416 }
417
418 /// <summary>
419 /// ノードリストを更新
420 /// </summary>
421 private void UpdateUI()
422 {
423 if (NodeList == null)
424 return;
425 NodeList.Html("");
426 NodeList.Append(m_DeviceController.GetUINodeList(listitem_Click));
427 NodeList.CollapsibleSet().CollapsibleSet("refresh");
428 jQuery.Select("ul[data-role='listview']", NodeList).ListView().ListView("refresh");
429 }
430
431 /// <summary>
432 /// コールバック関数
433 /// </summary>
434 /// <param name="args"></param>
435 private void OnResponse(object args)
436 {
437 int switchData = (int)((dynamic[])args)[0];
438 if (switchData != (int)WAMP_MSG_TYPE.RESULT) {
439 return;
440 }
441
442 dynamic doc = ((dynamic[])args)[4];
443 if (m_DeviceController != null) {
444 m_DeviceController.RecvResponse(new WebApiEchonetMessage(doc));
445 if (PropertyList == null)
446 return;
447
448 m_CurrentNode.GetData();
449 }
450 SetPropertyBtn.Disable(true);
451 }
452
453 private void OnSetResponse(object args)
454 {
455 dynamic doc = ((dynamic[])args)[4];
456 if (m_DeviceController != null) {
457 if (PropertyList == null)
458 return;
459 m_DeviceController.RecvResponse(new WebApiEchonetMessage(doc));
460 }
461 SetPropertyBtn.Disable(true);
462 }
463
464 /// <summary>
465 /// #li_device_XXXXXXをクリックしたとき
466 /// </summary>
467 /// <param name="elem"></param>
468 /// <param name="ev"></param>
469 private void listitem_Click(Element elem, jQueryEvent ev, DeviceController.DeviceInfo di)
470 {
471 if (PropertyList == null)
472 return;
473 m_CurrentNode = di;
474 }
475
476 /// <summary>
477 /// webapiと接続された時、機器検索のアイコンを切り替える
478 /// </summary>
479 private void WampClientConnected()
480 {
481 //接続スイッチがOFFの時、スイッチを切り替える
482 bool flag = ConnectionSwt.Prop("checked");
483 if (!flag) {
484 ConnectionSwt.Prop("checked", true).FlipSwitch("refresh");
485 }
486 SearchBtn.ToggleClass("ui-icon-alert", "ui-icon-refresh");
487 sendHello();
488 }
489
490 /// <summary>
491 /// webapiと切断されたとき、機器検索のアイコンを切り替える
492 /// </summary>
493 private void WampClientDisconnected()
494 {
495 SearchBtn.ToggleClass("ui-icon-refresh", "ui-icon-alert");
496 }
497
498 /// <summary>
499 /// 接続スイッチを変更
500 /// </summary>
501 /// <param name="ele"></param>
502 public void Connect(Element ele, jQueryEvent eve)
503 {
504 bool connect = jQuery.Select(ele).Prop("checked");
505
506 //接続スイッチがOn && m_WampClient.isConnecting() == false
507 if (connect && !m_WampClient.isConnecting()) {
508 Debug.WriteLine("m_WampClient.isConnecting():" + m_WampClient.isConnecting().ToString());
509 m_WampClient.connect("ws://" + Window.Location.Host + "/webapi");
510 }
511 //接続スイッチがOff && m_WampClient.isConnecting() ==true
512 else if (!connect && m_WampClient.isConnecting()) {
513 m_WampClient.disconnect();
514 // m_WampClient.sendGoodbye("{}", "wamp.error.system_shutdown",Disconnect);
515 }
516 }
517
518 /// <summary>
519 /// 切断
520 /// </summary>
521 /// <param name="args"></param>
522 public void Disconnect(object args)
523 {
524 m_WampClient.disconnect();
525 }
526
527 int TimerId = 0;
528
529 /// <summary>
530 /// 機器検索ボタンを押下
531 /// </summary>
532 /// <param name="ele"></param>
533 public void Search(Element ele, jQueryEvent ev)
534 {
535 jQuery.Document.Trigger(UIEventNames.SearchStart);
536 string data = m_WampClient.sendCall("{}", "com.sonycsl.kadecot.provider.procedure.getDeviceList",
537 null, null, OnDevListed);
538 if (data == null) {
539 jQuery.Document.Trigger(UIEventNames.SearchError);
540 return;
541 }
542 this.TimerId = Window.SetInterval(() => {
543 jQuery.Document.Trigger(UIEventNames.SearchError);
544 }, 20000);
545 }
546
547 public void SearchStart(jQueryEvent ev)
548 {
549 jQueryMobile.Loading("show", new LoadingOption("機器検索中...", true));
550 SearchBtn.Disable(true);
551 Debug.WriteLine("機器検索開始");
552 }
553
554 /// <summary>
555 /// 機器が見つかった時実行
556 /// </summary>
557 /// <param name="ev"></param>
558 public void SearchEnd(jQueryEvent ev)
559 {
560 if (this.TimerId != 0) {
561 Window.ClearInterval(this.TimerId);
562 this.TimerId = 0;
563 }
564
565 jQueryMobile.Loading("hide");
566 SearchBtn.Disable(false);
567 NodeList.Find("li .ui-icon-alert").ToggleClass("ui-icon-alert", "ui-icon-carat-r");
568
569 Debug.WriteLine("機器検索終了");
570 }
571
572 /// <summary>
573 /// 機器が見つからなかったとき実行
574 /// </summary>
575 /// <param name="ev"></param>
576 public void SearchError(jQueryEvent ev)
577 {
578 if (this.TimerId != 0) {
579 Window.ClearInterval(this.TimerId);
580 this.TimerId = 0;
581 }
582
583 jQueryMobile.Loading("hide");
584 jQuery.Select("#bt_search").RemoveAttr("disabled");
585 Debug.WriteLine("機器検索エラー");
586 Window.Alert("機器が見つかりませんでした");
587 NodeList.Find("li .ui-icon-carat-r").ToggleClass("ui-icon-carat-r", "ui-icon-alert");
588 }
589
590 public void PropertyWriteStart(jQueryEvent ev)
591 {
592 jQueryMobile.Loading("show");
593 }
594
595 public void PropertyWriteEnd(jQueryEvent ev)
596 {
597 //PropertyList.Find("li").Find(".ui-field-contain").Children(".ui-input-text").Each((i, ele) => {
598 // if (jQuery.Select(ele).Children(".ui-input-text").Length > 0) {
599 // jQuery.Select(ele).Children("a").Remove();
600 // jQuery.Select(ele).Children(".ui-input-text").Unwrap();
601 // }
602 //});
603 jQueryMobile.Loading("hide");
604 }
605
606 /// <summary>
607 /// 設定ボタンを押下
608 /// </summary>
609 /// <param name="ele"></param>
610 public void SetProperty(Element ele, jQueryEvent eve)
611 {
612 WebApiSet esv = new WebApiSet();
613 jQueryObject ctrls = PropertyList;
614
615 esv.deojid = (ENOD_ID)m_CurrentNode.EObjId;
616 bool enable = false;
617
618 foreach (var dpi in m_CurrentNode.Properties) {
619 if (dpi.InputData == null) {
620 continue;
621 }
622 else if (dpi.IsWaitRes) {
623 esv.AddEdt(dpi.PropertyCode, dpi.InputData);
624 enable = true;
625 }
626 }
627
628 if (!enable) {
629 return;
630 }
631 string call = m_WampClient.sendCall(esv.GetOption(), "jp.toppers.ecnl.procedure.set", "[]", esv.GetArguments(),
632 OnSetResponse);
633 if (call == null) {
634 Window.Alert("機器が接続されていません");
635 }
636 }
637
638 /// <summary>
639 /// 取得ボタンを押下
640 /// </summary>
641 /// <param name="ele"></param>
642 public void GetProperty(jQueryEvent eve)
643 {
644 string protocol = ((WampApiKadecotDevice)m_CurrentNode.Data).protocol;
645 if (protocol == "arduino") {
646 return;
647 }
648
649 WebApiGet esv = new WebApiGet();
650 //現在選択中のノードからEObjIDを取得
651 esv.deojid = (ENOD_ID)m_CurrentNode.EObjId;
652
653 //取得フラグ
654 bool enable = false;
655
656 foreach (var dpi in m_CurrentNode.Properties) {
657
658 if (dpi == null) {
659 continue;
660 }
661 dpi.IsWaitRes = false;
662
663 bool target = (dpi.Flag & EPC_FLAG.RULE_GET) != 0;
664
665 //読み込み禁止の場合
666 if (!target) {
667 dpi.ErrorText = "読み込み禁止です";
668 continue;
669 }
670 dpi.IsWaitRes = true;
671 esv.AddEpc(dpi.PropertyCode);
672 //読み込み可なのでtrue
673 enable = true;
674 }
675
676 if (!enable)
677 return;
678
679 string call = m_WampClient.sendCall(esv.GetOption(), "jp.toppers.ecnl.procedure.get", "[]", esv.GetArguments(),
680 OnResponse);
681 if (call == null) {
682 m_CurrentNode.GetDeviceBtn().ToggleClass("ui-icon-carat-r", "ui-icon-alert");
683 }
684 else {
685 m_CurrentNode.GetDeviceBtn().ToggleClass("ui-icon-alert", "ui-icon-carat-r");
686 }
687 }
688
689 /// <summary>
690 /// 設定と取得ボタンを押下
691 /// </summary>
692 /// <param name="ele"></param>
693 public void SetGetProperty(Element ele, jQueryEvent ev)
694 {
695 WebApiSet esv = new WebApiSet();
696
697 esv.deojid = (ENOD_ID)m_CurrentNode.EObjId;
698 bool enable = false;
699
700 foreach (var dpi in m_CurrentNode.Properties) {
701 if (dpi.InputData == null) {
702 continue;
703 }
704 else if (dpi.IsWaitRes) {
705 esv.AddEdt(dpi.PropertyCode, dpi.InputData);
706 enable = true;
707 }
708 }
709 if (!enable) {
710 return;
711 }
712 string call = m_WampClient.sendCall(esv.GetOption(), "jp.toppers.ecnl.procedure.setget", "[]", esv.GetArguments(),
713 OnResponse);
714 if (call == null) {
715 Window.Alert("機器が接続されていません");
716 }
717 }
718
719 /// <summary>
720 /// プロパティの値が変わった時
721 /// </summary>
722 /// <param name="ele"></param>
723 /// <param name="ev"></param>
724 public void PropertyChange(Element ele, jQueryEvent ev)
725 {
726 bool flag = m_CurrentNode.IsWait();
727 SetPropertyBtn.Disable(!flag);
728 SetGetPropertyBtn.Disable(!flag);
729 }
730
731 /// <summary>
732 /// Kadecotボタンをクリックした時に実行します
733 /// </summary>
734 /// <param name="ele"></param>
735 /// <param name="ev"></param>
736 public void KadecotClick(Element ele, jQueryEvent ev)
737 {
738 Window.Open("http://app.kadecot.net/index.html?kip=" + Window.Location.Hostname, "Kadecot");
739 }
740
741 DeviceController.DevicePropertyInfo dpi;
742
743 /// <summary>
744 /// 書き込み
745 /// </summary>
746 /// <param name="dpi"></param>
747 /// <param name="data"></param>
748 public void KadecotSet(DeviceController.DevicePropertyInfo dpi, byte[] data)
749 {
750 string propName;
751 if (dpi.PropertyCode == 0x80) {
752 propName = "OperationStatus";
753 }
754 else {
755 propName = "0x" + dpi.PropertyCode.ToString(16);
756 }
757
758 var di = m_CurrentNode;
759 if (di == null)
760 return;
761
762 this.dpi = dpi;
763 WampApiKadecotSet msg = new WampApiKadecotSet(di.EObjId, propName, data);
764
765 m_WampClient.sendCall(msg.GetOption(), "com.sonycsl.kadecot.echonetlite.procedure.set", "[]", msg.GetArguments(), KadecotSet);
766 }
767
768 /// <summary>
769 /// 書き込み
770 /// </summary>
771 /// <param name="args"></param>
772 private void KadecotSet(object args)
773 {
774 var di = m_CurrentNode;
775 dynamic doc = ((dynamic[])args)[4];
776
777 var res = new WampApiKadecotRes(doc);
778
779 if (m_DeviceController != null) {
780 m_DeviceController.RecvResponse(di, /*ESV_SET_RES*/0x71, this.dpi.PropertyCode, res.propertyValue);
781 }
782 }
783
784 public void KadecotGet(DeviceController.DevicePropertyInfo dpi)
785 {
786 string propName;
787 if (dpi.PropertyCode == 0x80) {
788 propName = "OperationStatus";
789 }
790 else {
791 propName = "0x" + dpi.PropertyCode.ToString(16);
792 }
793
794 var di = m_CurrentNode;
795 if (di == null)
796 return;
797
798 WampApiKadecotGet msg = new WampApiKadecotGet(di.EObjId, propName);
799 this.dpi = dpi;
800 m_WampClient.sendCall(msg.GetOption(), "com.sonycsl.kadecot.echonetlite.procedure.get", "[]", msg.GetArguments(), KadecotGet);
801 }
802
803 public void KadecotGet(object args)
804 {
805 var di = m_CurrentNode;
806 dynamic doc = ((dynamic[])args)[4];
807
808 var res = new WampApiKadecotRes(doc);
809
810 if (m_DeviceController != null) {
811 m_DeviceController.RecvResponse(di, /*ESV_GET_RES*/0x72, dpi.PropertyCode, res.propertyValue);
812 }
813 }
814
815 /// <summary>
816 /// 通信エラー発生時処理
817 /// </summary>
818 /// <param name="request"></param>
819 /// <param name="textStatus"></param>
820 /// <param name="error"></param>
821 private static void AjaxError(jQueryXmlHttpRequest request, string textStatus, dynamic error, string url)
822 {
823 var sep = new Regex("(\r\n|\r|\n)");
824 var lines = new List<string>();
825
826 lines.Add(textStatus);
827 if (error is string) {
828 lines.Add((string)error);
829 }
830 else {
831 lines.Add(error.message);
832
833 string stack = error.stack;
834 lines.AddRange(stack.Split(sep));
835 }
836
837 var html = jQuery.FromHtml("<p>");
838 foreach (var line in lines) {
839 if (sep.Exec(line) != null)
840 continue;
841 html.Append(Document.CreateTextNode(line).WholeText);
842 html.Append(jQuery.FromHtml("<br/>"));
843 }
844 html.Append(url + "の読み込みに失敗しました");
845 jQuery.Select("#popup_dialog_caption").Text("通信エラー");
846 jQuery.Select("#popup_dialog_title").Text("通信エラーが発生しました");
847 jQuery.Select("#popup_dialog_text").Html(html);
848 jQuery.Select("#popup_dialog").Popup("open", new { transition = "slidedown" });
849 }
850
851 /// <summary>
852 /// 設定・取得ボタンの有効・無効設定
853 /// </summary>
854 private void CurrentNodeChange(Element elem, jQueryEvent ev)
855 {
856 ButtonDisabled(m_CurrentNode);
857
858 if (m_CurrentNode == null) {
859 return;
860 }
861 PropertyCreate(m_CurrentNode);
862 GetProperty(ev);
863 return;
864 }
865
866 /// <summary>
867 /// 設定・取得ボタンを設定します
868 /// </summary>
869 /// <param name="di"></param>
870 private void ButtonDisabled(DeviceController.DeviceInfo di)
871 {
872 if (di == null) {
873 SetGetPropertyBtn.Disable(true);
874 GetPropertyBtn.Disable(true);
875 SetPropertyBtn.Disable(true);
876 return;
877 }
878
879 var ctrls = PropertyList;
880
881 SetGetPropertyBtn.Disable(ctrls == null);
882 GetPropertyBtn.Disable(ctrls == null);
883 SetPropertyBtn.Disable(ctrls == null);
884 }
885
886 /// <summary>
887 /// 入力画面を作成
888 /// </summary>
889 /// <param name="di"></param>
890 private void PropertyCreate(DeviceController.DeviceInfo di)
891 {
892 if (di == null) {
893 return;
894 }
895 jQuery.Document.Trigger(UIEventNames.PropertyWriteStart);
896 di.SetUIDevice(this);
897
898 PropertyList.Html("");
899 PropertyList.Append(di.GetPropertys());
900 PropertyList.ListView().ListView("refresh");
901 PropertyList.ListView().Trigger("create");
902
903 jQuery.Document.Trigger(UIEventNames.PropertyWriteEnd);
904 }
905
906 /// <summary>
907 /// 初期値設定ボタン
908 /// </summary>
909 /// <param name="elem"></param>
910 /// <param name="e"></param>
911 private void SetInitParams(Element elem, jQueryEvent e)
912 {
913 var macaddrfrm = new Regex("([0-9A-Fa-f]{2}):([0-9A-Fa-f]{2}):([0-9A-Fa-f]{2}):([0-9A-Fa-f]{2}):([0-9A-Fa-f]{2}):([0-9A-Fa-f]{2})");
914 var ipaddrfrm = new Regex("([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3}).([0-9]{1,3})");
915
916 var m = macaddrfrm.Exec(MacAddrTxt.GetValue());
917 if (m == null)
918 return;
919
920 var macAddr = "\"macAddr\":["
921 + Byte.Parse(m[1], 16) + ","
922 + Byte.Parse(m[2], 16) + ","
923 + Byte.Parse(m[3], 16) + ","
924 + Byte.Parse(m[4], 16) + ","
925 + Byte.Parse(m[5], 16) + ","
926 + Byte.Parse(m[6], 16) + "]";
927
928 var dhcpEnable = "\"dhcpEnable\":" + DhcpEnableCb.Prop("checked").ToString();
929
930 m = ipaddrfrm.Exec(IpAddrTxt.GetValue());
931 if (m == null)
932 return;
933
934 var ipAddr = "\"ipAddr\":["
935 + Byte.Parse(m[1]) + ","
936 + Byte.Parse(m[2]) + ","
937 + Byte.Parse(m[3]) + ","
938 + Byte.Parse(m[4]) + "]";
939
940
941 m = ipaddrfrm.Exec(NetmaskTxt.GetValue());
942 if (m == null)
943 return;
944
945 var netmask = "\"netmask\":["
946 + Byte.Parse(m[1]) + ","
947 + Byte.Parse(m[2]) + ","
948 + Byte.Parse(m[3]) + ","
949 + Byte.Parse(m[4]) + "]";
950
951
952 m = ipaddrfrm.Exec(GatewayTxt.GetValue());
953 if (m == null)
954 return;
955
956 var gateway = "\"gateway\":["
957 + Byte.Parse(m[1]) + ","
958 + Byte.Parse(m[2]) + ","
959 + Byte.Parse(m[3]) + ","
960 + Byte.Parse(m[4]) + "]";
961
962 m_WampClient.sendCall("{}", "jp.toppers.ecnl.procedure.setInitParams", "[]",
963 "{" + macAddr + "," + dhcpEnable + "," + ipAddr + "," + netmask + "," + gateway + "}", SetInitParamsRes);
964 }
965
966 public void SetInitParamsRes(object args)
967 {
968 int cmd = (int)((dynamic[])args)[0];
969 if (cmd != (int)WAMP_MSG_TYPE.RESULT) {
970 jQuery.Select("#popup_dialog_caption").Text("エラー");
971 jQuery.Select("#popup_dialog_title").Text("エラーが発生しました");
972 jQuery.Select("#popup_dialog_text").Text("初期データの書き込みに失敗しました。");
973 jQuery.Select("#popup_dialog").Popup("open", new { transition = "slidedown" });
974 return;
975 }
976
977 jQuery.Select("#popup_dialog_caption").Text("初期データ");
978 jQuery.Select("#popup_dialog_title").Text("初期データを書き込みました");
979 jQuery.Select("#popup_dialog_text").Text("初期データの書き込みに成功しました。");
980 jQuery.Select("#popup_dialog").Popup("open", new { transition = "slidedown" });
981 }
982
983 /// <summary>
984 /// 初期値設定ボタン
985 /// </summary>
986 /// <param name="elem"></param>
987 /// <param name="e"></param>
988 private void GetInitParams(Element elem, jQueryEvent e)
989 {
990 m_WampClient.sendCall("{}", "jp.toppers.ecnl.procedure.getInitParams", "[]", "{}", GetInitParamsRes);
991 }
992
993 public void GetInitParamsRes(object args)
994 {
995 int cmd = (int)((dynamic[])args)[0];
996 if (cmd != (int)WAMP_MSG_TYPE.RESULT) {
997 jQuery.Select("#popup_dialog_caption").Text("エラー");
998 jQuery.Select("#popup_dialog_title").Text("エラーが発生しました");
999 jQuery.Select("#popup_dialog_text").Text("初期データの読み込みに失敗しました。");
1000 jQuery.Select("#popup_dialog").Popup("open", new { transition = "slidedown" });
1001 return;
1002 }
1003
1004 dynamic param = ((dynamic[])args)[4];
1005 var macaddr = (byte[])(param.macAddr);
1006 MacAddrTxt.Value(String.Format("{0:X02}:{1:X02}:{2:X02}:{3:X02}:{4:X02}:{5:X02}",
1007 macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]));
1008
1009 var dhcpEnable = (bool)(param.dhcpEnable);
1010 DhcpEnableCb.Prop("checked", dhcpEnable).CheckboxRadio("refresh");
1011
1012 var ipaddr = (byte[])(param.ipAddr);
1013 IpAddrTxt.Value(String.Format("{0}:{1}:{2}:{3}",
1014 ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]));
1015
1016 var netmask = (byte[])(param.netmask);
1017 NetmaskTxt.Value(String.Format("{0}:{1}:{2}:{3}",
1018 netmask[0], netmask[1], netmask[2], netmask[3]));
1019
1020 var gateway = (byte[])(param.gateway);
1021 GatewayTxt.Value(String.Format("{0}:{1}:{2}:{3}",
1022 gateway[0], gateway[1], gateway[2], gateway[3]));
1023 }
1024
1025 /// <summary>設定ボタン</summary>
1026 public jQueryObject SetPropertyBtn { get { return jQuery.Select("#bt_set_property", page); } }
1027
1028 /// <summary>取得ボタン</summary>
1029 public jQueryObject GetPropertyBtn { get { return jQuery.Select("#bt_get_property", page); } }
1030
1031 /// <summary>設定と取得ボタン</summary>
1032 public jQueryObject SetGetPropertyBtn { get { return jQuery.Select("#bt_set_get_property", page); } }
1033
1034 /// <summary>Kadecotボタン</summary>
1035 public jQueryObject KadecotBtn { get { return jQuery.Select("#bt_kadecot", page); } }
1036
1037 /// <summary>接続スイッチ</summary>
1038 public jQueryObject ConnectionSwt { get { return jQuery.Select("#fs_connection", page); } }
1039
1040 /// <summary>プロパティリスト</summary>
1041 public jQueryObject PropertyList { get { return jQuery.Select("#lv_property_list", page); } }
1042
1043 /// <summary>機器検索ボタン</summary>
1044 public jQueryObject SearchBtn { get { return jQuery.Select("#bt_search", page); } }
1045
1046 /// <summary>ノードリスト</summary>
1047 public jQueryObject NodeList { get { return jQuery.Select("#node_list", page); } }
1048
1049 /// <summary>groupBox</summary>
1050 public jQueryObject PropertyGroupBox { get { return jQuery.Select("#lv_property_list", page).Find("li"); } }
1051
1052 /// <summary>初期値設定ボタン</summary>
1053 public jQueryObject SetInitParamsBtn { get { return jQuery.Select("#bt_set_init_params", page); } }
1054
1055 /// <summary>初期値取得ボタン</summary>
1056 public jQueryObject GetInitParamsBtn { get { return jQuery.Select("#bt_get_init_params", page); } }
1057
1058 /// <summary>MACアドレス入力</summary>
1059 public jQueryObject MacAddrTxt { get { return jQuery.Select("#txt_mac_addr", page); } }
1060
1061 /// <summary>DHCP有効/無効</summary>
1062 public jQueryObject DhcpEnableCb { get { return jQuery.Select("#cb_dhcp_enable", page); } }
1063
1064 /// <summary>IPアドレス入力</summary>
1065 public jQueryObject IpAddrTxt { get { return jQuery.Select("#txt_ip_addr", page); } }
1066
1067 /// <summary>サブネットマスク入力</summary>
1068 public jQueryObject NetmaskTxt { get { return jQuery.Select("#txt_netmask", page); } }
1069
1070 /// <summary>デフォルトゲートウェイ入力</summary>
1071 public jQueryObject GatewayTxt { get { return jQuery.Select("#txt_gateway", page); } }
1072
1073 public void pinMode_Change(UIFieldSet fieldset, int pin)
1074 {
1075 string value = fieldset.CheckdValue();
1076 JsDictionary dic = new JsDictionary("pin", pin, "mode", value);
1077 m_WampClient.sendCall("{\"deviceId\":" + 1 + "}", "com.sonycsl.kadecot.arduino.pinMode", "[]", Json.Stringify(dic), pinMode);
1078 }
1079
1080 public void digital_Change(UIButton button, UIFlipSwitch flipswitch, int pin)
1081 {
1082 WampApiKadecotSet msg = new WampApiKadecotSet(1, "2", new byte[2]);
1083 JsDictionary dic = new JsDictionary("pin", pin, "value", flipswitch.Value);
1084 m_WampClient.sendCall("{\"deviceId\":" + 1 + "}", "com.sonycsl.kadecot.arduino.digitalWrite", "[]", Json.Stringify(dic), digitalWrite);
1085 }
1086
1087 public void analogWrite_Change(UIRangeInput range, int pin)
1088 {
1089 WampApiKadecotSet msg = new WampApiKadecotSet(1, "2", new byte[2]);
1090 JsDictionary dic = new JsDictionary("pin", pin, "value", range.Value);
1091 m_WampClient.sendCall("{\"deviceId\":" + 1 + "}", "com.sonycsl.kadecot.arduino.analogWrite", "[]", Json.Stringify(dic), pinMode);
1092 }
1093
1094 public void analogRead(UIRangeInput range, int pin)
1095 {
1096 JsDictionary dic = new JsDictionary("pin", pin);
1097 m_WampClient.sendCall("{\"deviceId\":" + 1 + "}", "com.sonycsl.kadecot.arduino.analogRead", "[]", Json.Stringify(dic), (args) => { digitalRead(args, range); });
1098 }
1099
1100 public void pinMode(object args)
1101 {
1102 int switchData = (int)((dynamic[])args)[0];
1103 if (switchData != (int)WAMP_MSG_TYPE.RESULT) {
1104 return;
1105 }
1106 dynamic doc = ((dynamic[])args)[4];
1107 if (m_DeviceController != null) {
1108 if (PropertyList == null)
1109 return;
1110 }
1111 }
1112
1113 public void digitalWrite(object args)
1114 {
1115 int switchData = (int)((dynamic[])args)[0];
1116 if (switchData != (int)WAMP_MSG_TYPE.RESULT) {
1117 return;
1118 }
1119 dynamic doc = ((dynamic[])args)[4];
1120 if (m_DeviceController != null) {
1121 if (PropertyList == null)
1122 return;
1123 }
1124 }
1125
1126 public void DigitalRead(UIButton button, UIFlipSwitch flip, int i)
1127 {
1128 JsDictionary dic = new JsDictionary("pin", i);
1129 string str = m_WampClient.sendCall("{\"deviceId\":" + 1 + "}", "com.sonycsl.kadecot.arduino.digitalRead", "[]", Json.Stringify(dic), (arg) => { digitalRead(arg, flip); });
1130 if (str == null) {
1131 button.ToggleClass("ui-icon-refresh", "ui-icon-alert");
1132 }
1133 else {
1134 button.ToggleClass("ui-icon-alert", "ui-icon-refresh");
1135 }
1136 }
1137
1138 public void digitalRead(object args, UIObject uiobject)
1139 {
1140 int switchData = (int)((dynamic[])args)[0];
1141 if (switchData != (int)WAMP_MSG_TYPE.RESULT) {
1142 return;
1143 }
1144 dynamic doc = ((dynamic[])args)[4];
1145 if (m_DeviceController != null) {
1146
1147 WebApiGrsaguraMessage msg = new WebApiGrsaguraMessage(doc);
1148 if (uiobject.GetType() == typeof(UIFlipSwitch)) {
1149 UIFlipSwitch flip = (UIFlipSwitch)uiobject;
1150 flip.Value = msg.value;
1151 }
1152 else if (uiobject.GetType() == typeof(UIRangeInput)) {
1153 UIRangeInput range = (UIRangeInput)uiobject;
1154 range.Value = int.Parse(msg.value);
1155 range.Object.Slider("refresh");
1156 }
1157 }
1158 }
1159}
1160
1161namespace ctrlui
1162{
1163 public class Information
1164 {
1165 private jQueryObject info;
1166
1167 public Information()
1168 {
1169 }
1170
1171 public void Update(Element ele, string id)
1172 {
1173 var page = CtrlUI.GetPage(ele);
1174
1175 this.info = jQuery.Select("#" + id, page);
1176 if (this.info == null)
1177 return;
1178 jQuery.Ajax("./" + id + ".json").Success(this.Success).Error(this.Error);
1179 }
1180
1181 private void Success(object data, string textStatus, jQueryXmlHttpRequest request)
1182 {
1183 var items = (dynamic[])((data.GetType() == typeof(string)) ? jQuery.ParseJson((string)data) : data);
1184
1185 var listview = new UIListview("data-inset", true, "data-theme", "b").Object;
1186 listview.Append(new UIListDivider("ソフトウェア情報").Object);
1187
1188 foreach (var item in items) {
1189 string title = item.title;
1190 string version = item.version;
1191 string link = item.link;
1192 string note = item.note;
1193
1194 UIAnchor a;
1195 if (String.IsNullOrEmpty(link)) {
1196 a = new UIAnchor(new UIH(2, title));
1197 a.Href = "#";
1198 }
1199 else {
1200 a = new UIAnchor(new UIH(2, title));
1201 a.Href = link;
1202 a.Target = "_blank";
1203 }
1204 a.Append(new UIP("Version " + version));
1205 if (!String.IsNullOrEmpty(note))
1206 a.Append(new UIP(note));
1207 listview.Append(new UIListviewItem(a).Object);
1208 }
1209 UIAnchor anchor = new UIAnchor();
1210 anchor.Target = "_blank";
1211 anchor.Href = "http://www.core-s.co.jp";
1212 anchor.Append(new UIImg("src", "imgs/core-s.svg").Object).Append("コアーズ株式会社");
1213
1214 var listitem = new UIListDivider(anchor).Object;
1215
1216 listview.Append(listitem);
1217 this.info.Html("");
1218 this.info.Append(listview);
1219
1220 jQuery.Select("ul", this.info).ListView().ListView("refresh");
1221 this.info.Popup("reposition", new { positionTo = "origin" });
1222 }
1223
1224 private void Error(jQueryXmlHttpRequest request, string textStatus, Exception error)
1225 {
1226 jQueryObject listview = new UIListview("data-inset", "true", "data-theme", "b").Object;
1227 listview.Append(new UIListDivider("ソフトウェア情報").Object);
1228 listview.Append(new UIListviewItem(new UIP("通信エラー")).Object);
1229
1230 this.info.Append(listview);
1231 jQuery.Select("ul", this.info).ListView().ListView("refresh");
1232 this.info.Popup("reposition", new { positionTo = "origin" });
1233 }
1234 }
1235}
Note: See TracBrowser for help on using the repository browser.