diff --git a/docs/mesures/batteries/202609051304-suivi.csv b/docs/mesures/batteries/202609051304-suivi.csv index 449baa1..715891d 100644 --- a/docs/mesures/batteries/202609051304-suivi.csv +++ b/docs/mesures/batteries/202609051304-suivi.csv @@ -32,3 +32,276 @@ heure_reelle,etat,courant_mA,c1_mV,c2_mV,c3_mV,c4_mV,c5_mV,c6_mV,c7_mV,c8_mV,c9_ 2026-09-05T11:08:13.050Z,module1,,3364,3364,3364,3363,3364,3404,3534,3363,3364,3363,3381,3390,3364,3459,3364,171 2026-09-05T11:08:13.208Z,module2,,3385,3383,3386,3386,3384,3384,3386,3382,3384,3398,3383,3384,3385,3385,3385,16 2026-09-05T11:08:13.365Z,module3,,3361,3368,3361,3360,3359,3557,3359,3360,3360,3445,3362,3390,3360,3361,3431,198 +2026-09-05T11:08:33.496Z,module1,,3364,3363,3364,3363,3364,3405,3526,3363,3364,3363,3381,3390,3364,3460,3364,163 +2026-09-05T11:08:33.653Z,module2,,3385,3383,3386,3387,3384,3384,3386,3383,3385,3399,3384,3384,3385,3385,3385,16 +2026-09-05T11:08:33.810Z,module3,,3360,3366,3360,3359,3358,3548,3358,3359,3359,3442,3361,3389,3359,3360,3431,190 +2026-09-05T11:08:53.955Z,module1,,3364,3363,3364,3363,3364,3407,3523,3363,3364,3363,3382,3390,3364,3462,3364,160 +2026-09-05T11:08:54.112Z,module2,,3386,3384,3387,3387,3385,3385,3386,3383,3385,3399,3384,3385,3385,3385,3386,16 +2026-09-05T11:08:54.269Z,module3,,3360,3365,3359,3359,3358,3544,3358,3359,3359,3442,3360,3389,3358,3360,3433,186 +2026-09-05T11:09:14.401Z,module1,,3358,3357,3358,3357,3358,3393,3488,3357,3358,3357,3373,3377,3358,3448,3358,131 +2026-09-05T11:09:14.589Z,module2,,3377,3375,3377,3378,3376,3376,3377,3374,3376,3388,3375,3376,3376,3376,3376,14 +2026-09-05T11:09:14.745Z,module3,,3352,3352,3352,3353,3352,3502,3351,3352,3353,3420,3352,3374,3352,3353,3416,151 +2026-09-05T11:09:34.892Z,module1,,3365,3364,3364,3363,3364,3406,3512,3363,3364,3363,3382,3390,3364,3462,3364,149 +2026-09-05T11:09:35.052Z,module2,,3385,3382,3386,3386,3384,3384,3385,3382,3384,3398,3383,3384,3384,3384,3385,16 +2026-09-05T11:09:35.209Z,module3,,3359,3363,3359,3358,3358,3528,3357,3358,3358,3438,3360,3387,3358,3359,3434,171 +2026-09-05T11:09:55.340Z,module1,,3367,3365,3366,3365,3366,3414,3526,3365,3365,3365,3385,3395,3366,3471,3366,161 +2026-09-05T11:09:55.497Z,module2,,3390,3387,3390,3390,3388,3389,3389,3386,3388,3403,3388,3388,3389,3389,3389,17 +2026-09-05T11:09:55.654Z,module3,,3362,3368,3361,3361,3361,3546,3359,3361,3361,3447,3362,3393,3361,3362,3446,187 +2026-09-05T11:10:15.802Z,module1,,3370,3369,3369,3368,3369,3427,3554,3368,3368,3368,3390,3404,3369,3487,3369,186 +2026-09-05T11:10:15.959Z,module2,,3397,3394,3397,3398,3395,3396,3397,3393,3395,3412,3395,3396,3396,3396,3396,19 +2026-09-05T11:10:16.115Z,module3,,3367,3378,3367,3366,3366,3577,3364,3366,3366,3467,3368,3406,3366,3367,3469,213 +2026-09-05T11:10:36.262Z,module1,,3366,3365,3365,3364,3365,3421,3534,3364,3365,3364,3385,3396,3365,3482,3365,170 +2026-09-05T11:10:36.451Z,module2,,3395,3392,3395,3395,3393,3393,3395,3391,3393,3409,3393,3393,3394,3393,3393,18 +2026-09-05T11:10:36.609Z,module3,,3366,3376,3366,3365,3365,3565,3364,3365,3365,3463,3367,3406,3365,3366,3469,201 +2026-09-05T11:10:56.745Z,module1,,3366,3366,3366,3365,3365,3427,3537,3365,3366,3364,3386,3398,3366,3489,3365,173 +2026-09-05T11:10:56.901Z,module2,,3394,3392,3395,3395,3392,3392,3394,3390,3393,3408,3392,3393,3393,3393,3392,18 +2026-09-05T11:10:57.057Z,module3,,3365,3374,3365,3364,3364,3564,3363,3364,3364,3461,3366,3405,3364,3365,3472,201 +2026-09-05T11:11:17.201Z,module1,,3365,3364,3365,3363,3364,3424,3524,3364,3364,3363,3385,3394,3365,3486,3364,161 +2026-09-05T11:11:17.358Z,module2,,3392,3389,3392,3393,3390,3389,3392,3388,3390,3405,3389,3390,3391,3391,3389,17 +2026-09-05T11:11:17.514Z,module3,,3364,3371,3363,3363,3362,3550,3362,3363,3363,3456,3365,3403,3363,3364,3470,188 +2026-09-05T11:11:37.655Z,module1,,3364,3363,3364,3362,3363,3424,3518,3363,3363,3362,3383,3393,3364,3485,3363,156 +2026-09-05T11:11:37.815Z,module2,,3391,3389,3392,3392,3389,3389,3391,3387,3389,3404,3388,3390,3390,3390,3388,17 +2026-09-05T11:11:37.972Z,module3,,3363,3370,3363,3363,3362,3545,3361,3362,3362,3454,3364,3402,3362,3364,3472,184 +2026-09-05T11:11:58.101Z,module1,,3355,3356,3357,3355,3357,3405,3482,3356,3356,3356,3372,3376,3357,3465,3356,127 +2026-09-05T11:11:58.258Z,module2,,3379,3378,3380,3380,3377,3377,3380,3376,3378,3389,3376,3379,3379,3378,3376,13 +2026-09-05T11:11:58.475Z,module3,,3360,3363,3359,3358,3357,3512,3358,3358,3358,3435,3361,3393,3358,3359,3451,155 +2026-09-05T11:12:18.616Z,module1,,3360,3360,3361,3360,3362,3416,3497,3360,3361,3360,3379,3386,3361,3475,3361,137 +2026-09-05T11:12:18.774Z,module2,,3382,3380,3383,3384,3381,3379,3383,3379,3381,3394,3379,3382,3382,3381,3380,15 +2026-09-05T11:12:18.930Z,module3,,3361,3366,3360,3360,3359,3522,3359,3360,3360,3440,3362,3397,3360,3361,3460,163 +2026-09-05T11:12:39.060Z,module1,,3362,3361,3362,3361,3362,3419,3497,3361,3362,3361,3380,3388,3362,3476,3362,136 +2026-09-05T11:12:39.219Z,module2,,3383,3381,3384,3385,3383,3380,3383,3380,3382,3396,3380,3382,3383,3382,3382,16 +2026-09-05T11:12:39.375Z,module3,,3360,3364,3359,3359,3358,3519,3358,3359,3359,3438,3361,3396,3358,3360,3460,161 +2026-09-05T11:12:59.511Z,module1,,3367,3366,3366,3366,3367,3435,3522,3365,3366,3366,3387,3399,3366,3493,3367,157 +2026-09-05T11:12:59.668Z,module2,,3392,3389,3393,3393,3391,3389,3392,3388,3391,3405,3389,3391,3392,3391,3390,17 +2026-09-05T11:12:59.825Z,module3,,3363,3369,3362,3362,3361,3541,3361,3362,3362,3450,3364,3404,3362,3363,3479,180 +2026-09-05T11:13:19.955Z,module1,,3368,3367,3367,3366,3368,3440,3520,3366,3367,3367,3389,3401,3367,3495,3368,154 +2026-09-05T11:13:20.142Z,module2,,3395,3392,3396,3396,3394,3393,3395,3391,3393,3409,3393,3394,3395,3394,3393,18 +2026-09-05T11:13:20.297Z,module3,,3363,3370,3362,3362,3361,3538,3361,3362,3362,3450,3364,3406,3362,3363,3481,177 +2026-09-05T11:13:40.444Z,module1,,3368,3367,3367,3366,3368,3447,3529,3366,3367,3366,3390,3404,3368,3503,3367,163 +2026-09-05T11:13:40.635Z,module2,,3397,3394,3398,3398,3395,3394,3396,3393,3395,3410,3394,3395,3396,3395,3394,17 +2026-09-05T11:13:40.792Z,module3,,3363,3370,3363,3363,3363,3548,3361,3362,3363,3457,3364,3410,3362,3364,3495,187 +2026-09-05T11:14:00.929Z,module1,,3367,3366,3367,3365,3367,3448,3520,3366,3366,3365,3388,3402,3367,3502,3366,155 +2026-09-05T11:14:01.085Z,module2,,3396,3394,3397,3397,3394,3393,3396,3392,3394,3409,3393,3395,3396,3395,3393,17 +2026-09-05T11:14:01.242Z,module3,,3364,3372,3364,3363,3363,3543,3362,3363,3363,3457,3365,3413,3363,3364,3497,181 +2026-09-05T11:14:21.388Z,module1,,3366,3366,3366,3365,3366,3449,3516,3365,3366,3365,3388,3402,3366,3501,3366,151 +2026-09-05T11:14:21.545Z,module2,,3395,3393,3396,3396,3393,3392,3395,3391,3394,3407,3392,3394,3395,3394,3392,16 +2026-09-05T11:14:21.702Z,module3,,3365,3372,3364,3363,3363,3539,3362,3364,3363,3456,3366,3414,3363,3364,3497,177 +2026-09-05T11:14:41.847Z,module1,,3364,3364,3364,3362,3363,3439,3495,3363,3363,3362,3385,3395,3364,3487,3363,133 +2026-09-05T11:14:42.007Z,module2,,3390,3388,3391,3391,3389,3387,3390,3386,3389,3402,3387,3389,3390,3389,3388,16 +2026-09-05T11:14:42.163Z,module3,,3362,3367,3361,3361,3361,3515,3360,3361,3361,3444,3363,3407,3361,3362,3480,155 +2026-09-05T11:15:02.310Z,module1,,3364,3364,3364,3362,3363,3442,3499,3363,3363,3362,3385,3396,3364,3490,3363,137 +2026-09-05T11:15:02.497Z,module2,,3392,3389,3392,3393,3390,3389,3391,3388,3390,3402,3389,3391,3391,3390,3388,14 +2026-09-05T11:15:02.654Z,module3,,3364,3370,3363,3363,3362,3522,3361,3363,3363,3449,3365,3412,3363,3364,3488,161 +2026-09-05T11:15:22.800Z,module1,,3363,3363,3363,3361,3362,3444,3499,3362,3363,3361,3384,3395,3363,3491,3362,138 +2026-09-05T11:15:22.959Z,module2,,3391,3390,3392,3393,3390,3388,3391,3388,3390,3402,3388,3391,3391,3390,3388,14 +2026-09-05T11:15:23.116Z,module3,,3365,3372,3364,3364,3363,3525,3362,3364,3363,3450,3366,3415,3363,3365,3491,163 +2026-09-05T11:15:43.261Z,module1,,3364,3364,3365,3363,3364,3456,3512,3364,3364,3363,3387,3401,3365,3503,3364,149 +2026-09-05T11:15:43.419Z,module2,,3395,3393,3397,3397,3394,3392,3395,3392,3394,3406,3392,3394,3395,3394,3392,14 +2026-09-05T11:15:43.576Z,module3,,3366,3374,3365,3365,3364,3538,3363,3365,3365,3457,3367,3422,3364,3366,3507,175 +2026-09-05T11:16:03.723Z,module1,,3366,3366,3366,3365,3366,3470,3525,3366,3366,3365,3390,3408,3367,3514,3366,160 +2026-09-05T11:16:03.879Z,module2,,3400,3397,3400,3401,3398,3396,3399,3395,3398,3410,3396,3399,3399,3398,3396,15 +2026-09-05T11:16:04.036Z,module3,,3367,3376,3366,3366,3365,3550,3364,3366,3366,3464,3368,3430,3366,3367,3523,186 +2026-09-05T11:16:24.167Z,module1,,3366,3366,3367,3365,3367,3473,3519,3366,3367,3366,3390,3409,3367,3515,3367,154 +2026-09-05T11:16:24.324Z,module2,,3399,3397,3400,3400,3397,3395,3399,3395,3397,3409,3395,3398,3398,3397,3395,14 +2026-09-05T11:16:24.573Z,module3,,3367,3376,3366,3366,3365,3545,3364,3366,3366,3463,3368,3432,3366,3367,3522,181 +2026-09-05T11:16:44.715Z,module1,,3367,3367,3368,3367,3368,3479,3518,3367,3368,3367,3391,3411,3368,3516,3368,151 +2026-09-05T11:16:44.873Z,module2,,3399,3396,3400,3400,3398,3394,3399,3395,3397,3409,3395,3398,3399,3397,3395,15 +2026-09-05T11:16:45.029Z,module3,,3366,3374,3366,3365,3365,3542,3364,3365,3366,3462,3368,3434,3365,3367,3522,178 +2026-09-05T11:17:05.176Z,module1,,3368,3368,3368,3366,3368,3483,3515,3367,3368,3367,3392,3412,3368,3516,3368,150 +2026-09-05T11:17:05.331Z,module2,,3400,3397,3401,3402,3399,3396,3399,3396,3399,3410,3396,3399,3400,3399,3397,14 +2026-09-05T11:17:05.488Z,module3,,3366,3374,3365,3365,3364,3538,3364,3365,3365,3461,3367,3436,3365,3366,3521,174 +2026-09-05T11:17:25.634Z,module1,,3364,3364,3364,3363,3365,3462,3489,3363,3364,3364,3386,3402,3365,3496,3365,133 +2026-09-05T11:17:25.792Z,module2,,3391,3389,3392,3393,3391,3387,3391,3388,3390,3400,3388,3391,3391,3390,3388,13 +2026-09-05T11:17:25.949Z,module3,,3362,3365,3361,3360,3359,3508,3359,3361,3361,3440,3363,3423,3360,3362,3489,149 +2026-09-05T11:17:46.085Z,module1,,3366,3366,3366,3366,3367,3471,3497,3365,3366,3365,3389,3407,3367,3503,3366,138 +2026-09-05T11:17:46.242Z,module2,,3395,3393,3396,3397,3395,3391,3394,3392,3394,3404,3392,3394,3395,3394,3392,13 +2026-09-05T11:17:46.459Z,module3,,3361,3365,3360,3360,3359,3514,3359,3360,3360,3442,3362,3425,3360,3361,3496,155 +2026-09-05T11:18:06.603Z,module1,,3367,3367,3367,3366,3368,3477,3500,3366,3367,3366,3391,3409,3367,3506,3367,140 +2026-09-05T11:18:06.760Z,module2,,3397,3395,3398,3398,3396,3393,3396,3393,3395,3406,3394,3396,3397,3395,3394,13 +2026-09-05T11:18:06.917Z,module3,,3361,3365,3361,3361,3360,3514,3359,3360,3361,3444,3362,3428,3360,3362,3500,155 +2026-09-05T11:18:27.063Z,module1,,3369,3369,3369,3368,3369,3497,3516,3368,3369,3368,3394,3418,3369,3520,3369,152 +2026-09-05T11:18:27.221Z,module2,,3404,3401,3404,3405,3403,3400,3403,3399,3402,3412,3401,3403,3403,3402,3400,13 +2026-09-05T11:18:27.378Z,module3,,3366,3374,3366,3366,3365,3537,3364,3366,3366,3461,3367,3445,3365,3367,3529,173 +2026-09-05T11:18:47.525Z,module1,,3370,3369,3370,3369,3370,3511,3523,3369,3370,3368,3396,3423,3370,3529,3370,161 +2026-09-05T11:18:47.685Z,module2,,3407,3404,3407,3408,3405,3402,3406,3402,3405,3414,3403,3406,3406,3405,3402,12 +2026-09-05T11:18:47.843Z,module3,,3369,3379,3368,3368,3367,3548,3367,3368,3368,3470,3370,3457,3368,3369,3544,181 +2026-09-05T11:19:07.989Z,module1,,3369,3369,3369,3368,3369,3508,3514,3368,3369,3367,3395,3422,3370,3524,3368,157 +2026-09-05T11:19:08.146Z,module2,,3405,3402,3406,3406,3404,3400,3404,3401,3403,3412,3401,3404,3405,3403,3401,12 +2026-09-05T11:19:08.303Z,module3,,3369,3378,3368,3368,3367,3540,3366,3368,3368,3466,3370,3458,3367,3369,3536,174 +2026-09-05T11:19:28.447Z,module1,,3368,3368,3369,3367,3369,3510,3511,3368,3369,3367,3394,3422,3369,3524,3368,157 +2026-09-05T11:19:28.636Z,module2,,3405,3402,3406,3406,3403,3400,3404,3401,3403,3411,3401,3404,3404,3403,3400,11 +2026-09-05T11:19:28.792Z,module3,,3369,3378,3368,3368,3367,3538,3367,3368,3368,3466,3371,3462,3368,3369,3536,171 +2026-09-05T11:19:48.938Z,module1,,3364,3364,3364,3363,3364,3483,3485,3363,3364,3362,3388,3410,3364,3501,3363,139 +2026-09-05T11:19:49.096Z,module2,,3396,3394,3397,3397,3395,3392,3396,3393,3395,3401,3393,3396,3396,3394,3391,10 +2026-09-05T11:19:49.254Z,module3,,3367,3374,3366,3366,3365,3513,3365,3366,3366,3453,3368,3450,3366,3367,3506,148 +2026-09-05T11:20:09.400Z,module1,,3364,3365,3365,3363,3364,3491,3491,3364,3364,3362,3388,3412,3365,3507,3363,145 +2026-09-05T11:20:09.558Z,module2,,3398,3396,3399,3399,3397,3393,3398,3394,3396,3403,3395,3398,3398,3396,3393,10 +2026-09-05T11:20:09.714Z,module3,,3369,3377,3368,3367,3367,3522,3366,3367,3367,3458,3370,3458,3367,3368,3518,156 +2026-09-05T11:20:29.850Z,module1,,3363,3364,3364,3362,3364,3494,3491,3363,3364,3362,3387,3413,3364,3508,3363,146 +2026-09-05T11:20:30.007Z,module2,,3398,3396,3398,3399,3397,3393,3398,3394,3396,3402,3395,3398,3398,3396,3392,10 +2026-09-05T11:20:30.164Z,module3,,3369,3377,3368,3368,3367,3523,3366,3367,3368,3459,3370,3462,3368,3369,3521,157 +2026-09-05T11:20:50.293Z,module1,,3366,3367,3367,3366,3368,3515,3505,3366,3367,3366,3392,3423,3368,3523,3367,157 +2026-09-05T11:20:50.483Z,module2,,3403,3401,3404,3404,3402,3398,3403,3399,3401,3407,3400,3403,3403,3401,3398,9 +2026-09-05T11:20:50.636Z,module3,,3370,3379,3369,3368,3368,3536,3367,3368,3369,3465,3371,3474,3368,3369,3538,171 +2026-09-05T11:21:10.782Z,module1,,3369,3369,3370,3369,3371,3530,3512,3369,3370,3369,3396,3432,3370,3531,3370,162 +2026-09-05T11:21:10.937Z,module2,,3407,3404,3408,3408,3407,3402,3406,3403,3406,3412,3403,3406,3407,3406,3403,10 +2026-09-05T11:21:11.094Z,module3,,3370,3379,3369,3369,3368,3539,3367,3368,3369,3467,3371,3481,3368,3370,3545,178 +2026-09-05T11:21:31.229Z,module1,,3369,3369,3369,3368,3370,3522,3504,3368,3369,3368,3395,3430,3370,3525,3369,157 +2026-09-05T11:21:31.385Z,module2,,3406,3403,3406,3407,3405,3401,3405,3402,3404,3410,3402,3405,3405,3404,3402,9 +2026-09-05T11:21:31.541Z,module3,,3369,3377,3368,3367,3367,3529,3366,3368,3368,3462,3370,3478,3367,3369,3533,167 +2026-09-05T11:21:51.687Z,module1,,3370,3369,3370,3368,3370,3524,3503,3369,3370,3369,3396,3432,3370,3525,3370,157 +2026-09-05T11:21:51.846Z,module2,,3406,3404,3407,3407,3406,3401,3406,3403,3405,3410,3403,3406,3406,3404,3402,9 +2026-09-05T11:21:52.003Z,module3,,3369,3377,3368,3368,3367,3527,3366,3368,3368,3460,3370,3480,3367,3369,3531,165 +2026-09-05T11:22:12.150Z,module1,,3370,3369,3370,3369,3370,3524,3501,3369,3370,3369,3396,3434,3370,3524,3370,155 +2026-09-05T11:22:12.307Z,module2,,3407,3404,3407,3407,3406,3402,3406,3403,3405,3409,3403,3406,3406,3404,3402,7 +2026-09-05T11:22:12.494Z,module3,,3368,3375,3367,3367,3365,3523,3366,3367,3367,3457,3369,3481,3367,3368,3528,163 +2026-09-05T11:22:32.632Z,module1,,3364,3364,3365,3363,3365,3493,3475,3364,3365,3363,3388,3419,3365,3502,3364,139 +2026-09-05T11:22:32.787Z,module2,,3397,3395,3397,3398,3396,3392,3396,3394,3396,3398,3393,3396,3397,3395,3392,6 +2026-09-05T11:22:32.941Z,module3,,3359,3360,3359,3359,3358,3491,3358,3359,3360,3432,3359,3454,3359,3360,3489,133 +2026-09-05T11:22:53.087Z,module1,,3371,3371,3371,3370,3372,3523,3499,3370,3371,3370,3398,3437,3371,3523,3371,153 +2026-09-05T11:22:53.245Z,module2,,3408,3405,3407,3408,3406,3403,3406,3403,3405,3410,3404,3407,3407,3405,3403,7 +2026-09-05T11:22:53.401Z,module3,,3368,3375,3367,3367,3366,3518,3365,3367,3367,3456,3368,3482,3367,3368,3524,159 +2026-09-05T11:23:13.549Z,module1,,3372,3371,3372,3370,3372,3536,3505,3371,3372,3370,3399,3442,3372,3530,3372,166 +2026-09-05T11:23:13.706Z,module2,,3410,3408,3410,3411,3409,3405,3409,3406,3408,3412,3407,3409,3410,3408,3406,7 +2026-09-05T11:23:13.864Z,module3,,3369,3378,3369,3369,3368,3526,3367,3368,3369,3462,3370,3494,3368,3370,3537,170 +2026-09-05T11:23:34.002Z,module1,,3374,3373,3373,3372,3373,3550,3513,3372,3374,3372,3402,3450,3374,3539,3373,178 +2026-09-05T11:23:34.157Z,module2,,3414,3411,3414,3414,3413,3409,3413,3410,3412,3415,3411,3413,3413,3411,3409,6 +2026-09-05T11:23:34.315Z,module3,,3374,3385,3373,3373,3372,3539,3371,3372,3373,3474,3375,3511,3372,3374,3553,182 +2026-09-05T11:23:54.461Z,module1,,3369,3369,3369,3368,3370,3530,3496,3369,3370,3368,3396,3441,3370,3526,3369,162 +2026-09-05T11:23:54.650Z,module2,,3408,3406,3408,3408,3407,3403,3407,3404,3406,3408,3405,3408,3408,3405,3403,5 +2026-09-05T11:23:54.807Z,module3,,3371,3381,3370,3370,3370,3523,3369,3370,3370,3462,3372,3499,3370,3371,3533,164 +2026-09-05T11:24:14.952Z,module1,,3369,3369,3369,3368,3370,3527,3493,3369,3370,3368,3395,3441,3370,3524,3369,159 +2026-09-05T11:24:15.109Z,module2,,3407,3405,3407,3407,3406,3402,3406,3403,3405,3407,3404,3407,3406,3404,3402,5 +2026-09-05T11:24:15.267Z,module3,,3371,3380,3370,3370,3369,3521,3369,3370,3370,3460,3372,3500,3370,3371,3529,160 +2026-09-05T11:24:35.408Z,module1,,3369,3369,3369,3367,3369,3524,3491,3368,3369,3367,3394,3441,3370,3522,3368,157 +2026-09-05T11:24:35.565Z,module2,,3406,3404,3406,3407,3405,3401,3406,3403,3405,3406,3403,3406,3406,3404,3401,6 +2026-09-05T11:24:35.722Z,module3,,3371,3380,3370,3370,3369,3518,3369,3370,3370,3458,3372,3500,3370,3371,3526,157 +2026-09-05T11:24:55.868Z,module1,,3368,3368,3369,3367,3369,3523,3489,3368,3369,3367,3393,3441,3369,3521,3368,156 +2026-09-05T11:24:56.027Z,module2,,3406,3404,3406,3406,3405,3401,3405,3402,3404,3404,3403,3406,3405,3403,3400,6 +2026-09-05T11:24:56.184Z,module3,,3371,3379,3370,3370,3369,3517,3368,3370,3370,3458,3372,3501,3370,3371,3526,158 +2026-09-05T11:25:16.320Z,module1,,3368,3368,3369,3368,3370,3521,3488,3368,3369,3368,3393,3442,3370,3521,3369,153 +2026-09-05T11:25:16.507Z,module2,,3405,3403,3406,3406,3405,3400,3405,3402,3404,3404,3402,3405,3405,3403,3401,6 +2026-09-05T11:25:16.664Z,module3,,3372,3380,3370,3370,3369,3516,3369,3370,3370,3456,3372,3503,3370,3371,3524,155 +2026-09-05T11:25:36.810Z,module1,,3368,3368,3369,3367,3370,3513,3482,3368,3369,3368,3392,3440,3369,3516,3369,149 +2026-09-05T11:25:36.967Z,module2,,3403,3401,3403,3404,3403,3398,3402,3400,3402,3402,3399,3403,3403,3401,3399,6 +2026-09-05T11:25:37.124Z,module3,,3372,3379,3370,3369,3369,3510,3369,3370,3370,3452,3373,3498,3370,3371,3515,146 +2026-09-05T11:25:57.260Z,module1,,3373,3373,3373,3372,3374,3549,3504,3372,3374,3373,3399,3459,3374,3539,3373,177 +2026-09-05T11:25:57.419Z,module2,,3414,3411,3414,3414,3413,3408,3413,3410,3412,3412,3410,3413,3413,3411,3409,6 +2026-09-05T11:25:57.575Z,module3,,3374,3385,3372,3372,3371,3530,3371,3372,3372,3464,3375,3525,3372,3373,3546,175 +2026-09-05T11:26:17.722Z,module1,,3374,3374,3375,3373,3376,3557,3506,3374,3375,3374,3402,3465,3375,3544,3375,184 +2026-09-05T11:26:17.880Z,module2,,3416,3414,3416,3417,3416,3411,3415,3413,3415,3414,3413,3416,3416,3414,3412,6 +2026-09-05T11:26:18.036Z,module3,,3373,3383,3372,3372,3370,3530,3370,3372,3372,3464,3374,3529,3372,3373,3547,177 +2026-09-05T11:26:38.176Z,module1,,3375,3375,3375,3374,3376,3563,3508,3375,3376,3374,3403,3471,3376,3548,3375,189 +2026-09-05T11:26:38.334Z,module2,,3418,3415,3418,3418,3417,3413,3417,3414,3416,3415,3415,3417,3417,3415,3413,5 +2026-09-05T11:26:38.519Z,module3,,3373,3383,3372,3372,3370,3530,3370,3372,3372,3463,3374,3533,3371,3373,3548,178 +2026-09-05T11:26:58.653Z,module1,,3375,3375,3376,3374,3376,3559,3506,3375,3376,3374,3403,3473,3376,3546,3375,185 +2026-09-05T11:26:58.812Z,module2,,3419,3416,3418,3419,3417,3413,3418,3415,3417,3414,3416,3418,3418,3415,3413,6 +2026-09-05T11:26:58.968Z,module3,,3374,3385,3373,3373,3373,3530,3372,3373,3373,3467,3375,3536,3373,3374,3550,178 +2026-09-05T11:27:19.097Z,module1,,3373,3374,3374,3373,3375,3548,3499,3374,3375,3373,3401,3470,3375,3540,3374,175 +2026-09-05T11:27:19.255Z,module2,,3416,3413,3416,3416,3415,3410,3415,3412,3414,3411,3412,3415,3415,3413,3410,6 +2026-09-05T11:27:19.415Z,module3,,3375,3385,3373,3374,3373,3525,3372,3373,3374,3465,3376,3531,3373,3375,3542,170 +2026-09-05T11:27:39.546Z,module1,,3374,3374,3374,3373,3375,3546,3498,3374,3375,3373,3401,3471,3375,3540,3374,173 +2026-09-05T11:27:39.703Z,module2,,3416,3413,3415,3416,3415,3410,3415,3412,3414,3411,3412,3415,3415,3412,3411,6 +2026-09-05T11:27:39.861Z,module3,,3376,3387,3375,3374,3374,3525,3373,3375,3375,3465,3377,3533,3374,3376,3541,168 +2026-09-05T11:28:00.008Z,module1,,3374,3374,3374,3372,3375,3543,3495,3374,3375,3373,3401,3471,3375,3539,3374,171 +2026-09-05T11:28:00.165Z,module2,,3416,3413,3415,3415,3414,3410,3414,3412,3414,3410,3412,3415,3415,3412,3410,6 +2026-09-05T11:28:00.322Z,module3,,3376,3387,3375,3375,3374,3523,3373,3375,3375,3464,3377,3533,3375,3376,3539,166 +2026-09-05T11:28:20.459Z,module1,,3374,3374,3374,3373,3375,3542,3495,3374,3375,3373,3401,3473,3375,3539,3374,169 +2026-09-05T11:28:20.648Z,module2,,3415,3413,3415,3415,3414,3410,3414,3412,3414,3410,3412,3415,3415,3412,3410,5 +2026-09-05T11:28:20.803Z,module3,,3377,3388,3375,3375,3375,3523,3374,3375,3376,3464,3378,3535,3375,3377,3540,166 +2026-09-05T11:28:40.944Z,module1,,3373,3374,3374,3372,3374,3538,3492,3373,3374,3372,3400,3472,3375,3537,3373,166 +2026-09-05T11:28:41.101Z,module2,,3414,3412,3414,3414,3413,3409,3413,3411,3413,3408,3411,3414,3414,3411,3409,6 +2026-09-05T11:28:41.258Z,module3,,3377,3388,3376,3375,3375,3521,3374,3376,3376,3462,3378,3533,3376,3377,3536,162 +2026-09-05T11:29:01.405Z,module1,,3373,3374,3374,3372,3374,3538,3491,3373,3374,3372,3400,3473,3375,3537,3373,166 +2026-09-05T11:29:01.564Z,module2,,3415,3412,3414,3414,3413,3409,3413,3411,3413,3407,3411,3414,3414,3411,3409,8 +2026-09-05T11:29:01.720Z,module3,,3377,3389,3376,3375,3375,3520,3374,3376,3376,3461,3378,3534,3376,3377,3536,162 +2026-09-05T11:29:21.851Z,module1,,3372,3373,3373,3372,3374,3535,3489,3373,3374,3372,3399,3473,3375,3537,3372,165 +2026-09-05T11:29:22.008Z,module2,,3414,3412,3414,3414,3413,3408,3413,3411,3413,3407,3410,3414,3414,3411,3409,7 +2026-09-05T11:29:22.164Z,module3,,3377,3389,3376,3376,3375,3519,3374,3376,3376,3461,3378,3534,3376,3377,3535,161 +2026-09-05T11:29:42.294Z,module1,,3373,3373,3374,3373,3375,3533,3488,3374,3375,3373,3399,3474,3375,3537,3374,164 +2026-09-05T11:29:42.481Z,module2,,3411,3409,3412,3412,3411,3406,3411,3409,3411,3405,3408,3411,3412,3409,3407,7 +2026-09-05T11:29:42.638Z,module3,,3378,3389,3376,3376,3375,3518,3375,3376,3377,3459,3378,3534,3376,3377,3533,159 +2026-09-05T11:30:02.770Z,module1,,3375,3375,3376,3374,3377,3537,3491,3376,3377,3375,3402,3479,3377,3540,3376,166 +2026-09-05T11:30:02.930Z,module2,,3416,3414,3416,3416,3416,3411,3415,3413,3415,3409,3413,3416,3416,3413,3412,7 +2026-09-05T11:30:03.087Z,module3,,3378,3390,3376,3376,3376,3518,3375,3376,3377,3459,3379,3536,3376,3378,3535,161 +2026-09-05T11:30:23.217Z,module1,,3375,3376,3376,3374,3377,3535,3490,3376,3377,3375,3402,3479,3377,3539,3376,165 +2026-09-05T11:30:23.380Z,module2,,3416,3413,3416,3416,3415,3411,3415,3413,3415,3409,3413,3415,3415,3413,3412,7 +2026-09-05T11:30:23.536Z,module3,,3378,3389,3376,3376,3375,3515,3375,3376,3376,3457,3379,3533,3376,3377,3531,158 +2026-09-05T11:30:43.672Z,module1,,3376,3376,3377,3375,3378,3534,3490,3376,3377,3376,3403,3480,3378,3539,3377,164 +2026-09-05T11:30:43.828Z,module2,,3417,3414,3416,3416,3416,3412,3415,3413,3415,3409,3414,3416,3416,3413,3412,8 +2026-09-05T11:30:43.985Z,module3,,3378,3389,3376,3376,3375,3514,3375,3376,3377,3456,3379,3533,3376,3378,3530,158 +2026-09-05T11:31:04.119Z,module1,,3376,3377,3377,3375,3378,3532,3488,3376,3378,3376,3403,3480,3378,3539,3377,164 +2026-09-05T11:31:04.277Z,module2,,3417,3414,3416,3416,3416,3412,3415,3413,3415,3409,3414,3416,3416,3413,3412,8 +2026-09-05T11:31:04.463Z,module3,,3378,3389,3376,3376,3375,3512,3375,3376,3376,3452,3378,3531,3376,3377,3527,156 +2026-09-05T11:31:24.609Z,module1,,3376,3377,3377,3375,3378,3529,3486,3376,3377,3376,3402,3479,3378,3537,3376,162 +2026-09-05T11:31:24.765Z,module2,,3416,3414,3416,3416,3415,3411,3415,3413,3415,3407,3413,3415,3415,3412,3411,9 +2026-09-05T11:31:24.922Z,module3,,3377,3388,3375,3376,3375,3509,3374,3376,3377,3451,3378,3528,3376,3377,3524,154 +2026-09-05T11:31:45.055Z,module1,,3376,3377,3377,3375,3378,3529,3486,3377,3378,3376,3402,3480,3378,3538,3377,163 +2026-09-05T11:31:45.214Z,module2,,3416,3414,3416,3416,3416,3411,3415,3413,3415,3408,3413,3416,3416,3413,3412,8 +2026-09-05T11:31:45.371Z,module3,,3379,3391,3377,3378,3377,3511,3376,3377,3378,3454,3379,3531,3377,3379,3528,155 +2026-09-05T11:32:05.505Z,module1,,3376,3377,3377,3375,3378,3527,3484,3377,3378,3376,3402,3480,3378,3537,3377,162 +2026-09-05T11:32:05.665Z,module2,,3416,3413,3416,3416,3415,3411,3415,3413,3415,3407,3413,3415,3415,3413,3411,9 +2026-09-05T11:32:05.820Z,module3,,3380,3393,3378,3378,3378,3511,3377,3378,3379,3454,3381,3531,3378,3380,3526,154 +2026-09-05T11:32:25.946Z,module1,,3376,3377,3377,3375,3378,3525,3483,3377,3378,3376,3402,3480,3378,3537,3376,162 +2026-09-05T11:32:26.133Z,module2,,3416,3413,3415,3416,3415,3411,3414,3413,3414,3406,3413,3415,3415,3412,3411,10 +2026-09-05T11:32:26.290Z,module3,,3381,3394,3379,3379,3379,3511,3378,3379,3380,3454,3382,3532,3379,3380,3526,154 +2026-09-05T11:32:46.437Z,module1,,3376,3377,3377,3375,3379,3525,3483,3377,3378,3376,3403,3480,3379,3537,3377,162 +2026-09-05T11:32:46.625Z,module2,,3416,3413,3415,3415,3415,3411,3414,3413,3414,3406,3413,3415,3415,3412,3411,10 +2026-09-05T11:32:46.781Z,module3,,3381,3395,3379,3379,3379,3510,3378,3380,3380,3453,3382,3532,3380,3381,3526,154 +2026-09-05T11:33:06.914Z,module1,,3376,3377,3377,3375,3378,3522,3481,3377,3378,3376,3402,3479,3379,3536,3377,161 +2026-09-05T11:33:07.074Z,module2,,3415,3413,3415,3415,3414,3410,3414,3412,3414,3406,3412,3415,3415,3412,3411,9 +2026-09-05T11:33:07.231Z,module3,,3382,3396,3380,3380,3379,3509,3379,3380,3381,3452,3383,3530,3380,3381,3524,151 +2026-09-05T11:33:27.376Z,module1,,3376,3377,3377,3375,3378,3520,3479,3377,3378,3375,3402,3478,3378,3534,3376,159 +2026-09-05T11:33:27.533Z,module2,,3415,3413,3415,3415,3414,3410,3414,3412,3414,3404,3412,3415,3414,3411,3409,11 +2026-09-05T11:33:27.690Z,module3,,3382,3396,3380,3380,3379,3508,3379,3380,3381,3450,3383,3529,3380,3381,3522,150 +2026-09-05T11:33:47.835Z,module1,,3375,3376,3377,3375,3378,3517,3477,3376,3378,3375,3401,3476,3378,3534,3376,159 +2026-09-05T11:33:47.990Z,module2,,3414,3412,3414,3414,3414,3409,3413,3411,3413,3404,3411,3414,3414,3411,3410,10 +2026-09-05T11:33:48.145Z,module3,,3382,3396,3380,3380,3379,3506,3379,3380,3381,3449,3383,3527,3380,3381,3520,148 +2026-09-05T11:34:08.281Z,module1,,3376,3377,3378,3376,3380,3516,3477,3377,3379,3377,3402,3477,3379,3534,3378,158 +2026-09-05T11:34:08.468Z,module2,,3415,3413,3416,3416,3415,3410,3414,3413,3415,3405,3412,3415,3415,3412,3412,11 +2026-09-05T11:34:08.624Z,module3,,3383,3397,3380,3381,3380,3505,3379,3381,3381,3447,3383,3526,3381,3382,3518,147 +2026-09-05T11:34:28.770Z,module1,,3378,3379,3379,3377,3381,3517,3478,3379,3380,3378,3404,3479,3381,3535,3379,158 +2026-09-05T11:34:28.927Z,module2,,3417,3414,3416,3416,3416,3412,3415,3413,3415,3406,3414,3416,3416,3413,3412,11 +2026-09-05T11:34:29.083Z,module3,,3382,3397,3380,3380,3380,3503,3379,3381,3381,3446,3383,3525,3381,3382,3517,146 +2026-09-05T11:34:49.228Z,module1,,3379,3379,3380,3378,3381,3517,3478,3380,3381,3379,3405,3479,3381,3535,3379,157 +2026-09-05T11:34:49.385Z,module2,,3417,3415,3416,3417,3416,3412,3415,3414,3416,3406,3414,3416,3416,3413,3413,11 +2026-09-05T11:34:49.541Z,module3,,3383,3398,3380,3381,3380,3502,3380,3381,3381,3445,3383,3523,3381,3382,3515,143 +2026-09-05T11:35:09.686Z,module1,,3379,3380,3380,3378,3382,3516,3478,3380,3382,3380,3405,3479,3382,3535,3380,157 +2026-09-05T11:35:09.845Z,module2,,3417,3415,3417,3417,3417,3412,3416,3414,3416,3406,3415,3417,3417,3414,3413,11 +2026-09-05T11:35:10.002Z,module3,,3383,3398,3380,3381,3380,3501,3380,3381,3382,3443,3383,3522,3381,3382,3513,142 +2026-09-05T11:35:30.148Z,module1,,3380,3380,3381,3379,3382,3514,3477,3380,3382,3380,3406,3479,3382,3535,3380,156 +2026-09-05T11:35:30.303Z,module2,,3417,3415,3417,3417,3416,3412,3416,3414,3416,3405,3415,3417,3416,3414,3412,12 +2026-09-05T11:35:30.491Z,module3,,3383,3398,3381,3381,3380,3499,3380,3381,3382,3440,3384,3519,3381,3383,3510,139 +2026-09-05T11:35:50.637Z,module1,,3380,3380,3381,3378,3382,3512,3475,3380,3382,3379,3405,3477,3382,3534,3380,156 +2026-09-05T11:35:50.793Z,module2,,3416,3415,3416,3416,3416,3411,3415,3413,3415,3405,3414,3416,3416,3413,3412,11 +2026-09-05T11:35:50.949Z,module3,,3383,3398,3380,3381,3381,3496,3380,3381,3382,3440,3383,3517,3381,3383,3509,137 +2026-09-05T11:36:11.096Z,module1,,3380,3380,3381,3379,3382,3510,3475,3381,3382,3380,3406,3477,3382,3533,3380,154 +2026-09-05T11:36:11.256Z,module2,,3417,3414,3416,3417,3416,3412,3415,3414,3416,3405,3414,3416,3416,3413,3412,12 +2026-09-05T11:36:11.415Z,module3,,3385,3401,3383,3383,3383,3497,3381,3383,3384,3442,3385,3518,3383,3385,3511,137 +2026-09-05T11:36:31.532Z,module1,,3380,3381,3381,3379,3382,3509,3473,3381,3383,3380,3406,3476,3383,3532,3380,153 +2026-09-05T11:36:31.689Z,module2,,3416,3414,3416,3416,3415,3412,3415,3413,3415,3404,3414,3416,3416,3413,3411,12 +2026-09-05T11:36:31.845Z,module3,,3386,3403,3383,3384,3383,3497,3382,3384,3385,3441,3386,3517,3384,3385,3509,135 +2026-09-05T11:36:51.991Z,module1,,3380,3381,3381,3379,3382,3508,3473,3381,3383,3380,3406,3475,3383,3532,3380,153 +2026-09-05T11:36:52.148Z,module2,,3416,3414,3416,3416,3416,3411,3415,3413,3415,3404,3413,3416,3416,3413,3412,12 +2026-09-05T11:36:52.304Z,module3,,3387,3405,3384,3385,3385,3497,3383,3385,3386,3441,3387,3517,3385,3386,3509,134 +2026-09-05T11:37:12.451Z,module1,,3380,3381,3381,3379,3383,3505,3471,3381,3383,3380,3406,3473,3383,3531,3381,152 +2026-09-05T11:37:12.640Z,module2,,3416,3414,3415,3416,3415,3411,3414,3413,3415,3403,3413,3415,3415,3412,3411,13 +2026-09-05T11:37:12.798Z,module3,,3387,3406,3385,3385,3385,3495,3384,3385,3386,3440,3388,3515,3385,3387,3507,131 +2026-09-05T11:37:32.938Z,module1,,3380,3381,3381,3379,3383,3503,3470,3381,3383,3380,3406,3472,3383,3530,3381,151 +2026-09-05T11:37:33.095Z,module2,,3415,3414,3415,3415,3415,3411,3414,3413,3414,3402,3413,3415,3415,3412,3410,13 +2026-09-05T11:37:33.252Z,module3,,3388,3407,3385,3386,3386,3494,3385,3386,3387,3438,3389,3514,3386,3387,3505,129 +2026-09-05T11:37:53.398Z,module1,,3380,3381,3381,3379,3382,3502,3469,3381,3383,3380,3406,3471,3383,3529,3380,150 +2026-09-05T11:37:53.554Z,module2,,3415,3413,3415,3415,3415,3410,3414,3412,3414,3402,3412,3415,3415,3412,3410,13 +2026-09-05T11:37:53.710Z,module3,,3389,3407,3385,3386,3386,3493,3385,3386,3387,3437,3389,3513,3386,3388,3504,128 +2026-09-05T11:38:13.856Z,module1,,3379,3381,3381,3379,3383,3498,3466,3381,3383,3380,3405,3468,3383,3527,3381,148 +2026-09-05T11:38:14.015Z,module2,,3415,3413,3416,3416,3416,3410,3414,3413,3415,3403,3412,3415,3415,3412,3412,13 +2026-09-05T11:38:14.172Z,module3,,3388,3407,3385,3386,3386,3491,3385,3386,3387,3435,3389,3510,3386,3388,3501,125 +2026-09-05T11:38:34.307Z,module1,,3381,3382,3382,3380,3385,3499,3467,3383,3385,3382,3407,3470,3385,3529,3382,149 +2026-09-05T11:38:34.494Z,module2,,3416,3414,3416,3417,3416,3411,3415,3414,3416,3404,3414,3416,3416,3413,3412,13 +2026-09-05T11:38:34.650Z,module3,,3389,3409,3386,3387,3386,3489,3386,3387,3388,3433,3390,3507,3387,3388,3498,121 +2026-09-05T11:38:54.796Z,module1,,3382,3383,3383,3381,3386,3497,3467,3383,3385,3383,3408,3469,3385,3528,3383,147 +2026-09-05T11:38:54.954Z,module2,,3417,3414,3416,3417,3416,3412,3415,3414,3416,3404,3414,3416,3416,3413,3413,13 +2026-09-05T11:38:55.110Z,module3,,3389,3409,3386,3387,3386,3487,3386,3387,3388,3431,3390,3504,3387,3388,3496,118 +2026-09-05T11:39:15.257Z,module1,,3383,3384,3384,3382,3387,3497,3467,3385,3386,3384,3409,3469,3387,3528,3384,146 +2026-09-05T11:39:15.414Z,module2,,3417,3415,3417,3417,3417,3413,3416,3415,3416,3405,3415,3417,3417,3414,3413,12 +2026-09-05T11:39:15.572Z,module3,,3389,3410,3386,3387,3387,3486,3386,3387,3389,3430,3390,3503,3387,3389,3495,117 diff --git a/tools/guetter-plafond-bms.mjs b/tools/guetter-plafond-bms.mjs new file mode 100644 index 0000000..a09ad1e --- /dev/null +++ b/tools/guetter-plafond-bms.mjs @@ -0,0 +1,96 @@ +#!/usr/bin/env node +// Guette le plafond de courant de charge impose par le BMS et note chacun de +// ses changements, en y accolant les tensions de cellule relevees au meme +// moment par `pylontech-console.mjs --suivi` (le CSV le plus recent). +// +// Le point qui interesse : a quelle tension de cellule, et apres combien de +// temps, le BMS RELACHE. La retombee de l'alarme ne le dit pas — elle survient +// bien avant, le plafond restant bas plusieurs heures apres. +// +// node tools/guetter-plafond-bms.mjs [--minutes 55] [--pas 15] + +import fs from 'node:fs'; +import path from 'node:path'; + +const arg = (n, d) => { const i = process.argv.indexOf('--' + n); return i < 0 ? d : process.argv[i + 1]; }; +const PAS = Math.max(5, +arg('pas', 15)) * 1000; +const FIN_MS = Date.now() + Math.max(1, +arg('minutes', 55)) * 60000; +const DOSSIER = 'docs/mesures/batteries'; + +const env = Object.fromEntries( + fs.readFileSync('.env', 'utf8').split('\n') + .filter((l) => l.includes('=') && !l.startsWith('#')) + .map((l) => [l.slice(0, l.indexOf('=')).trim(), l.slice(l.indexOf('=') + 1).trim()])); + +const etat = async (id) => { + const r = await fetch('http://10.10.10.17:8123/api/states/' + id, + { headers: { Authorization: 'Bearer ' + env.HA_TOKEN } }); + return r.json(); +}; + +// Dernier relevé console par module, depuis le CSV du suivi en cours. +function cellulesRecentes() { + let f; + try { + f = fs.readdirSync(DOSSIER).filter((n) => n.endsWith('-suivi.csv')) + .map((n) => path.join(DOSSIER, n)) + .sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs)[0]; + } catch { return ''; } + if (!f || Date.now() - fs.statSync(f).mtimeMs > 180000) return ''; // suivi arrete + const lignes = fs.readFileSync(f, 'utf8').trim().split('\n').slice(1); + const parModule = new Map(); + for (const l of lignes) { const c = l.split(','); if (c.length > 17) parModule.set(c[1], c); } + const out = []; + for (const [nom, c] of parModule) { + const v = c.slice(3, 18).map(Number).filter((x) => x > 0); + if (!v.length) continue; + const hi = Math.max(...v); + out.push(`${nom} haute ${hi} mV (cellule ${v.indexOf(hi) + 1}, ecart ${hi - Math.min(...v)} mV)`); + } + return out.join(' · '); +} + +const h = () => new Date().toLocaleTimeString('fr-FR'); + +(async () => { + let plafond = null, depuis = Date.now(), plancher = Infinity; + const journal = []; + console.log(`Guet du plafond de charge, pas de ${PAS / 1000} s.`); + while (Date.now() < FIN_MS) { + let ccl, soc, alarme; + try { + [ccl, soc, alarme] = await Promise.all([ + etat('sensor.airtria_8_us2000c_maximum_allowed_charge_current'), + etat('sensor.victron_battery_soc'), + etat('sensor.airtria_8_us2000c_tension_de_cellule_elevee'), + ]); + } catch { await new Promise((r) => setTimeout(r, PAS)); continue; } + const v = parseFloat(ccl.state); + if (!Number.isFinite(v)) { await new Promise((r) => setTimeout(r, PAS)); continue; } + + if (plafond === null) { + plafond = v; plancher = v; + console.log(`${h()} plafond initial ${v} A · SOC ${soc.state} % · alarme ${alarme.state}`); + console.log(` ${cellulesRecentes()}`); + } else if (v !== plafond) { + const duree = Math.round((Date.now() - depuis) / 1000); + const sens = v > plafond ? 'REMONTE' : 'baisse '; + const ligne = `${h()} ${sens} ${plafond} -> ${v} A (apres ${Math.floor(duree / 60)} min ${duree % 60} s)` + + ` SOC ${soc.state} % alarme ${alarme.state}\n ${cellulesRecentes()}`; + console.log(ligne); journal.push(ligne); + const remonte = v > plafond && plafond <= plancher; + plafond = v; depuis = Date.now(); plancher = Math.min(plancher, v); + // --complet : suivre tout l'escalier de remontee au lieu de s'arreter + // a la premiere marche. La forme de la remontee est ce qui dit si le + // BMS relache par paliers fixes ou proportionnellement. + if (remonte && !arg('complet', false)) { + console.log('\n=== LE PLAFOND EST REMONTE ==='); + console.log(journal.join('\n')); + process.exit(0); + } + } + await new Promise((r) => setTimeout(r, PAS)); + } + console.log(`${h()} fin du guet, plafond toujours a ${plafond} A`); + if (journal.length) console.log(journal.join('\n')); +})(); diff --git a/tools/historise-evcs.mjs b/tools/historise-evcs.mjs index a01a1b9..a464e04 100644 --- a/tools/historise-evcs.mjs +++ b/tools/historise-evcs.mjs @@ -363,6 +363,28 @@ async function migrer(client) { 'ALTER TABLE session_charge ADD COLUMN IF NOT EXISTS energie_station_kwh double precision'); await client.query( 'CREATE INDEX IF NOT EXISTS session_charge_debut_idx ON session_charge (debut DESC)'); + + // Tensions cellule par cellule des modules Pylontech. La source est la + // console serie du BMS, pas Home Assistant : aucune de ces valeurs n'est + // publiee cote Victron, qui n'expose que l'agregat du parc. + // + // L'identite d'un module est son CODE-BARRES, jamais son adresse : chaque + // chaine renumerote ses modules a partir de 1, donc il existe deux + // « module 1 » dans ce parc. + await client.query(` + CREATE TABLE IF NOT EXISTS cellule ( + ts timestamptz NOT NULL, + module text NOT NULL, + cellule smallint NOT NULL, + mv integer NOT NULL, + soc smallint, + courant_ma integer, + etat text, + source text NOT NULL, + PRIMARY KEY (ts, module, cellule) + )`); + await client.query( + 'CREATE INDEX IF NOT EXISTS cellule_module_ts_idx ON cellule (module, ts DESC)'); // Le role de lecture doit voir la nouvelle table. S'il n'existe pas encore, // on ne fait pas echouer le demarrage pour autant. await client.query(`DO $$ BEGIN diff --git a/tools/importer-cellules.mjs b/tools/importer-cellules.mjs new file mode 100644 index 0000000..94f32d7 --- /dev/null +++ b/tools/importer-cellules.mjs @@ -0,0 +1,182 @@ +#!/usr/bin/env node +// Verse dans PostgreSQL les tensions cellule par cellule relevees sur la +// console des BMS Pylontech, pour qu'elles soient tracables dans Grafana a +// cote du reste du systeme. +// +// Deux sources, deux formats : +// - les exports d'historique (`--historique`, ou `datalist history dtls`) +// un enregistrement toutes les 30 minutes, jusqu'a 1798 par module ; +// - les CSV de suivi (`--suivi`), au pas choisi pendant un essai. +// +// A executer LA OU le mot de passe existe, c'est-a-dire dans le conteneur +// d'historisation, qui monte le depot en lecture seule : +// +// sudo docker compose exec historisation \ +// node tools/importer-cellules.mjs 'docs/mesures/batteries/*' +// +// --a-blanc analyse et compte, n'ecrit rien. + +import fs from 'node:fs'; +import path from 'node:path'; +import pg from 'pg'; + +const args = process.argv.slice(2); +const BLANC = args.includes('--a-blanc'); +const motifs = args.filter((a) => !a.startsWith('--')); + +// Correspondance adresse -> code-barres pour les CSV de suivi, qui ne portent +// que l'adresse. Chaque chaine renumerote a partir de 1 : une adresse seule +// est ambigue dans ce parc. Completer au fil des relevés `info `. +const CARTE_SUIVI = { + 1: 'K220803C30160322', // pack ancien, adresse 1 + 3: 'K220803C30160319', // pack ancien, adresse 3 + // 2 : code-barres pas encore releve -> enregistre en 'pack_ancien:2' +}; + +const lireTexte = (f) => { + const brut = fs.readFileSync(f); + const utf16 = brut[0] === 0xff && brut[1] === 0xfe; + return brut.toString(utf16 ? 'utf16le' : 'utf8').replace(/\r/g, ''); +}; + +// ---------------------------------------------------------------- historique +function lireHistorique(f) { + const txt = lireTexte(f); + const bc = txt.match(/Barcode\s*:\s*(\S+)/); + if (!bc) return null; + const recs = new Map(); + for (const ligne of txt.split('\n')) { + const c = ligne.split(/\s+/).filter(Boolean); + if (c.length < 18 + 15 * 6) continue; + if (!/^\d+$/.test(c[0]) || !/^\d\d-\d\d-\d\d$/.test(c[1])) continue; + const [a, m, j] = c[1].split('-').map(Number); + const [H, M, S] = c[2].split(':').map(Number); + recs.set(+c[0], { + // heure MODULE, corrigee plus bas + brut: Date.UTC(2000 + a, m - 1, j, H, M, S), + courant: +c[4], soc: parseInt(c[16], 10), etat: c[10], + mv: Array.from({ length: 15 }, (_, k) => +c[18 + k * 6 + 1]), + }); + } + if (!recs.size) return null; + + // L'horloge des modules derive de plusieurs heures. Plutot que de la + // demander, on la DEDUIT : l'enregistrement le plus RECENT d'un export est, + // a une demi-periode pres, contemporain de l'export lui-meme. + // + // ⚠️ Le plus recent n'est PAS celui de plus grand index : le tampon du BMS + // est circulaire, il reecrit par-dessus le plus ancien. Trier par index + // donnait des decalages de -865 h. + const rangs = [...recs.keys()].sort((x, y) => recs.get(x).brut - recs.get(y).brut); + // Depuis le 05/09, `pylontech-console.mjs --historique` inscrit le decalage + // en tete, mesure a la seconde de l'export. C'est la seule valeur exacte : + // on la prefere toujours a la deduction. + const entete = txt.match(/^# decalage_minutes\s*:\s*(-?\d+)/m); + const force = args.find((a) => a.startsWith('--decalage=')); + let decalageMin, origine; + if (force) { decalageMin = +force.split('=')[1]; origine = 'impose'; } + else if (entete) { decalageMin = +entete[1]; origine = 'mesure a l\'export'; } + else { + const dernier = recs.get(rangs[rangs.length - 1]).brut; + decalageMin = Math.round((dernier - fs.statSync(f).mtimeMs) / 60000); + origine = 'DEDUIT, approximatif'; + } + const decalageMs = decalageMin * 60000; + // Garde : au-dela d'une journee, la deduction ne tient plus (fichier + // recopie, horodatage de fichier perdu). On refuse plutot que de deplacer + // des mesures n'importe ou. + if (Math.abs(decalageMin) > 24 * 60) { + throw new Error(`decalage deduit aberrant (${Math.round(decalageMin / 60)} h)`); + } + + const lignes = []; + for (const r of rangs) { + const x = recs.get(r); + // Le module ecrit en heure locale de Paris : on repasse par l'offset reel. + const t = new Date(x.brut - decalageMs); + const local = new Date(t.getTime() - new Date(t).getTimezoneOffset() * 60000); + for (let k = 0; k < 15; k++) { + lignes.push([local.toISOString(), bc[1], k + 1, x.mv[k], x.soc, x.courant, x.etat, 'historique']); + } + } + return { module: bc[1], decalageMin, origine, lignes, nb: rangs.length }; +} + +// --------------------------------------------------------------------- suivi +function lireSuivi(f) { + const lignes = []; + const modules = new Set(); + for (const l of lireTexte(f).trim().split('\n').slice(1)) { + const c = l.split(','); + if (c.length < 18) continue; + const ad = parseInt(String(c[1]).replace(/\D/g, ''), 10); + if (!Number.isFinite(ad)) continue; + const mod = CARTE_SUIVI[ad] || `pack_ancien:${ad}`; + modules.add(mod); + const cour = c[2] === '' ? null : +c[2]; + for (let k = 0; k < 15; k++) { + const mv = +c[3 + k]; + if (!(mv > 1000)) continue; + lignes.push([c[0], mod, k + 1, mv, null, cour, c[1] || null, 'suivi']); + } + } + return lignes.length ? { modules: [...modules], lignes } : null; +} + +// ---------------------------------------------------------------------- main +const fichiers = []; +for (const m of motifs) { + const d = path.dirname(m), base = path.basename(m); + const re = new RegExp('^' + base.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*') + '$'); + for (const n of fs.readdirSync(d)) if (re.test(n)) fichiers.push(path.join(d, n)); +} +if (!fichiers.length) { console.error('Aucun fichier.'); process.exit(1); } + +const paquets = []; +for (const f of fichiers.sort()) { + const n = path.basename(f); + try { + if (n.endsWith('-suivi.csv')) { + const r = lireSuivi(f); + if (r) { paquets.push(r.lignes); console.log(` ${n} suivi, ${r.lignes.length / 15} releves, modules ${r.modules.join(' ')}`); } + } else if (/histor/i.test(n) && n.endsWith('.txt')) { + // Les exports d'EVENEMENTS portent les memes colonnes mais decrivent des + // declenchements, pas un echantillonnage regulier : les melanger ferait + // des courbes fausses. + const r = lireHistorique(f); + if (r) { + paquets.push(r.lignes); + const d = r.decalageMin; + const t0 = r.lignes[0][0].slice(0, 16).replace('T', ' '); + const t1 = r.lignes[r.lignes.length - 1][0].slice(0, 16).replace('T', ' '); + console.log(` ${n}\n ${r.module}, ${r.nb} enregistrements, horloge ` + + `${d >= 0 ? '+' : '-'}${Math.trunc(Math.abs(d) / 60)} h ${Math.abs(d % 60)} min` + + ` (${r.origine}) -> ${t0} a ${t1}`); + } + } + } catch (e) { console.error(` ${n} ignore : ${e.message}`); } +} +const toutes = paquets.flat(); +console.log(`\n${toutes.length} lignes cellule au total.`); +if (BLANC) { console.log('A blanc : rien ecrit.'); process.exit(0); } + +const client = new pg.Client({ + host: process.env.PGHOST || '10.10.10.22', + port: Number(process.env.PGPORT || 5432), + user: process.env.PGUSER || 'evcs', + database: process.env.PGDATABASE || 'evcs', + password: process.env.PGPASSWORD, +}); +await client.connect(); +let ecrites = 0; +for (let i = 0; i < toutes.length; i += 500) { + const lot = toutes.slice(i, i + 500); + const val = lot.map((_, k) => `($${k * 8 + 1},$${k * 8 + 2},$${k * 8 + 3},$${k * 8 + 4},$${k * 8 + 5},$${k * 8 + 6},$${k * 8 + 7},$${k * 8 + 8})`).join(','); + const r = await client.query( + `INSERT INTO cellule (ts, module, cellule, mv, soc, courant_ma, etat, source) + VALUES ${val} ON CONFLICT (ts, module, cellule) DO NOTHING`, lot.flat()); + ecrites += r.rowCount; + process.stdout.write(`\r ${i + lot.length} / ${toutes.length} `); +} +console.log(`\n${ecrites} lignes nouvelles, ${toutes.length - ecrites} deja presentes.`); +await client.end(); diff --git a/tools/pylontech-console.mjs b/tools/pylontech-console.mjs index a026694..d4b526a 100644 --- a/tools/pylontech-console.mjs +++ b/tools/pylontech-console.mjs @@ -208,6 +208,25 @@ async function main() { console.log(`Extraction de l'historique a partir de l'enregistrement ${depuis}.`); console.log('Le module en garde 1798, un toutes les 30 minutes : comptez plusieurs minutes.'); const f = journal(nom, `# releve du ${horodate()} sur ${dev}\n`); + // L'horloge du module derive de plusieurs heures et chaque module a la + // sienne. On la CAPTURE ici, a la seconde ou l'export commence, plutot que + // de la deduire ensuite : le tampon d'historique est circulaire et contient + // des enregistrements anterieurs a des remises a l'heure, ce qui rend toute + // deduction a posteriori fausse de plusieurs heures. + const rtc = await commande(l, 'time', 8000); + const m = rtc.match(/RTC\s+(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/); + if (m) { + const reel = new Date(); + const mod = new Date(m[1].replace(' ', 'T') + 'Z'); + const decMin = Math.round((mod.getTime() - + (reel.getTime() - reel.getTimezoneOffset() * 60000)) / 60000); + journal(nom, `# RTC module : ${m[1]}\n# heure reelle : ${reel.toISOString()}\n` + + `# decalage_minutes : ${decMin}\n`); + console.log(`Horloge du module : ${m[1]} — decalage ${decMin} min sur l'heure reelle.`); + } else { + journal(nom, '# RTC module : non lu\n'); + console.log('Horloge du module non lue : le decalage devra etre donne a l\'import.'); + } journal(nom, await commande(l, 'info', 8000)); // UNE seule commande suffit : le module pagine lui-meme jusqu'au dernier // enregistrement, `commande` tourne les pages. Boucler sur des index