IEEE1888 GateWay sample that handles multiple sensors.
Dependencies: EthernetInterface Fiap HTTPClientForFIAP NTPClient mbed-rtos mbed spxml
Fork of IEEE1888_TEMP_NODE by
This program sends data to FIAP storage with IEEE1888 format.
Note: You should locate storage.txt into mbed memory at least before using this program. The storage.txt contains storage url, see example at main.h
You can launch an AMI ( Amazon Machine Image ) on Amazon Web Service ( http://aws.amazon.com/ ) as the FIAP storage. The AMI is named as "IEEE1888 FiapStorage2 Sample", registered at Tokyo region (ap-northeast-1) .
If You need more information about the AMI, see http://d.hatena.ne.jp/satoruyoshida/20130611/1370961807 .
This image shows sample data of IEEE1888 format.
Note: this image is shown if FIAP_DEBUG_MODE is set to true.
You can define COUNT_OF_POINTS constant as number of analog sensors and digital inputs. In this program, I use P19 and P20 as analog inputs from 2 sensors. So I define the COUNT_OF_POINTS as 2.
P19 is connected to illuminance sensor, S9648 (HAMAMATSU PHOTONICS K.K.). And P20 is connected to temperature sensor, LM35 (National Semiconductor Corporation) .
You can also use another analog sensors and digital inputs, for example LM61BIZ instead of LM35.
from here, in Japanese. このプログラムは IEEE1888 形式で FIAP Storage にデータ送信する例です。 このプログラムを使用する前に、少なくとも FIAP Storage の url を記載した sotrage.txt をメモリに格納しておく必要があります。 url の例は、 main.h ファイルにあります。
Amazon Web Service に用意した AMI を利用して FIAP Storage を起動することができます。IEEE1888 FiapStorage2 Sample という名前の公開 AMI です。
この AMI について詳しくは、http://d.hatena.ne.jp/satoruyoshida/20130611/1370961807 をご覧ください。
なお、main.h にはほかにも定数があります。例えば、IEEE1888 (FIAP) の通信内容をコンソールで確認したい場合は、FIAP_DEBUG_MODE を true にします。 また、アナログ・センサーやデジタル入力の個数に沿って、COUNT_OF_POINTS を定義します。
このプログラム例では、P19 および P20 をセンサーからのアナログ入力として使用しています。そのため、COUNT_OF_POINTS を 2 と定義しています。 P19 には浜松ホトニクス社製の照度センサー S9648、P20 にはナショナル・セミコンダクターの温度センサー LM35 を接続しています。 参考までに LM35 をより安価な LM61BIZ に置き換えた場合の設定値もコメントアウト状態で入れてあります
(ここから日本語文のみの内容) トランジスタ技術 2012年 2月号 の P189 - P195 に、Arduino、Ethernet シールド、温度センサー(LM35)、照度センサー(S9648-100)、DIP スイッチおよびトグルスイッチを用いたネットワーク温度&照度計の記事が掲載されています(落合 秀也 様/井上 博之 様)。 このプログラムでは、照度センサーは S9648-100 ではなく、より安価な S9648 で代用し、スイッチ 2 種類は省略していますのでご注意ください。 S9648 の負荷抵抗 1KΩ に並列に入れたコンデンサーは、手元に余っていた 0.1μF です。この容量が妥当かどうかは未検証です。
LM35 の出力をアンプで6倍に増幅してみたときのメモがここにあります。
https://mbed.org/users/strysd/notebook/memo_analog_input_from_lm35dz_via_nju7032d/
照度センサーを S9648-100 に変えて、抵抗値も検討したときのメモはこちら。
https://mbed.org/users/strysd/notebook/difference_s9648_and_s9648_100/
main.cpp@18:f277fbbcea4b, 2013-02-20 (annotated)
- Committer:
- strysd
- Date:
- Wed Feb 20 16:13:50 2013 +0000
- Revision:
- 18:f277fbbcea4b
- Parent:
- 17:868a61434584
- Child:
- 20:44214878a602
make storage url is set from file, and clock down.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
strysd | 6:cccef292257b | 1 | #include "main.h" |
yueee_yt | 0:27cf9683af17 | 2 | #include "mbed.h" |
yueee_yt | 0:27cf9683af17 | 3 | #include "EthernetInterface.h" |
yueee_yt | 0:27cf9683af17 | 4 | #include "NTPClient.h" |
yueee_yt | 0:27cf9683af17 | 5 | #include "fiap.h" |
yueee_yt | 0:27cf9683af17 | 6 | |
yueee_yt | 0:27cf9683af17 | 7 | EthernetInterface eth; |
yueee_yt | 0:27cf9683af17 | 8 | time_t ctTime; |
strysd | 18:f277fbbcea4b | 9 | Serial pc(USBTX, USBRX); |
strysd | 18:f277fbbcea4b | 10 | FIAP fiap; |
yueee_yt | 0:27cf9683af17 | 11 | |
strysd | 17:868a61434584 | 12 | //AnalogIn ain_p15(p15); |
strysd | 17:868a61434584 | 13 | //AnalogIn ain_p16(p16); |
strysd | 17:868a61434584 | 14 | //AnalogIn ain_p17(p17); |
strysd | 17:868a61434584 | 15 | //AnalogIn ain_p18(p18); |
strysd | 13:4e51ac520b33 | 16 | AnalogIn ain_p19(p19); |
strysd | 13:4e51ac520b33 | 17 | AnalogIn ain_p20(p20); |
strysd | 4:f50c307c5eda | 18 | |
strysd | 13:4e51ac520b33 | 19 | DigitalOut led1(LED1);//error while connecting to NTP server or FIAPStorage |
strysd | 8:e482433c9593 | 20 | DigitalOut led2(LED2);//sendFIAP |
strysd | 8:e482433c9593 | 21 | DigitalOut led3(LED3);//LAN speed (1 = error) |
strysd | 8:e482433c9593 | 22 | DigitalOut led4(LED4);//LAN link (1 = error) |
strysd | 4:f50c307c5eda | 23 | |
strysd | 8:e482433c9593 | 24 | DigitalIn lnk(P1_25);//LAN link |
strysd | 8:e482433c9593 | 25 | DigitalIn spd(P1_26);//LAN speed |
strysd | 9:0d34968a5de1 | 26 | DigitalOut speed(p29);//LAN speed for RJ45 (1 = OK) |
strysd | 9:0d34968a5de1 | 27 | DigitalOut link(p30); //LAN link for RJ45 (1 = OK) |
strysd | 8:e482433c9593 | 28 | |
strysd | 8:e482433c9593 | 29 | int exitTimer; |
strysd | 17:868a61434584 | 30 | int i; |
strysd | 13:4e51ac520b33 | 31 | |
strysd | 18:f277fbbcea4b | 32 | char storage_url[100];//define longer than actual length |
strysd | 18:f277fbbcea4b | 33 | struct fiap_element element[]= { |
strysd | 18:f277fbbcea4b | 34 | {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, |
strysd | 18:f277fbbcea4b | 35 | }; |
strysd | 18:f277fbbcea4b | 36 | struct tm t; |
strysd | 18:f277fbbcea4b | 37 | |
strysd | 17:868a61434584 | 38 | char val_p15[6]; |
strysd | 17:868a61434584 | 39 | char val_p16[6]; |
strysd | 17:868a61434584 | 40 | char val_p17[6]; |
strysd | 17:868a61434584 | 41 | char val_p18[6]; |
strysd | 13:4e51ac520b33 | 42 | char val_p19[6]; |
strysd | 13:4e51ac520b33 | 43 | char val_p20[6]; |
strysd | 13:4e51ac520b33 | 44 | |
strysd | 17:868a61434584 | 45 | float float_p15_wrk; |
strysd | 17:868a61434584 | 46 | float float_p16_wrk; |
strysd | 17:868a61434584 | 47 | float float_p17_wrk; |
strysd | 17:868a61434584 | 48 | float float_p18_wrk; |
strysd | 17:868a61434584 | 49 | float float_p19_wrk; |
strysd | 17:868a61434584 | 50 | float float_p20_wrk; |
strysd | 17:868a61434584 | 51 | |
strysd | 17:868a61434584 | 52 | float float_p15; |
strysd | 17:868a61434584 | 53 | float float_p16; |
strysd | 17:868a61434584 | 54 | float float_p17; |
strysd | 17:868a61434584 | 55 | float float_p18; |
strysd | 13:4e51ac520b33 | 56 | float float_p19; |
strysd | 13:4e51ac520b33 | 57 | float float_p20; |
strysd | 13:4e51ac520b33 | 58 | |
strysd | 9:0d34968a5de1 | 59 | //if you set LEDs for LAN indicator in real time. |
strysd | 9:0d34968a5de1 | 60 | /* |
strysd | 9:0d34968a5de1 | 61 | Ticker flipper; |
strysd | 9:0d34968a5de1 | 62 | |
strysd | 9:0d34968a5de1 | 63 | void myflip() { |
strysd | 9:0d34968a5de1 | 64 | led3 = spd; |
strysd | 9:0d34968a5de1 | 65 | led4 = lnk; |
strysd | 17:868a61434584 | 66 | if(USE_RJ45_LAMP == true){ |
strysd | 17:868a61434584 | 67 | speed = !spd; |
strysd | 17:868a61434584 | 68 | link = !lnk; |
strysd | 17:868a61434584 | 69 | } |
strysd | 9:0d34968a5de1 | 70 | } |
strysd | 9:0d34968a5de1 | 71 | */ |
strysd | 9:0d34968a5de1 | 72 | |
strysd | 18:f277fbbcea4b | 73 | int syncNTP(void) |
strysd | 18:f277fbbcea4b | 74 | { |
strysd | 18:f277fbbcea4b | 75 | NTPClient ntp; |
strysd | 18:f277fbbcea4b | 76 | if (ntp.setTime(NTP_SERVER) != 0) { |
strysd | 18:f277fbbcea4b | 77 | return -1; |
strysd | 18:f277fbbcea4b | 78 | } |
strysd | 18:f277fbbcea4b | 79 | ctTime = time(NULL); |
strysd | 18:f277fbbcea4b | 80 | ctTime+= TIME_ZONE_SECONDS; |
strysd | 18:f277fbbcea4b | 81 | set_time(ctTime); |
strysd | 18:f277fbbcea4b | 82 | return 0; |
strysd | 18:f277fbbcea4b | 83 | } |
strysd | 18:f277fbbcea4b | 84 | |
strysd | 18:f277fbbcea4b | 85 | int setFIAPStorage(void ) |
strysd | 18:f277fbbcea4b | 86 | { |
strysd | 18:f277fbbcea4b | 87 | LocalFileSystem local("local"); |
strysd | 18:f277fbbcea4b | 88 | FILE *fp; |
strysd | 18:f277fbbcea4b | 89 | fp = fopen("/local/storage.txt", "r"); |
strysd | 18:f277fbbcea4b | 90 | if(fp == NULL){ |
strysd | 18:f277fbbcea4b | 91 | return -1; |
strysd | 18:f277fbbcea4b | 92 | } |
strysd | 18:f277fbbcea4b | 93 | fgets(storage_url, 100, fp); |
strysd | 18:f277fbbcea4b | 94 | fiap.setStorage(storage_url); |
strysd | 18:f277fbbcea4b | 95 | fclose(fp); |
strysd | 18:f277fbbcea4b | 96 | |
strysd | 18:f277fbbcea4b | 97 | fiap.debug_mode=FIAP_DEBUG_MODE; |
strysd | 18:f277fbbcea4b | 98 | return 0; |
strysd | 18:f277fbbcea4b | 99 | } |
strysd | 18:f277fbbcea4b | 100 | |
strysd | 13:4e51ac520b33 | 101 | int sendFIAP(void ) |
yueee_yt | 0:27cf9683af17 | 102 | { |
yueee_yt | 0:27cf9683af17 | 103 | ctTime = time(NULL); |
strysd | 4:f50c307c5eda | 104 | t = *localtime(&ctTime); |
strysd | 10:51ef659414a9 | 105 | |
strysd | 17:868a61434584 | 106 | float_p15_wrk = |
strysd | 17:868a61434584 | 107 | float_p16_wrk = |
strysd | 17:868a61434584 | 108 | float_p17_wrk = |
strysd | 17:868a61434584 | 109 | float_p18_wrk = |
strysd | 17:868a61434584 | 110 | float_p19_wrk = |
strysd | 17:868a61434584 | 111 | float_p20_wrk = |
strysd | 17:868a61434584 | 112 | 0.0; |
strysd | 17:868a61434584 | 113 | |
strysd | 17:868a61434584 | 114 | // float_p15_wrk = ain_p15; |
strysd | 17:868a61434584 | 115 | // float_p16_wrk = ain_p16; |
strysd | 17:868a61434584 | 116 | // float_p17_wrk = ain_p17; |
strysd | 17:868a61434584 | 117 | // float_p18_wrk = ain_p18; |
strysd | 17:868a61434584 | 118 | float_p19_wrk = ain_p19; |
strysd | 17:868a61434584 | 119 | float_p20_wrk = ain_p20; |
strysd | 17:868a61434584 | 120 | |
strysd | 17:868a61434584 | 121 | // float_p15 = float_p15_wrk * P15_COEFFICIENT + P15_CONSTANT; |
strysd | 17:868a61434584 | 122 | // float_p16 = float_p16_wrk * P16_COEFFICIENT + P16_CONSTANT; |
strysd | 17:868a61434584 | 123 | // float_p17 = float_p17_wrk * P17_COEFFICIENT + P17_CONSTANT; |
strysd | 17:868a61434584 | 124 | // float_p18 = float_p18_wrk * P18_COEFFICIENT + P18_CONSTANT; |
strysd | 17:868a61434584 | 125 | float_p19 = float_p19_wrk * P19_COEFFICIENT + P19_CONSTANT; |
strysd | 17:868a61434584 | 126 | float_p20 = float_p20_wrk * P20_COEFFICIENT + P20_CONSTANT; |
strysd | 17:868a61434584 | 127 | |
strysd | 17:868a61434584 | 128 | // sprintf(val_p15,"%4.1f",float_p15); |
strysd | 17:868a61434584 | 129 | // sprintf(val_p16,"%4.1f",float_p16); |
strysd | 17:868a61434584 | 130 | // sprintf(val_p17,"%4.1f",float_p17); |
strysd | 17:868a61434584 | 131 | // sprintf(val_p18,"%4.1f",float_p18); |
strysd | 13:4e51ac520b33 | 132 | sprintf(val_p19,"%4.1f",float_p19); |
strysd | 13:4e51ac520b33 | 133 | sprintf(val_p20,"%4.1f",float_p20); |
strysd | 13:4e51ac520b33 | 134 | |
strysd | 13:4e51ac520b33 | 135 | //P19 |
strysd | 13:4e51ac520b33 | 136 | element[0].cid=P19_POINT_ID; |
strysd | 13:4e51ac520b33 | 137 | element[0].value=val_p19; |
strysd | 13:4e51ac520b33 | 138 | |
strysd | 13:4e51ac520b33 | 139 | //P20 |
strysd | 13:4e51ac520b33 | 140 | element[1].cid=P20_POINT_ID; |
strysd | 13:4e51ac520b33 | 141 | element[1].value=val_p20; |
strysd | 13:4e51ac520b33 | 142 | |
strysd | 17:868a61434584 | 143 | //Common |
strysd | 17:868a61434584 | 144 | element[0].year = |
strysd | 17:868a61434584 | 145 | element[1].year = |
strysd | 18:f277fbbcea4b | 146 | t.tm_year + 1900; |
strysd | 17:868a61434584 | 147 | |
strysd | 17:868a61434584 | 148 | element[0].month = |
strysd | 17:868a61434584 | 149 | element[1].month = |
strysd | 18:f277fbbcea4b | 150 | t.tm_mon + 1; |
strysd | 17:868a61434584 | 151 | |
strysd | 17:868a61434584 | 152 | element[0].day = |
strysd | 17:868a61434584 | 153 | element[1].day = |
strysd | 17:868a61434584 | 154 | t.tm_mday; |
strysd | 17:868a61434584 | 155 | |
strysd | 17:868a61434584 | 156 | element[0].hour = |
strysd | 17:868a61434584 | 157 | element[1].hour = |
strysd | 17:868a61434584 | 158 | t.tm_hour; |
strysd | 17:868a61434584 | 159 | |
strysd | 17:868a61434584 | 160 | element[0].minute = |
strysd | 17:868a61434584 | 161 | element[1].minute = |
strysd | 17:868a61434584 | 162 | t.tm_min; |
strysd | 17:868a61434584 | 163 | |
strysd | 17:868a61434584 | 164 | element[0].second = |
strysd | 17:868a61434584 | 165 | element[1].second = |
strysd | 17:868a61434584 | 166 | t.tm_sec; |
strysd | 17:868a61434584 | 167 | |
strysd | 17:868a61434584 | 168 | element[0].timezone = |
strysd | 17:868a61434584 | 169 | element[1].timezone = |
strysd | 17:868a61434584 | 170 | TIME_ZONE_CHAR; |
strysd | 13:4e51ac520b33 | 171 | |
strysd | 13:4e51ac520b33 | 172 | return fiap.post(element,COUNT_OF_POINTS); |
yueee_yt | 0:27cf9683af17 | 173 | } |
yueee_yt | 0:27cf9683af17 | 174 | |
strysd | 17:868a61434584 | 175 | /* stop USB Interface */ |
strysd | 17:868a61434584 | 176 | #define USR_POWERDOWN (0x104) |
strysd | 17:868a61434584 | 177 | int semihost_powerdown() { |
strysd | 17:868a61434584 | 178 | uint32_t arg; |
strysd | 17:868a61434584 | 179 | return __semihost(USR_POWERDOWN, &arg); |
strysd | 17:868a61434584 | 180 | } |
strysd | 17:868a61434584 | 181 | |
strysd | 18:f277fbbcea4b | 182 | /* Frequency Control */ |
strysd | 18:f277fbbcea4b | 183 | void setPLL0Frequency(unsigned char clkSrc, unsigned short M, unsigned char N) |
strysd | 18:f277fbbcea4b | 184 | { |
strysd | 18:f277fbbcea4b | 185 | LPC_SC->CLKSRCSEL = clkSrc; |
strysd | 18:f277fbbcea4b | 186 | LPC_SC->PLL0CFG = (((unsigned int)N-1) << 16) | M-1; |
strysd | 18:f277fbbcea4b | 187 | LPC_SC->PLL0CON = 0x01; |
strysd | 18:f277fbbcea4b | 188 | LPC_SC->PLL0FEED = 0xAA; |
strysd | 18:f277fbbcea4b | 189 | LPC_SC->PLL0FEED = 0x55; |
strysd | 18:f277fbbcea4b | 190 | while (!(LPC_SC->PLL0STAT & (1<<26))); |
strysd | 18:f277fbbcea4b | 191 | |
strysd | 18:f277fbbcea4b | 192 | LPC_SC->PLL0CON = 0x03; |
strysd | 18:f277fbbcea4b | 193 | LPC_SC->PLL0FEED = 0xAA; |
strysd | 18:f277fbbcea4b | 194 | LPC_SC->PLL0FEED = 0x55; |
strysd | 18:f277fbbcea4b | 195 | } |
strysd | 18:f277fbbcea4b | 196 | |
strysd | 18:f277fbbcea4b | 197 | unsigned int setSystemFrequency(unsigned char clkDivider, unsigned char clkSrc, unsigned short M, unsigned char N) |
strysd | 18:f277fbbcea4b | 198 | { |
strysd | 18:f277fbbcea4b | 199 | setPLL0Frequency(clkSrc, M, N); |
strysd | 18:f277fbbcea4b | 200 | LPC_SC->CCLKCFG = clkDivider - 1; |
strysd | 18:f277fbbcea4b | 201 | SystemCoreClockUpdate(); |
strysd | 18:f277fbbcea4b | 202 | return SystemCoreClock; |
strysd | 18:f277fbbcea4b | 203 | } |
strysd | 18:f277fbbcea4b | 204 | |
yueee_yt | 0:27cf9683af17 | 205 | int main() |
yueee_yt | 0:27cf9683af17 | 206 | { |
strysd | 18:f277fbbcea4b | 207 | setSystemFrequency(0x3, 0x1, 6, 1);//48MHz |
strysd | 9:0d34968a5de1 | 208 | led1 = led2 = led3 = led4 = speed = link = 0; |
strysd | 18:f277fbbcea4b | 209 | pc.baud(9600); |
strysd | 9:0d34968a5de1 | 210 | |
strysd | 9:0d34968a5de1 | 211 | //if you set LEDs for LAN indicator in real time. |
strysd | 9:0d34968a5de1 | 212 | //interval : 0.1 = 100ms |
strysd | 9:0d34968a5de1 | 213 | //flipper.attach(&myflip, 0.1); |
strysd | 4:f50c307c5eda | 214 | |
yueee_yt | 0:27cf9683af17 | 215 | eth.init(); //Use DHCP |
yueee_yt | 0:27cf9683af17 | 216 | eth.connect(); |
strysd | 10:51ef659414a9 | 217 | printf("IP: %s\r\n", eth.getIPAddress()); |
strysd | 18:f277fbbcea4b | 218 | |
strysd | 10:51ef659414a9 | 219 | led1 = 1; |
strysd | 18:f277fbbcea4b | 220 | if(syncNTP() != 0) { |
strysd | 18:f277fbbcea4b | 221 | printf("NTP Sync Error\r\n"); |
strysd | 18:f277fbbcea4b | 222 | return -1; |
strysd | 18:f277fbbcea4b | 223 | } |
strysd | 18:f277fbbcea4b | 224 | ctTime = time(NULL); |
strysd | 18:f277fbbcea4b | 225 | printf("Time: %s\r\n", ctime(&ctTime)); |
strysd | 18:f277fbbcea4b | 226 | |
strysd | 18:f277fbbcea4b | 227 | if(setFIAPStorage() != 0) { |
strysd | 18:f277fbbcea4b | 228 | printf("Check if storage.txt exists in mbed memory.\r\n"); |
yueee_yt | 0:27cf9683af17 | 229 | return -1; |
yueee_yt | 0:27cf9683af17 | 230 | } |
strysd | 10:51ef659414a9 | 231 | led1 = 0; |
strysd | 18:f277fbbcea4b | 232 | |
strysd | 17:868a61434584 | 233 | if(FIAP_DEBUG_MODE == false){ |
strysd | 18:f277fbbcea4b | 234 | semihost_powerdown();//Stop also USB Interface |
strysd | 17:868a61434584 | 235 | } |
strysd | 13:4e51ac520b33 | 236 | |
strysd | 13:4e51ac520b33 | 237 | exitTimer = RETRY_TIMES_ON_ERROR; |
strysd | 8:e482433c9593 | 238 | while(exitTimer > 0) { |
strysd | 8:e482433c9593 | 239 | led3 = spd; |
strysd | 8:e482433c9593 | 240 | led4 = lnk; |
strysd | 17:868a61434584 | 241 | if(USE_RJ45_LAMP == true){ |
strysd | 17:868a61434584 | 242 | speed = !spd; |
strysd | 17:868a61434584 | 243 | link = !lnk; |
strysd | 17:868a61434584 | 244 | } |
strysd | 8:e482433c9593 | 245 | if (led4 == 1 || led3 == 1) { |
strysd | 8:e482433c9593 | 246 | exitTimer--; |
strysd | 13:4e51ac520b33 | 247 | wait(WAIT_NEXT_SEND); |
strysd | 13:4e51ac520b33 | 248 | continue; |
strysd | 13:4e51ac520b33 | 249 | } |
strysd | 13:4e51ac520b33 | 250 | |
strysd | 18:f277fbbcea4b | 251 | if(sendFIAP() != 0){ |
strysd | 13:4e51ac520b33 | 252 | led1 = 1; |
strysd | 13:4e51ac520b33 | 253 | exitTimer--; |
strysd | 8:e482433c9593 | 254 | } else { |
strysd | 13:4e51ac520b33 | 255 | led1 = 0; |
strysd | 13:4e51ac520b33 | 256 | exitTimer = RETRY_TIMES_ON_ERROR;//initialize |
strysd | 8:e482433c9593 | 257 | } |
strysd | 13:4e51ac520b33 | 258 | wait(WAIT_NEXT_SEND); |
yueee_yt | 0:27cf9683af17 | 259 | } |
strysd | 8:e482433c9593 | 260 | eth.disconnect(); |
strysd | 17:868a61434584 | 261 | if(FIAP_DEBUG_MODE == true){ |
strysd | 17:868a61434584 | 262 | printf("Disconnected because of error\r\n"); |
strysd | 17:868a61434584 | 263 | } |
strysd | 13:4e51ac520b33 | 264 | |
strysd | 8:e482433c9593 | 265 | return -1; |
strysd | 5:720a29128f41 | 266 | } |