github.com/archlabjp/eeslism-go@v0.0.0-20231109122333-4bb7bfcdf292/eeslism/escntlsch_s.go (about) 1 //This file is part of EESLISM. 2 // 3 //Foobar is free software : you can redistribute itand /or modify 4 //it under the terms of the GNU General Public License as published by 5 //the Free Software Foundation, either version 3 of the License, or 6 //(at your option) any later version. 7 // 8 //Foobar is distributed in the hope that it will be useful, 9 //but WITHOUT ANY WARRANTY; without even the implied warranty of 10 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 11 //GNU General Public License for more details. 12 // 13 //You should have received a copy of the GNU General Public License 14 //along with Foobar.If not, see < https://www.gnu.org/licenses/>. 15 16 /* es_cntlsch_s.c */ 17 package eeslism 18 19 import ( 20 "fmt" 21 "io" 22 ) 23 24 func Contlschdlr(_Contl []*CONTL, Mpath []*MPATH, _Compnt []*COMPNT) { 25 26 // 全ての経路、機器を停止で初期化 27 for _, Mp := range Mpath { 28 Mp.Control = OFF_SW 29 Mp.mpathschd(OFF_SW) 30 } 31 32 // 機器の制御情報を「停止」で初期化 33 for i := range _Compnt { 34 Compnt := _Compnt[i] 35 Compnt.Control = OFF_SW 36 37 if Compnt.Eqptype == VALV_TYPE || Compnt.Eqptype == TVALV_TYPE { 38 v := Compnt.Eqp.(*VALV) 39 if v.Xinit != nil { 40 v.X = *v.Xinit 41 } else { 42 v.X = 1.0 43 } 44 } 45 46 for m := 0; m < Compnt.Nout; m++ { 47 Eo := Compnt.Elouts[m] 48 Eo.Sysld = 'n' 49 Eo.Control = OFF_SW 50 } 51 } 52 53 // CONTLの制御情報を反映 54 for _, Contl := range _Contl { 55 Contl.Lgv = 1 56 // True:1、False:0 57 // if分で制御される場合 58 if Contl.Type == 'c' { 59 Contl.Lgv = contrlif(Contl.Cif) 60 61 // ANDで2条件の場合 62 if Contl.AndCif != nil { 63 Contl.Lgv = Contl.Lgv * contrlif(Contl.AndCif) 64 } 65 66 // ANDで3条件の場合 67 if Contl.AndAndCif != nil { 68 Contl.Lgv = Contl.Lgv * contrlif(Contl.AndAndCif) 69 } 70 71 // or条件の場合 72 if Contl.OrCif != nil { 73 Contl.Lgv = Contl.Lgv + contrlif(Contl.OrCif) 74 } 75 } 76 77 if Contl.Lgv != 0 { 78 if Contl.Cst != nil { 79 if Contl.Cst.Type == VAL_CTYPE { 80 *Contl.Cst.Lft.V = *Contl.Cst.Rgt.V 81 } else { 82 *Contl.Cst.Lft.S = *Contl.Cst.Rgt.S 83 84 if Contl.Cst.PathType == MAIN_CPTYPE { 85 Mp := Contl.Cst.Path.(*MPATH) 86 Mp.Control = *Contl.Cst.Lft.S 87 Mp.mpathschd(Mp.Control) 88 } else if Contl.Cst.PathType == LOCAL_CPTYPE { 89 Pli := Contl.Cst.Path.(*PLIST) 90 Pli.lpathscdd(*Contl.Cst.Lft.S) 91 } 92 } 93 } 94 } 95 } 96 97 for i := range _Compnt { 98 Compnt := _Compnt[i] 99 100 switch Compnt.Eqptype { 101 case ROOM_TYPE: 102 if SIMUL_BUILDG { 103 Compnt.Control = ON_SW 104 Eo := Compnt.Elouts[0] 105 Eo.Control = ON_SW 106 Eo = Compnt.Elouts[1] 107 Eo.Control = ON_SW 108 roomldschd(Compnt.Eqp.(*ROOM)) 109 } 110 case BOILER_TYPE: 111 boildschd(Compnt.Eqp.(*BOI)) 112 case REFACOMP_TYPE: 113 refaldschd(Compnt.Eqp.(*REFA)) 114 case HCLOAD_TYPE, HCLOADW_TYPE, RMAC_TYPE, RMACD_TYPE: 115 hcldschd(Compnt.Eqp.(*HCLOAD)) 116 case PIPEDUCT_TYPE: 117 pipeldsschd(Compnt.Eqp.(*PIPE)) 118 case RDPANEL_TYPE: 119 rdpnlldsschd(Compnt.Eqp.(*RDPNL)) 120 case HCCOIL_TYPE: 121 Eo := Compnt.Elouts[1] 122 if Eo.Lpath == nil { 123 Eo.Control = OFF_SW 124 Hcc := Compnt.Eqp.(*HCC) 125 Hcc.Wet = 'd' 126 } 127 case FLIN_TYPE: 128 Compnt.Control = FLWIN_SW 129 Flin := Compnt.Eqp.(*FLIN) 130 Eo := Compnt.Elouts[0] 131 Eo.Control = FLWIN_SW 132 Eo.Sysv = *Flin.Vart 133 if Flin.Awtype == 'A' { 134 Eo := Compnt.Elouts[1] 135 Eo.Control = FLWIN_SW 136 Eo.Sysv = *Flin.Varx 137 } 138 } 139 140 for m := 0; m < Compnt.Nout; m++ { 141 Eo := Compnt.Elouts[m] 142 if Eo.Control == LOAD_SW { 143 Eo.Eldobj.Sysld = 'y' 144 } 145 } 146 } 147 148 for _, Mp := range Mpath { 149 for _, Pli := range Mp.Plist { 150 if Pli.Batch { 151 Pli.lpathschbat() 152 } 153 } 154 } 155 } 156 157 /* --------------------------------------------------- */ 158 159 func contrlif(ctlif *CTLIF) int { 160 var id int 161 var a, b float64 162 163 boolToInt := func(b bool) int { 164 if b { 165 return 1 166 } 167 return 0 168 } 169 170 if ctlif.Type == VAL_CTYPE { 171 a = *ctlif.Lft1.V 172 if ctlif.Nlft == 2 { 173 a -= *ctlif.Lft2.V 174 } 175 b = *ctlif.Rgt.V 176 177 switch ctlif.Op { 178 case 'l': 179 id = boolToInt(a < b) 180 case 'g': 181 id = boolToInt(a > b) 182 case 'E': 183 id = boolToInt(a == b) 184 case 'L': 185 id = boolToInt(a <= b) 186 case 'G': 187 id = boolToInt(a >= b) 188 case 'N': 189 id = boolToInt(a != b) 190 default: 191 id = 0 192 } 193 } else { 194 switch ctlif.Op { 195 case 'E': 196 id = boolToInt(*ctlif.Lft1.S == *ctlif.Rgt.S) 197 case 'N': 198 id = boolToInt(*ctlif.Lft1.S != *ctlif.Rgt.S) 199 default: 200 id = 0 201 } 202 } 203 204 return id 205 } 206 207 /* --------------------------------------------------- */ 208 209 func (mp *MPATH) mpathschd(control ControlSWType) { 210 for _, path := range mp.Plist { 211 path.Control = control 212 path.lpathscdd(control) 213 } 214 } 215 216 /* --------------------------------------------------- */ 217 218 func (plist *PLIST) lpathscdd(control ControlSWType) { 219 if plist.Org { 220 lpathschd(control, plist.Pelm) 221 222 if plist.Lpair != nil { 223 plist.Lpair.Control = control 224 lpathschd(control, plist.Lpair.Pelm) 225 } 226 } 227 } 228 229 /* --------------------------------------------------- */ 230 231 func lpathschd(control ControlSWType, pelm []*PELM) { 232 for _, Pelm := range pelm { 233 234 // 電気蓄熱暖房器の機器制御は変更しない 235 if Pelm.Cmp.Eqptype != STHEAT_TYPE { 236 Pelm.Cmp.Control = control 237 } 238 239 if Pelm.Out != nil { 240 // 一時的に室の場合は止められないようにした。電気蓄熱暖房器も同様 241 // 順次対応予定 242 if Pelm.Cmp.Eqptype != ROOM_TYPE { // && strcmp(Pelm.cmp.eqptype, STHEAT_TYPE) != 0) 243 Pelm.Out.Control = control 244 } 245 //else if (strcmp(Pelm.cmp.eqptype, STHEAT_TYPE) != 0) 246 // Pelm.out.control = control; 247 } 248 } 249 } 250 251 /* --------------------------------------------------- */ 252 253 /* 蓄熱槽のバッチ給水、排水時の設定 */ 254 255 func (Plist *PLIST) lpathschbat() { 256 var j, k, i, jt, ifl int 257 var batop ControlSWType 258 var Tsout, Gbat float64 259 var Stank *STANK 260 var Pelm *PELM 261 262 Stank = nil 263 for j, Pe := range Plist.Pelm { 264 265 if Pe.Cmp.Eqptype == STANK_TYPE { 266 Plist.G = Gbat 267 Gbat = 0.0 268 for k = 0; k < len(Pe.Cmp.Elouts); k++ { 269 if Pe.Out == Pe.Cmp.Elouts[k] { 270 break 271 } 272 } 273 Stank = Pe.Cmp.Eqp.(*STANK) 274 Stank.Batchop = OFF_SW 275 batop = Stank.Batchcon[k] 276 277 if batop == BTFILL { 278 for i = 0; i < Stank.Ndiv; i++ { 279 if Stank.DtankF[i] == TANK_EMPTY { 280 jt = j 281 Gbat += Stank.Dvol[i] 282 Stank.Batchop = BTFILL 283 } 284 } 285 } else { 286 ifl = 0 287 for i = 0; i < Stank.Ndiv; i++ { 288 if Stank.DtankF[i] == TANK_FULL { 289 ifl++ 290 } 291 } 292 if Stank.Ndiv == ifl { 293 Stank.Batchop = BTDRAW 294 jt = j 295 } 296 } 297 break 298 } 299 } 300 301 peiIdx := 0 302 if Stank.Batchop == BTFILL || Stank.Batchop == BTDRAW { 303 if Pelm.Out.Control == FLWIN_SW { 304 peiIdx++ 305 } 306 307 lpathschd(ON_SW, Plist.Pelm[peiIdx:]) 308 309 if Stank.Batchop == BTFILL { 310 Plist.G = Gbat * Row / DTM 311 lpathschd(OFF_SW, Plist.Pelm[jt:]) 312 Plist.Pelm[jt].Out.Control = BATCH_SW 313 } else if Stank.Batchop == BTDRAW { 314 lpathschd(OFF_SW, Plist.Pelm[:jt]) 315 Plist.Pelm[jt].Out.Control = BATCH_SW 316 317 for j = 0; j <= Stank.Jout[k]; j++ { 318 Stank.DtankF[j] = TANK_EMPTY 319 Tsout += Stank.Tssold[j] 320 Gbat += Stank.Dvol[j] 321 } 322 Tsout /= float64(Stank.Jout[k] + 1) 323 Plist.G = Gbat * Row / DTM 324 325 Plist.Pelm[jt].Out.Sysv = Tsout 326 } 327 } 328 } 329 330 /* --------------------------------------------------- */ 331 332 func contlxprint(Ncontl int, C *CONTL, out io.Writer) { 333 var i int 334 var cif *CTLIF 335 var cst *CTLST 336 var V float64 337 var Contl *CONTL 338 339 Contl = C 340 if DEBUG { 341 fmt.Fprintln(out, "contlxprint --- Contlschdlr") 342 343 for i = 0; i < Ncontl; i++ { 344 fmt.Fprintf(out, "[%d] type=%c lgv=%d\n", 345 i, Contl.Type, Contl.Lgv) 346 cif = Contl.Cif 347 cst = Contl.Cst 348 349 if cif != nil { 350 fmt.Fprintf(out, " iftype=%c [ %c ]", cif.Type, cif.Op) 351 if cif.Type == VAL_CTYPE { 352 if cif.Nlft > 1 { 353 V = *cif.Lft2.V 354 } else { 355 V = 0.0 356 } 357 358 fmt.Fprintf(out, " lft1=%.2f lft2=%.2f rgt=%.2f\n", *cif.Lft1.V, V, *cif.Rgt.V) 359 } else { 360 fmt.Fprintf(out, " lft1=%s lft2=%s rgt=%s\n", *cif.Lft1.S, *cif.Lft2.S, *cif.Rgt.S) 361 } 362 } 363 364 fmt.Fprintf(out, " sttype=%c pathtype=%c", cst.Type, cst.PathType) 365 if cst.Type == VAL_CTYPE { 366 fmt.Fprintf(out, " lft=%.2f rgt=%.2f\n", *cst.Lft.V, *cst.Rgt.V) 367 } else { 368 fmt.Fprintf(out, " lft=%s rgt=%s\n", *cst.Lft.S, *cst.Rgt.S) 369 } 370 } 371 } 372 373 Contl = C 374 if Ferr != nil { 375 fmt.Fprintln(out, "contlxprint --- Contlschdlr") 376 377 for i = 0; i < Ncontl; i++ { 378 fmt.Fprintf(out, "[%d]\ttype=%c\tlgv=%d\n", i, Contl.Type, Contl.Lgv) 379 cif = Contl.Cif 380 cst = Contl.Cst 381 382 if cif != nil { 383 fmt.Fprintf(out, "\tiftype=%c\t[%c]", cif.Type, cif.Op) 384 if cif.Type == VAL_CTYPE { 385 if cif.Nlft > 1 { 386 V = *cif.Lft2.V 387 } else { 388 V = 0.0 389 } 390 391 fmt.Fprintf(out, "\tlft1=%.2f\tlft2=%.2f\trgt=%.2f\n", *cif.Lft1.V, V, *cif.Rgt.V) 392 } else { 393 fmt.Fprintf(out, "\tlft1=%s\tlft2=%s\trgt=%s\n", *cif.Lft1.S, *cif.Lft2.S, *cif.Rgt.S) 394 } 395 } 396 397 fmt.Fprintf(out, "\tsttype=%c\tpathtype=%c", cst.Type, cst.PathType) 398 if cst.Type == VAL_CTYPE { 399 fmt.Fprintf(out, "\tlft=%.2f\trgt=%.2f\n", *cst.Lft.V, *cst.Rgt.V) 400 } else { 401 fmt.Fprintf(out, "\tlft=%s\trgt=%s\n", *cst.Lft.S, *cst.Rgt.S) 402 } 403 } 404 } 405 } 406 407 /* --------------------------------------------------- */ 408 409 /* 負荷計算モードの再設定、 410 暖房時冷房負荷または冷房時暖房負荷のときは自然室温計算 */ 411 412 func rmloadreset(Qload float64, loadsw ControlSWType, Eo *ELOUT, SWITCH ControlSWType) int { 413 if Eo.Sysld == 'y' { 414 if (loadsw == HEATING_LOAD && Qload < 0.0) || 415 (loadsw == COOLING_LOAD && Qload > 0.0) { 416 Eo.Control = SWITCH 417 Eo.Sysld = 'n' 418 return 1 419 } else { 420 return 0 421 } 422 } else { 423 return 0 424 } 425 } 426 427 /* --------------------------------------------------- */ 428 429 /* 加熱、冷却モードの再設定、 430 加熱房時冷房負荷または冷却時暖房負荷のときは機器停止 */ 431 432 func chswreset(Qload float64, chmode ControlSWType, Eo *ELOUT) int { 433 var Elo *ELOUT 434 435 if (chmode == HEATING_SW && Qload < 0.0) || 436 (chmode == COOLING_SW && Qload > 0.0) { 437 Elo = Eo 438 Elo.Control = ON_SW 439 Elo.Sysld = 'n' 440 Elo.Emonitr.Control = ON_SW 441 return 1 442 } else { 443 return 0 444 } 445 } 446 447 /* --------------------------------------------------- */ 448 449 /* 仮想空調機の再設定 450 湿りコイルの非除湿時乾きコイルへの変更 */ 451 452 func chqlreset(Hcload *HCLOAD) int { 453 454 Ql := Hcload.Ql 455 Qs := Hcload.Qs 456 wet := Hcload.Wetmode 457 chmode := Hcload.Chmode 458 Elo := Hcload.Cmp.Elouts[1] 459 //Elos := Hcload.Cmp.Elouts[0] 460 461 if (wet && Ql > 1.e-6) || (wet && Qs >= 0.0) { 462 Hcload.Wetmode = false 463 Elo.Control = ON_SW 464 Elo.Sysld = 'n' 465 466 if Elo.Emonitr != nil { 467 Elo.Emonitr.Control = ON_SW 468 } 469 470 return 1 471 } 472 473 if chmode == COOLING_SW && (Ql > 0.0 || Qs >= 0.0) { 474 Elo.Control = ON_SW 475 Hcload.Wetmode = false 476 Elo.Sysld = 'n' 477 if Elo.Emonitr != nil { 478 Elo.Emonitr.Control = ON_SW 479 } 480 481 return 1 482 } 483 484 return 0 485 } 486 487 /* 過負荷運転ための再設定 */ 488 489 func maxcapreset(Qload, Qmax float64, chmode ControlSWType, Eo *ELOUT) int { 490 var Boi *BOI 491 492 var Eosysld rune 493 var Boimode rune 494 var Eocontrol, Eoemonitrcontrol, Boicmpcntrol ControlSWType 495 496 Boi = Eo.Cmp.Eqp.(*BOI) 497 498 Eocontrol = Eo.Control 499 Eosysld = Eo.Sysld 500 if Eo.Emonitr != nil { 501 Eoemonitrcontrol = Eo.Emonitr.Control 502 } else { 503 return 0 504 } 505 506 Boicmpcntrol = Boi.Cmp.Control 507 Boimode = Boi.Mode 508 509 if (chmode == HEATING_SW && Qload > Qmax) || 510 (chmode == COOLING_SW && Qload < Qmax) { 511 // 過負荷なので最大能力で再計算する 512 Eo.Control = ON_SW 513 Eo.Sysld = 'n' 514 Eo.Emonitr.Control = ON_SW 515 Boi.Cmp.Control = ON_SW 516 517 //最大能力運転フラグ 518 Boi.Mode = 'M' 519 } 520 521 if Eo.Control == Eocontrol && 522 Eo.Sysld == Eosysld && 523 Eo.Emonitr.Control == Eoemonitrcontrol && 524 Boi.Cmp.Control == Boicmpcntrol && 525 Boi.Mode == Boimode { 526 return 0 527 } else { 528 return 1 529 } 530 }