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  }