SysBee v1

Dependencies:   C027_Support mbed

Fork of App_Pese_Ruche_SYSBEE by Sysbee

Committer:
Cosi
Date:
Tue Sep 11 13:20:01 2018 +0000
Revision:
7:95ddf8fa6260
Parent:
6:b69c4870db2c
Child:
8:3af661bcfcec
Version avec Fonction de moyenage de d?riv?e

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bennettmatt1977 0:15a06b50e14e 1 #include "mbed.h"
maxelior 1:5639bc1208d5 2 #include <string.h>
thomaspotier 5:d2702cbe5afe 3 //#include <LowPowerTimeout.h>
bennettmatt1977 0:15a06b50e14e 4
bennettmatt1977 0:15a06b50e14e 5 #include "GPS.h"
bennettmatt1977 0:15a06b50e14e 6 #include "MDM.h"
thomaspotier 4:bee94a4094b6 7
thomaspotier 4:bee94a4094b6 8 // sim pin code
maxelior 1:5639bc1208d5 9 #define SIMPIN "1234"
bennettmatt1977 0:15a06b50e14e 10 #define APN NULL
bennettmatt1977 0:15a06b50e14e 11 #define USERNAME NULL
maxelior 1:5639bc1208d5 12 #define PASSWORD NULL
maxelior 2:57d040afa937 13
thomaspotier 4:bee94a4094b6 14 // size of the average buffer (more means more averaged)
thomaspotier 5:d2702cbe5afe 15 #define AVERAGING_SIZE 500
thomaspotier 4:bee94a4094b6 16 // time between each capture in us
thomaspotier 5:d2702cbe5afe 17 #define AVERAGING_TIME 500
maxelior 2:57d040afa937 18
Cosi 7:95ddf8fa6260 19 /*
Cosi 7:95ddf8fa6260 20 // time between each measure in s
Cosi 6:b69c4870db2c 21 #define MEASURE_INTERVAL (10 * 60)
thomaspotier 5:d2702cbe5afe 22 // time between each averaging in s
Cosi 6:b69c4870db2c 23 #define AVERAGE_INTERVAL (24 * 60 * 60)
Cosi 6:b69c4870db2c 24 //WEEK measure time interval
Cosi 6:b69c4870db2c 25 #define WEEK_INTERVALL (7 * 24 * 60 * 60)
Cosi 7:95ddf8fa6260 26 */
Cosi 7:95ddf8fa6260 27
Cosi 7:95ddf8fa6260 28 //Test intervals :
Cosi 7:95ddf8fa6260 29 #define MEASURE_INTERVAL 5
Cosi 7:95ddf8fa6260 30 #define AVERAGE_INTERVAL 20
Cosi 7:95ddf8fa6260 31 #define WEEK_INTERVAL (2 * 60)
Cosi 7:95ddf8fa6260 32
thomaspotier 5:d2702cbe5afe 33 // number of measure before average
thomaspotier 5:d2702cbe5afe 34 #define AVERAGE_COUNT ((int)(AVERAGE_INTERVAL / MEASURE_INTERVAL))
thomaspotier 4:bee94a4094b6 35
Cosi 6:b69c4870db2c 36 #define WEEK_COUNT ((int)(WEEK_INTERVAL / AVERAGE_INTERVAL))
Cosi 6:b69c4870db2c 37
Cosi 6:b69c4870db2c 38 //#define SENSOR_OFFSET 6.1f
Cosi 6:b69c4870db2c 39 //#define SENSOR_FACTOR 39.0f
Cosi 6:b69c4870db2c 40 #define SENSOR_OFFSET 9.4f
Cosi 6:b69c4870db2c 41 #define SENSOR_FACTOR 26.3f
thomaspotier 4:bee94a4094b6 42
thomaspotier 4:bee94a4094b6 43 // weight difference needed to send sms
thomaspotier 4:bee94a4094b6 44 #define DIFF_THRESHOLD 0.4f
maxelior 3:8b90a40df4db 45
thomaspotier 4:bee94a4094b6 46 // states of the hive
thomaspotier 4:bee94a4094b6 47 typedef enum E_HIVE_STATE {
thomaspotier 5:d2702cbe5afe 48 HIVE_STATE_INIT = 0,
Cosi 6:b69c4870db2c 49 HIVE_STATE_STANDBY,
Cosi 6:b69c4870db2c 50 HIVE_STATE_WEEK,
Cosi 7:95ddf8fa6260 51 HIVE_STATE_DAILY,
thomaspotier 5:d2702cbe5afe 52 HIVE_STATE_MEASURE,
thomaspotier 5:d2702cbe5afe 53 HIVE_STATE_NOTHING_NEW,
thomaspotier 5:d2702cbe5afe 54 HIVE_STATE_HONEY,
thomaspotier 5:d2702cbe5afe 55 HIVE_STATE_PROBLEM_SPRING,
thomaspotier 4:bee94a4094b6 56 } t_hive_state;
maxelior 3:8b90a40df4db 57
thomaspotier 5:d2702cbe5afe 58 t_hive_state current_state = HIVE_STATE_INIT;
thomaspotier 4:bee94a4094b6 59
thomaspotier 4:bee94a4094b6 60 // buffer used to create message content
thomaspotier 4:bee94a4094b6 61 char buffer[1024];
maxelior 3:8b90a40df4db 62
thomaspotier 5:d2702cbe5afe 63 float average_values[AVERAGE_COUNT] = {0.0f};
Cosi 7:95ddf8fa6260 64 //float diff_values[AVERAGE_COUNT] = {0.0f};
thomaspotier 5:d2702cbe5afe 65 float last_average = 0;
Cosi 6:b69c4870db2c 66 float week_last_average = 0;
thomaspotier 5:d2702cbe5afe 67 float current_average = 0;
Cosi 7:95ddf8fa6260 68 float week_average = 0;
thomaspotier 5:d2702cbe5afe 69 float current_average_diff = 0;
Cosi 6:b69c4870db2c 70 float week_average_diff = 0;
thomaspotier 5:d2702cbe5afe 71 float current_measure_diff = 0;
thomaspotier 5:d2702cbe5afe 72 unsigned int average_ticks_passed = 0;
Cosi 6:b69c4870db2c 73 unsigned int week_ticks_passed = 0;
Cosi 7:95ddf8fa6260 74 int size_tab = 0;
Cosi 7:95ddf8fa6260 75 int time_diff = 0;
Cosi 7:95ddf8fa6260 76
Cosi 7:95ddf8fa6260 77 //void init_modem(void);
thomaspotier 4:bee94a4094b6 78
thomaspotier 4:bee94a4094b6 79 // analog read of sensor board output
thomaspotier 4:bee94a4094b6 80 AnalogIn sensor(PC_5);
thomaspotier 4:bee94a4094b6 81
thomaspotier 4:bee94a4094b6 82 // phone number for sms (Cosima DORLAND)
Cosi 6:b69c4870db2c 83 //const char phone_number[] = "0680182150";
thomaspotier 5:d2702cbe5afe 84 const char phone_number[] = "0786074814";
thomaspotier 4:bee94a4094b6 85
thomaspotier 4:bee94a4094b6 86 // Serial object for pc communications
thomaspotier 4:bee94a4094b6 87 Serial pc(USBTX, USBRX);
maxelior 1:5639bc1208d5 88
thomaspotier 4:bee94a4094b6 89 // modem object for sms communications
thomaspotier 4:bee94a4094b6 90 MDMSerial modem;
thomaspotier 4:bee94a4094b6 91
thomaspotier 5:d2702cbe5afe 92 // sleep utils
thomaspotier 5:d2702cbe5afe 93 Timeout sleep_timout;
thomaspotier 5:d2702cbe5afe 94
thomaspotier 5:d2702cbe5afe 95 bool awake = true;
thomaspotier 5:d2702cbe5afe 96
thomaspotier 4:bee94a4094b6 97 // led for test blink
thomaspotier 4:bee94a4094b6 98 DigitalOut led(LED1);
thomaspotier 4:bee94a4094b6 99
thomaspotier 4:bee94a4094b6 100
thomaspotier 5:d2702cbe5afe 101 void blink(void)
thomaspotier 4:bee94a4094b6 102 {
thomaspotier 4:bee94a4094b6 103 led.write(1);
thomaspotier 4:bee94a4094b6 104 wait(0.2);
thomaspotier 4:bee94a4094b6 105 led.write(0);
maxelior 2:57d040afa937 106 }
maxelior 1:5639bc1208d5 107
thomaspotier 5:d2702cbe5afe 108 void wake_up(void)
thomaspotier 5:d2702cbe5afe 109 {
thomaspotier 5:d2702cbe5afe 110 awake = true;
thomaspotier 5:d2702cbe5afe 111 }
thomaspotier 5:d2702cbe5afe 112
thomaspotier 5:d2702cbe5afe 113 void power_sleep(float time)
thomaspotier 5:d2702cbe5afe 114 {
thomaspotier 5:d2702cbe5afe 115 awake = false;
thomaspotier 5:d2702cbe5afe 116 sleep_timout.attach(wake_up, time);
thomaspotier 5:d2702cbe5afe 117 pc.printf("Going to sleep !\n\r");
thomaspotier 5:d2702cbe5afe 118 while (!awake) sleep();
thomaspotier 5:d2702cbe5afe 119 pc.printf("Woke up !\n\r");
thomaspotier 5:d2702cbe5afe 120 }
thomaspotier 5:d2702cbe5afe 121
thomaspotier 4:bee94a4094b6 122 // send a sms to the phone number
thomaspotier 4:bee94a4094b6 123 void send_message(char msg[])
thomaspotier 4:bee94a4094b6 124 {
thomaspotier 4:bee94a4094b6 125 MDMParser::DevStatus devStatus = {};
thomaspotier 4:bee94a4094b6 126 MDMParser::NetStatus netStatus = {};
maxelior 2:57d040afa937 127
thomaspotier 4:bee94a4094b6 128 // log sms sending to pc
thomaspotier 5:d2702cbe5afe 129 pc.printf("\x1b[34mSMS: %s\n\r\x1b[0m", msg);
thomaspotier 4:bee94a4094b6 130
thomaspotier 4:bee94a4094b6 131 while (!modem.checkNetStatus(&netStatus)) {
thomaspotier 5:d2702cbe5afe 132 pc.printf("\x1b[34mMODEM checkNetStatus failed...\n\r\x1b[0m");
thomaspotier 4:bee94a4094b6 133 wait(1);
thomaspotier 4:bee94a4094b6 134 }
thomaspotier 4:bee94a4094b6 135 modem.dumpDevStatus(&devStatus);
thomaspotier 4:bee94a4094b6 136 while (!modem.registerNet(&netStatus)) {
thomaspotier 5:d2702cbe5afe 137 pc.printf("\x1b[34mMODEM registerNet failed...\n\r\x1b[0m");
thomaspotier 4:bee94a4094b6 138 wait(1);
thomaspotier 4:bee94a4094b6 139 }
thomaspotier 4:bee94a4094b6 140 modem.dumpNetStatus(&netStatus);
thomaspotier 4:bee94a4094b6 141 modem.smsSend(phone_number ,msg);
maxelior 2:57d040afa937 142 }
maxelior 1:5639bc1208d5 143
thomaspotier 4:bee94a4094b6 144 // return the current calibrated weight
thomaspotier 4:bee94a4094b6 145 float get_weight()
thomaspotier 4:bee94a4094b6 146 {
thomaspotier 4:bee94a4094b6 147 float weight;
thomaspotier 4:bee94a4094b6 148
thomaspotier 4:bee94a4094b6 149 // weight is the sensor output in volts
thomaspotier 4:bee94a4094b6 150 weight = sensor.read() * 3.3f;
thomaspotier 4:bee94a4094b6 151 // return calibrated result
thomaspotier 4:bee94a4094b6 152 return (weight * SENSOR_FACTOR - SENSOR_OFFSET);
thomaspotier 4:bee94a4094b6 153 }
thomaspotier 4:bee94a4094b6 154
thomaspotier 4:bee94a4094b6 155 // return an averaged weight (time consuming function)
thomaspotier 4:bee94a4094b6 156 float get_averaged_weight()
thomaspotier 4:bee94a4094b6 157 {
thomaspotier 4:bee94a4094b6 158 float average = 0;
thomaspotier 4:bee94a4094b6 159 int i;
thomaspotier 4:bee94a4094b6 160
thomaspotier 4:bee94a4094b6 161 for(i = 0; i < AVERAGING_SIZE; i++) {
thomaspotier 4:bee94a4094b6 162 average += get_weight();
thomaspotier 4:bee94a4094b6 163 wait_us(AVERAGING_TIME);
thomaspotier 4:bee94a4094b6 164 }
thomaspotier 4:bee94a4094b6 165 return (average / AVERAGING_SIZE);
thomaspotier 4:bee94a4094b6 166 }
thomaspotier 4:bee94a4094b6 167
Cosi 7:95ddf8fa6260 168 // return average of differential
Cosi 7:95ddf8fa6260 169 float get_differential_average (float tab[])
Cosi 7:95ddf8fa6260 170 {
Cosi 7:95ddf8fa6260 171 int i = 1;
Cosi 7:95ddf8fa6260 172 float differential = 0;
Cosi 7:95ddf8fa6260 173
Cosi 7:95ddf8fa6260 174 for ( i = 1; i < size_tab; i++)
Cosi 7:95ddf8fa6260 175 differential += (tab[i] - tab[i-1])/time_diff;
Cosi 7:95ddf8fa6260 176
Cosi 7:95ddf8fa6260 177 return differential/size_tab;
Cosi 7:95ddf8fa6260 178 }
Cosi 7:95ddf8fa6260 179
Cosi 7:95ddf8fa6260 180
Cosi 7:95ddf8fa6260 181 void init_modem(void)
Cosi 7:95ddf8fa6260 182 {
Cosi 7:95ddf8fa6260 183 MDMParser::DevStatus devStatus = {};
Cosi 7:95ddf8fa6260 184 MDMParser::NetStatus netStatus = {};
Cosi 7:95ddf8fa6260 185
Cosi 7:95ddf8fa6260 186 // retry from begining if something fails
Cosi 7:95ddf8fa6260 187 while (!modem.init(SIMPIN, &devStatus, D4)) {
Cosi 7:95ddf8fa6260 188 pc.printf("\x1b[34m");
Cosi 7:95ddf8fa6260 189 pc.printf("MODEM init failed...\n\r");
Cosi 7:95ddf8fa6260 190 pc.printf("\x1b[0m");
Cosi 7:95ddf8fa6260 191 wait(1);
Cosi 7:95ddf8fa6260 192 }
Cosi 7:95ddf8fa6260 193 while (!modem.checkNetStatus(&netStatus)) {
Cosi 7:95ddf8fa6260 194 pc.printf("\x1b[34m");
Cosi 7:95ddf8fa6260 195 pc.printf("MODEM net_status failed...\n\r");
Cosi 7:95ddf8fa6260 196 pc.printf("\x1b[0m");
Cosi 7:95ddf8fa6260 197 wait(1);
Cosi 7:95ddf8fa6260 198 }
Cosi 7:95ddf8fa6260 199 modem.dumpDevStatus(&devStatus);
Cosi 7:95ddf8fa6260 200 }
Cosi 7:95ddf8fa6260 201
Cosi 7:95ddf8fa6260 202
thomaspotier 4:bee94a4094b6 203 // automata calculations
maxelior 1:5639bc1208d5 204 void automate()
maxelior 1:5639bc1208d5 205 {
thomaspotier 4:bee94a4094b6 206 switch(current_state) {
thomaspotier 5:d2702cbe5afe 207 case HIVE_STATE_INIT:
Cosi 6:b69c4870db2c 208 // setting baud rate for serial communication with the pc
Cosi 6:b69c4870db2c 209 pc.baud(115200);
Cosi 6:b69c4870db2c 210 pc.printf("TEST\n\r");
Cosi 6:b69c4870db2c 211 init_modem();
Cosi 6:b69c4870db2c 212 current_state = HIVE_STATE_STANDBY;
Cosi 6:b69c4870db2c 213 break;
Cosi 6:b69c4870db2c 214
Cosi 6:b69c4870db2c 215 case HIVE_STATE_STANDBY:
thomaspotier 5:d2702cbe5afe 216 if (average_ticks_passed == AVERAGE_COUNT)
Cosi 7:95ddf8fa6260 217 current_state = HIVE_STATE_DAILY;
thomaspotier 5:d2702cbe5afe 218 else
thomaspotier 5:d2702cbe5afe 219 current_state = HIVE_STATE_MEASURE;
Cosi 7:95ddf8fa6260 220 power_sleep(MEASURE_INTERVAL);
Cosi 7:95ddf8fa6260 221 break;
Cosi 7:95ddf8fa6260 222
thomaspotier 5:d2702cbe5afe 223 case HIVE_STATE_MEASURE:
thomaspotier 5:d2702cbe5afe 224 average_values[average_ticks_passed] = get_averaged_weight();
thomaspotier 5:d2702cbe5afe 225 pc.printf("Weight is %02.2fkg\n\r", average_values[average_ticks_passed]);
thomaspotier 5:d2702cbe5afe 226 // if we are of the first measure use the one at the end of the list (last one)
thomaspotier 5:d2702cbe5afe 227 current_measure_diff = average_ticks_passed == 0 ? average_values[average_ticks_passed] - average_values[AVERAGE_COUNT - 1] : average_values[average_ticks_passed] - average_values[average_ticks_passed - 1];
thomaspotier 5:d2702cbe5afe 228 if (abs(current_measure_diff) > DIFF_THRESHOLD)
Cosi 6:b69c4870db2c 229 {
Cosi 6:b69c4870db2c 230 sprintf(buffer, "3 There has been a problem : %0.1fkg of change in %d minutes !", current_measure_diff, MEASURE_INTERVAL / 60);
Cosi 6:b69c4870db2c 231 send_message(buffer);
Cosi 6:b69c4870db2c 232 }
thomaspotier 5:d2702cbe5afe 233 else
Cosi 6:b69c4870db2c 234 current_state = HIVE_STATE_STANDBY;
Cosi 7:95ddf8fa6260 235 average_ticks_passed++;
Cosi 7:95ddf8fa6260 236 break;
Cosi 7:95ddf8fa6260 237
Cosi 7:95ddf8fa6260 238 case HIVE_STATE_DAILY:
Cosi 7:95ddf8fa6260 239 float dif_av = 0;
Cosi 7:95ddf8fa6260 240 size_tab = AVERAGE_COUNT;
Cosi 7:95ddf8fa6260 241 time_diff = MEASURE_INTERVAL;
thomaspotier 5:d2702cbe5afe 242 current_average = 0;
thomaspotier 5:d2702cbe5afe 243 for(int i = 0; i < average_ticks_passed; i++) {
thomaspotier 5:d2702cbe5afe 244 current_average += average_values[i];
maxelior 1:5639bc1208d5 245 }
thomaspotier 5:d2702cbe5afe 246 current_average /= average_ticks_passed;
thomaspotier 5:d2702cbe5afe 247 current_average_diff = current_average - last_average;
thomaspotier 5:d2702cbe5afe 248 last_average = current_average;
Cosi 7:95ddf8fa6260 249
Cosi 7:95ddf8fa6260 250 /*dif_av = get_differential_average(average_values)
Cosi 7:95ddf8fa6260 251 ((dif_av*AVERAGE_COUNT)+average_values[AVERAGE_COUNT]) - (average_values[AVERAGE_COUNT]);*/
Cosi 6:b69c4870db2c 252 if (current_average_diff > DIFF_THRESHOLD)
Cosi 6:b69c4870db2c 253 {
Cosi 6:b69c4870db2c 254 sprintf(buffer, "1 There is more and more honey in the hive ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60);
Cosi 6:b69c4870db2c 255 send_message(buffer);
Cosi 6:b69c4870db2c 256 }
Cosi 6:b69c4870db2c 257 else if (current_average_diff < -DIFF_THRESHOLD)
Cosi 6:b69c4870db2c 258 {
Cosi 6:b69c4870db2c 259 sprintf(buffer, "2 There is less honey ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60);
Cosi 6:b69c4870db2c 260 send_message(buffer);
Cosi 6:b69c4870db2c 261 }
thomaspotier 5:d2702cbe5afe 262 else
Cosi 6:b69c4870db2c 263 {
Cosi 6:b69c4870db2c 264 sprintf(buffer, "0 Everything is fine ! %0.1fkg of change in %d hours !", current_average_diff, AVERAGE_INTERVAL / 60);
Cosi 6:b69c4870db2c 265 send_message(buffer);
Cosi 6:b69c4870db2c 266 }
thomaspotier 5:d2702cbe5afe 267 average_ticks_passed = 0;
Cosi 6:b69c4870db2c 268 current_state = HIVE_STATE_STANDBY;
thomaspotier 5:d2702cbe5afe 269 break;
Cosi 6:b69c4870db2c 270
Cosi 6:b69c4870db2c 271 case HIVE_STATE_WEEK:
Cosi 7:95ddf8fa6260 272 size_tab = 7;
Cosi 7:95ddf8fa6260 273 time_diff = WEEK_INTERVAL;
Cosi 6:b69c4870db2c 274 week_average = 0;
Cosi 6:b69c4870db2c 275 for(int i = 0; i < week_ticks_passed; i++) {
Cosi 6:b69c4870db2c 276 week_average += average_values[i];
Cosi 6:b69c4870db2c 277
Cosi 6:b69c4870db2c 278 }
Cosi 6:b69c4870db2c 279 week_average /= week_ticks_passed;
Cosi 6:b69c4870db2c 280 week_average_diff = week_average - week_last_average;
Cosi 6:b69c4870db2c 281 week_last_average = week_average;
Cosi 6:b69c4870db2c 282 if (week_average_diff > DIFF_THRESHOLD)
Cosi 6:b69c4870db2c 283 {
Cosi 6:b69c4870db2c 284 sprintf(buffer, "4 There is more and more honey in the hive over the week! %0.1fkg of change in %d hours !", week_average_diff, WEEK_INTERVAL / 60);
Cosi 6:b69c4870db2c 285 send_message(buffer);
Cosi 6:b69c4870db2c 286 }
Cosi 6:b69c4870db2c 287 else if (week_average_diff < -DIFF_THRESHOLD)
Cosi 6:b69c4870db2c 288 {
Cosi 7:95ddf8fa6260 289 sprintf(buffer, "5 There is less honey over the last week ! %0.1fkg of change in %d hours !", week_average_diff, WEEK_INTERVAL / 60);
Cosi 6:b69c4870db2c 290 send_message(buffer);
Cosi 6:b69c4870db2c 291 }
Cosi 6:b69c4870db2c 292 else
Cosi 6:b69c4870db2c 293 {
Cosi 6:b69c4870db2c 294 sprintf(buffer, "6 Everything was fine over the last week ! %0.1fkg of change in %d hours !", week_average_diff, WEEK_INTERVAL / 60);
Cosi 6:b69c4870db2c 295 send_message(buffer);
Cosi 6:b69c4870db2c 296 }
Cosi 6:b69c4870db2c 297 week_ticks_passed = 0;
Cosi 6:b69c4870db2c 298 current_state = HIVE_STATE_STANDBY;
thomaspotier 5:d2702cbe5afe 299 break;
Cosi 6:b69c4870db2c 300
Cosi 6:b69c4870db2c 301
Cosi 6:b69c4870db2c 302
thomaspotier 4:bee94a4094b6 303 default:
thomaspotier 5:d2702cbe5afe 304 pc.printf("Error...");
maxelior 2:57d040afa937 305 break;
maxelior 1:5639bc1208d5 306 }
maxelior 1:5639bc1208d5 307 }
bennettmatt1977 0:15a06b50e14e 308
bennettmatt1977 0:15a06b50e14e 309 int main(void)
bennettmatt1977 0:15a06b50e14e 310 {
Cosi 6:b69c4870db2c 311
Cosi 6:b69c4870db2c 312
thomaspotier 4:bee94a4094b6 313
thomaspotier 4:bee94a4094b6 314 // main loop
maxelior 1:5639bc1208d5 315 while(1) {
thomaspotier 4:bee94a4094b6 316 // blink once for each measure
thomaspotier 5:d2702cbe5afe 317 //blink();
thomaspotier 4:bee94a4094b6 318 // getting sensor values
thomaspotier 4:bee94a4094b6 319 // acquisition();
thomaspotier 4:bee94a4094b6 320 // changing state of automata according to read values
maxelior 1:5639bc1208d5 321 automate();
bennettmatt1977 0:15a06b50e14e 322 }
bennettmatt1977 0:15a06b50e14e 323 }
maxelior 1:5639bc1208d5 324
maxelior 1:5639bc1208d5 325
maxelior 1:5639bc1208d5 326
maxelior 1:5639bc1208d5 327
maxelior 1:5639bc1208d5 328