<commit_before>package generatorControllers

import (
	. "eaciit/wfdemo-git/library/helper"
	. "eaciit/wfdemo-git/library/models"
	. "eaciit/wfdemo-git/processapp/summaryGenerator/controllers"
	"eaciit/wfdemo-git/web/helper"
	"log"
	"math"
	"os"
	"strconv"
	"sync"
	"time"

	"github.com/eaciit/dbox"
	_ "github.com/eaciit/dbox/dbc/mongo"
	tk "github.com/eaciit/toolkit"
)

type GenScadaSummary struct {
	*BaseController
}

func daysIn(m time.Month, year int) int {
	return time.Date(year, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
}

func (d *GenScadaSummary) Generate(base *BaseController) {
	if base != nil {
		d.BaseController = base

		ctx, e := PrepareConnection()
		if e != nil {
			ErrorHandler(e, "Scada Summary")
			os.Exit(0)
		}

		budgetMonths := []float64{
			5911.8744,
			6023.419200000001,
			7027.3224,
			8588.9496,
			14389.2792,
			16954.8096,
			15727.8168,
			12046.8384,
			9704.3976,
			5688.784799999999,
			3569.4336,
			5911.8744}

		d.BaseController.Ctx.DeleteMany(new(ScadaSummaryByMonth), dbox.Ne("projectname", ""))

		projectList := []ProjectOut{}
		projectList = append(projectList, ProjectOut{
			Name:   "",
			Value:  "Fleet",
			Coords: []float64{},
		})

		projects, _ := helper.GetProjectList()
		projectList = append(projectList, projects...)

		for _, v := range projectList {
			project := v.Value

			filter := []*dbox.Filter{}
			filter = append(filter, dbox.Gte("power", -200))
			group := []string{}

			if project != "Fleet" {
				filter = append(filter, dbox.Eq("projectname", project))
				group = []string{"projectname", "dateinfo.monthid"}
			} else {
				group = []string{"dateinfo.monthid"}
			}

			csr, e := ctx.NewQuery().From(new(ScadaData).TableName()).
				Where(dbox.And(filter...)).
				Aggr(dbox.AggrSum, "$power", "totalpower").
				Aggr(dbox.AggrSum, "$energy", "energy").
				Aggr(dbox.AggrSum, "$energylost", "totalenergylost").
				Aggr(dbox.AggrSum, "$oktime", "totaloktime").
				Aggr(dbox.AggrSum, "$minutes", "totalminutes").
				Aggr(dbox.AggrSum, "$griddowntime", "totalgriddowntime").
				Aggr(dbox.AggrSum, "$unknowntime", "totalunknowntime").
				Aggr(dbox.AggrSum, "$machinedowntime", "totalmachinedowntime").
				Aggr(dbox.AggrAvr, "$avgwindspeed", "avgwindspeed").
				Aggr(dbox.AggrSum, 1, "totaltimestamp").
				Aggr(dbox.AggrMax, "$dateinfo.dateid", "maxdateid").
				Aggr(dbox.AggrMin, "$dateinfo.dateid", "mindateid").
				Group(group...).
				Cursor(nil)
			defer csr.Close()

			if e != nil {
				ErrorHandler(e, "Scada Summary")
				os.Exit(0)
			}

			datas := []tk.M{}
			e = csr.Fetch(&datas, 0, false)

			divider := 1000.0

			for _, data := range datas {
				id := data["_id"].(tk.M)
				imonthid := id["dateinfo_monthid"].(int)
				monthid := strconv.Itoa(imonthid)
				year := monthid[0:4]
				month := monthid[4:6]
				day := "01"

				var turbineList []TurbineOut
				noOfTurbine := 0

				if project != "Fleet" {
					turbineList, _ = helper.GetTurbineList([]interface{}{project})
				} else {
					turbineList, _ = helper.GetTurbineList(nil)
				}
				noOfTurbine = len(turbineList)

				iMonth, _ := strconv.Atoi(string(month))
				iMonth = iMonth - 1

				dtStr := year + "-" + month + "-" + day
				dtId, _ := time.Parse("2006-01-02", dtStr)
				dtinfo := GetDateInfo(dtId)
				ioktime := data["totaloktime"]
				oktime := 0.0
				if ioktime != nil {
					oktime = (ioktime.(float64)) / 3600 // divide by 3600 secs, result in hours
				}

				revenueTimes := 5.74

				duration := 0.0
				lostEnergy := 0.0

				ipower := data["totalpower"]
				power := 0.0
				if ipower != nil {
					power = ipower.(float64)
				}

				ienergy := data["energy"]
				energy := 0.0
				if ienergy != nil {
					energy = ienergy.(float64)
				}

				iminutes := data["totalminutes"]
				minutes := 0.0
				if iminutes != nil {
					minutes = float64(iminutes.(int)) / 60
				}

				imaxdate := data["maxdateid"]
				imindate := data["mindateid"]
				maxdate := time.Now()
				mindate := time.Now()
				if imaxdate != nil {
					maxdate = imaxdate.(time.Time)
				}

				if imindate != nil {
					mindate = imindate.(time.Time)
				}
				//log.Printf("#%v\n", (power / 6000000))

				pipe := []tk.M{tk.M{}.Set("$unwind", "$detail"),
					tk.M{}.Set("$match", tk.M{}.Set("detail.detaildateinfo.monthid", imonthid)), tk.M{}.Set("$group", tk.M{}.Set("_id", "$projectname").Set("duration", tk.M{}.Set("$sum", "$detail.duration")).Set("powerlost", tk.M{}.Set("$sum", "$detail.powerlost")))}
				// log.Printf("#%v\n", pipe)
				csr1, _ := ctx.NewQuery().
					Command("pipe", pipe).
					From(new(Alarm).TableName()).
					Cursor(nil)
				defer csr1.Close()

				alarms := []tk.M{}
				e = csr1.Fetch(&alarms, 0, false)

				// log.Printf("#%v\n", alarms)

				if len(alarms) > 0 {
					alarm := alarms[0]
					ipowerlost := alarm["powerlost"]
					if ipowerlost != nil {
						lostEnergy = ipowerlost.(float64)
					}
					iduration := alarm["duration"]
					if iduration != nil {
						duration = iduration.(float64)
					}
				}
				//log.Println("Lost:", lostEnergy)
				//log.Println("Duration:", duration)

				powerlastyear := 0.0
				// powerlost := data["totalpowerlost"].(float64)
				// griddowntime := data["totalgriddowntime"].(float64)
				iwindspeed := data["avgwindspeed"]
				windspeed := 0.0
				if iwindspeed != nil {
					windspeed = iwindspeed.(float64)
				}

				itotaldata := data["totaltimestamp"]
				totaldata := 0
				if itotaldata != nil {
					totaldata = itotaldata.(int)
				}

				igriddowntime := data["totalgriddowntime"]
				griddowntime := 0.0
				if igriddowntime != nil {
					griddowntime = igriddowntime.(float64) / 3600
				}

				imachinedowntime := data["totalmachinedowntime"]
				machinedowntime := 0.0
				if imachinedowntime != nil {
					machinedowntime = imachinedowntime.(float64) / 3600
				}

				iunknowntime := data["totalunknowntime"]
				unknowntime := 0.0
				if iunknowntime != nil {
					unknowntime = iunknowntime.(float64) / 3600
				}
				_ = machinedowntime
				_ = griddowntime
				_ = unknowntime

				expwstimes := 0.133
				randno := tk.RandInt(5)
				//log.Printf("#%v\n", randno)
				if randno > 3 {
					expwstimes = -0.125
				}

				expWindSpeed := (windspeed + (windspeed * expwstimes))
				revenue := power * revenueTimes
				revenueInLacs := revenue / 100000

				tStart, _ := time.Parse("020601_150405", "01"+maxdate.UTC().Format("0601")+"_000000")
				daysInYear := GetDayInYear(tStart.Year())
				days := daysInYear.GetInt(tk.ToString(int(tStart.Month())))

				tEnd, _ := time.Parse("020601_150405", tk.ToString(days)+maxdate.UTC().Format("0601")+"_235959")

				hourValue := helper.GetHourValue(tStart.UTC(), tEnd.UTC(), mindate.UTC(), maxdate.UTC())

				var plfDivider float64

				for _, v := range turbineList {
					plfDivider += v.Capacity
				}

				machineAvail, gridAvail, scadaAvail, trueAvail, plf := helper.GetAvailAndPLF(float64(noOfTurbine), oktime*3600, energy/1000, machinedowntime, griddowntime, float64(totaldata), hourValue, minutes, plfDivider)

				if plf > 100 {
					plf = 100
				}
				if gridAvail > 100 {
					gridAvail = 100
				}
				if scadaAvail > 100 {
					scadaAvail = 100
				}
				if machineAvail > 100 {
					machineAvail = 100
				}

				budget := budgetMonths[iMonth]

				mdl := new(ScadaSummaryByMonth).New()
				mdl.ProjectName = project
				mdl.DateInfo = dtinfo
				mdl.Production = ((power / 6) / divider)
				mdl.ProductionLastYear = (powerlastyear / divider)
				mdl.Revenue = revenue
				mdl.RevenueInLacs = revenueInLacs
				mdl.TrueAvail = trueAvail
				mdl.ScadaAvail = scadaAvail
				mdl.MachineAvail = machineAvail
				mdl.GridAvail = gridAvail
				mdl.PLF = plf
				mdl.Budget = budget * 1000
				mdl.AvgWindSpeed = windspeed
				mdl.ExpWindSpeed = expWindSpeed
				mdl.DowntimeHours = duration
				mdl.LostEnergy = lostEnergy / (divider * divider) // convert to giga
				mdl.RevenueLoss = (lostEnergy * revenueTimes)

				if mdl != nil {
					d.BaseController.Ctx.Insert(mdl)
				}

			}

		}

	}
}

func (d *GenScadaSummary) GenerateSummaryByProject(base *BaseController) {
	if base != nil {

		d.BaseController = base

		ctx, e := PrepareConnection()
		if e != nil {
			ErrorHandler(e, "Scada Summary")
			os.Exit(0)
		}

		d.BaseController.Ctx.DeleteMany(new(ScadaSummaryByProject), dbox.Ne("_id", ""))

		projectList := []ProjectOut{}
		projectList = append(projectList, ProjectOut{
			Name:   "",
			Value:  "Fleet",
			Coords: []float64{},
		})

		projects, _ := helper.GetProjectList()
		projectList = append(projectList, projects...)

		for _, v := range projectList {
			var turbineList []TurbineOut
			projectName := v.Value
			group := "projectname"

			filter := []*dbox.Filter{}
			filter = append(filter, dbox.Gte("power", -200))

			if projectName != "Fleet" {
				filter = append(filter, dbox.Eq("projectname", projectName))
				group = "turbine"
				turbineList, _ = helper.GetTurbineList([]interface{}{projectName})
			}

			csr, e := ctx.NewQuery().From(new(ScadaData).TableName()).
				Where(dbox.And(filter...)).
				Aggr(dbox.AggrSum, "$power", "totalpower").
				Aggr(dbox.AggrSum, "$energy", "energy").
				Aggr(dbox.AggrSum, "$energylost", "totalenergylost").
				Aggr(dbox.AggrSum, "$oktime", "totaloktime").
				Aggr(dbox.AggrSum, "$minutes", "totalminutes").
				Aggr(dbox.AggrSum, "$griddowntime", "totalgriddowntime").
				Aggr(dbox.AggrSum, "$unknowntime", "totalunknowntime").
				Aggr(dbox.AggrSum, "$machinedowntime", "totalmachinedowntime").
				Aggr(dbox.AggrAvr, "$avgwindspeed", "avgwindspeed").
				Aggr(dbox.AggrMax, "$dateinfo.dateid", "max").
				Aggr(dbox.AggrMin, "$dateinfo.dateid", "min").
				Group(group).
				Cursor(nil)
			defer csr.Close()

			_ = e

			datas := []tk.M{}
			e = csr.Fetch(&datas, 0, false)

			_, max, _ := GetDataDateAvailable(new(ScadaData).TableName(), "dateinfo.dateid", nil, d.Ctx.Connection)

			// daysInMonth := GetDayInYear(max.Year())
			// days := tk.ToString(daysInMonth.GetInt(tk.ToString(int(max.Month()))))
			// tmpdt, _ := time.Parse("060102_150405", max.UTC().Format("0601")+days+"_000000")
			tmpdt := max.UTC()
			endDate := tmpdt.UTC() //time.Parse("060102_150405", max.UTC().Format("0601")+"01_000000").UTC()
			startDate := GetNormalAddDateMonth(tmpdt.UTC(), -11)

			mdl := new(ScadaSummaryByProject).New()
			mdl.ID = projectName

			items := make([]ScadaSummaryByProjectItem, 0)
			for _, data := range datas {
				id := data["_id"].(tk.M)
				turbine := id[group].(string)
				idfield := "turbine"
				totalWtg := 0

				if projectName == "Fleet" {
					turbineList, _ = helper.GetTurbineList([]interface{}{turbine})
					idfield = "farm"
				}

				match := tk.M{}.
					Set(idfield, tk.M{}.Set("$eq", turbine)).
					Set("detail.detaildateinfo.dateid", tk.M{}.Set("$gte", startDate).Set("$lte", endDate))

				ioktime := data["totaloktime"]
				oktime := 0.0
				if ioktime != nil {
					oktime = (ioktime.(float64)) /// 3600 // divide by 3600 secs, result in hours
				}

				iminutes := data["totalminutes"]
				minutes := 0.0
				if iminutes != nil {
					valminutes, ok := iminutes.(float64) // divide by 60 secs, result in hours
					if !ok {
						ivalminutes := iminutes.(int)
						minutes = float64(ivalminutes) / 60.0
					} else {
						minutes = valminutes / 60.0
					}
				}
				_ = minutes

				downtimeHours := 0.0
				lostEnergy := 0.0

				// ilostEnergy := data["totalenergylost"]
				// if ilostEnergy != nil {
				// 	lostEnergy = ilostEnergy.(float64)
				// }

				pipe := []tk.M{
					tk.M{}.Set("$unwind", "$detail"),
					tk.M{}.Set("$match", match),
					tk.M{}.Set("$group", tk.M{}.Set("_id", "$"+idfield).
						Set("duration", tk.M{}.Set("$sum", "$detail.duration")).
						Set("powerlost", tk.M{}.Set("$sum", "$detail.powerlost"))),
					tk.M{}.Set("$sort", tk.M{}.Set("_id", 1)),
				}
				// log.Printf("#%v\n", pipe)
				csr1, _ := ctx.NewQuery().
					Command("pipe", pipe).
					From(new(Alarm).TableName()).
					Cursor(nil)
				defer csr1.Close()

				alarms := []tk.M{}
				e = csr1.Fetch(&alarms, 0, false)

				// log.Printf("#%v\n", alarms)

				if len(alarms) > 0 {
					alarm := alarms[0]
					ipowerlost := alarm["powerlost"]
					if ipowerlost != nil {
						lostEnergy = ipowerlost.(float64)
					}
					iduration := alarm["duration"]
					if iduration != nil {
						downtimeHours = iduration.(float64)
					}
				}

				ipower := data["totalpower"]
				power := 0.0
				if ipower != nil {
					power = ipower.(float64)
				}

				imachinedowntime := data["totalmachinedowntime"]
				machinedowntime := 0.0
				if imachinedowntime != nil {
					machinedowntime = imachinedowntime.(float64) / 3600
				}

				igriddowntime := data["totalgriddowntime"]
				griddowntime := 0.0
				if igriddowntime != nil {
					griddowntime = igriddowntime.(float64) / 3600
				}

				iunknowntime := data["totalunknowntime"]
				unknowntime := 0.0
				if iunknowntime != nil {
					unknowntime = iunknowntime.(float64) / 3600
				}

				_ = machinedowntime
				_ = griddowntime
				_ = unknowntime

				//downtimeHours = machinedowntime + griddowntime + unknowntime

				// machineAvail := (minutes - machinedowntime) / (durationInMonth * 24)

				maxDate := data.Get("max").(time.Time)
				minDate := data.Get("min").(time.Time)
				energy := data.GetFloat64("energy") / 1000

				hourValue := helper.GetHourValue(startDate.UTC(), endDate.UTC(), minDate.UTC(), maxDate.UTC())

				// log.Printf("%v | %v | %v \n", hourValue, minDate.String(), maxDate.String())
				var plfDivider float64
				for _, v := range turbineList {
					if projectName != "Fleet" {
						if v.Value == turbine {
							plfDivider += v.Capacity
							totalWtg += 1
						}
					} else {
						if v.Project == turbine {<commit_msg>fixing plf calculation on scada summary by month<commit_after>package generatorControllers

import (
	. "eaciit/wfdemo-git/library/helper"
	. "eaciit/wfdemo-git/library/models"
	. "eaciit/wfdemo-git/processapp/summaryGenerator/controllers"
	"eaciit/wfdemo-git/web/helper"
	"log"
	"math"
	"os"
	"strconv"
	"sync"
	"time"

	"github.com/eaciit/dbox"
	_ "github.com/eaciit/dbox/dbc/mongo"
	tk "github.com/eaciit/toolkit"
)

type GenScadaSummary struct {
	*BaseController
}

func daysIn(m time.Month, year int) int {
	return time.Date(year, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
}

func (d *GenScadaSummary) Generate(base *BaseController) {
	if base != nil {
		d.BaseController = base

		ctx, e := PrepareConnection()
		if e != nil {
			ErrorHandler(e, "Scada Summary")
			os.Exit(0)
		}

		budgetMonths := []float64{
			5911.8744,
			6023.419200000001,
			7027.3224,
			8588.9496,
			14389.2792,
			16954.8096,
			15727.8168,
			12046.8384,
			9704.3976,
			5688.784799999999,
			3569.4336,
			5911.8744}

		d.BaseController.Ctx.DeleteMany(new(ScadaSummaryByMonth), dbox.Ne("projectname", ""))

		projectList := []ProjectOut{}
		projectList = append(projectList, ProjectOut{
			Name:   "",
			Value:  "Fleet",
			Coords: []float64{},
		})

		projects, _ := helper.GetProjectList()
		projectList = append(projectList, projects...)

		for _, v := range projectList {
			project := v.Value

			filter := []*dbox.Filter{}
			filter = append(filter, dbox.Gte("power", -200))
			group := []string{}

			if project != "Fleet" {
				filter = append(filter, dbox.Eq("projectname", project))
				group = []string{"projectname", "dateinfo.monthid"}
			} else {
				group = []string{"dateinfo.monthid"}
			}

			csr, e := ctx.NewQuery().From(new(ScadaData).TableName()).
				Where(dbox.And(filter...)).
				Aggr(dbox.AggrSum, "$power", "totalpower").
				Aggr(dbox.AggrSum, "$energy", "energy").
				Aggr(dbox.AggrSum, "$energylost", "totalenergylost").
				Aggr(dbox.AggrSum, "$oktime", "totaloktime").
				Aggr(dbox.AggrSum, "$minutes", "totalminutes").
				Aggr(dbox.AggrSum, "$griddowntime", "totalgriddowntime").
				Aggr(dbox.AggrSum, "$unknowntime", "totalunknowntime").
				Aggr(dbox.AggrSum, "$machinedowntime", "totalmachinedowntime").
				Aggr(dbox.AggrAvr, "$avgwindspeed", "avgwindspeed").
				Aggr(dbox.AggrSum, 1, "totaltimestamp").
				Aggr(dbox.AggrMax, "$dateinfo.dateid", "maxdateid").
				Aggr(dbox.AggrMin, "$dateinfo.dateid", "mindateid").
				Group(group...).
				Cursor(nil)
			defer csr.Close()

			if e != nil {
				ErrorHandler(e, "Scada Summary")
				os.Exit(0)
			}

			datas := []tk.M{}
			e = csr.Fetch(&datas, 0, false)

			divider := 1000.0

			ids := tk.M{"bulan": "$dateinfo.monthid", "turbine": "$turbine"}
			pipe := []tk.M{
				{"$group": tk.M{"_id": ids}},
				{"$sort": tk.M{"dateinfo.monthid": 1}},
			}
			csrTurbine, e := ctx.NewQuery().
				From(new(ScadaData).TableName()).
				Where(dbox.And(filter...)).
				Command("pipe", pipe).
				Cursor(nil)

			if e != nil {
				ErrorHandler(e, "Scada Summary, error get turbine data on cursor")
			}
			defer csrTurbine.Close()

			dataTurbine := []tk.M{}
			e = csrTurbine.Fetch(&dataTurbine, 0, false)
			if e != nil {
				ErrorHandler(e, "Scada Summary, error get turbine data on fetch")
			}

			capacityPerMonth := map[string]float64{}
			totalTurbinePerMonth := map[string]float64{}
			var turbineMaster []TurbineOut
			noOfTurbine := 0.0
			var plfDivider float64
			if project != "Fleet" {
				turbineMaster, _ = helper.GetTurbineList([]interface{}{project})
			} else {
				turbineMaster, _ = helper.GetTurbineList(nil)
			}

			for _, turbineScada := range dataTurbine {
				aidi, _ := tk.ToM(turbineScada.Get("_id", tk.M{}))
				for _, turbine := range turbineMaster {
					if aidi.GetString("turbine") == turbine.Turbine {
						capacityPerMonth[tk.ToString(aidi.GetInt("bulan"))] += turbine.Capacity
						totalTurbinePerMonth[tk.ToString(aidi.GetInt("bulan"))] += 1
					}
				}
			}

			for _, data := range datas {
				id := data["_id"].(tk.M)
				imonthid := id["dateinfo_monthid"].(int)
				monthid := strconv.Itoa(imonthid)
				year := monthid[0:4]
				month := monthid[4:6]
				day := "01"

				iMonth, _ := strconv.Atoi(string(month))
				iMonth = iMonth - 1

				dtStr := year + "-" + month + "-" + day
				dtId, _ := time.Parse("2006-01-02", dtStr)
				dtinfo := GetDateInfo(dtId)
				ioktime := data["totaloktime"]
				oktime := 0.0
				if ioktime != nil {
					oktime = (ioktime.(float64)) / 3600 // divide by 3600 secs, result in hours
				}
				noOfTurbine = totalTurbinePerMonth[monthid]
				plfDivider = capacityPerMonth[monthid]

				revenueTimes := 5.74

				duration := 0.0
				lostEnergy := 0.0

				ipower := data["totalpower"]
				power := 0.0
				if ipower != nil {
					power = ipower.(float64)
				}

				ienergy := data["energy"]
				energy := 0.0
				if ienergy != nil {
					energy = ienergy.(float64)
				}

				iminutes := data["totalminutes"]
				minutes := 0.0
				if iminutes != nil {
					minutes = float64(iminutes.(int)) / 60
				}

				imaxdate := data["maxdateid"]
				imindate := data["mindateid"]
				maxdate := time.Now()
				mindate := time.Now()
				if imaxdate != nil {
					maxdate = imaxdate.(time.Time)
				}

				if imindate != nil {
					mindate = imindate.(time.Time)
				}
				//log.Printf("#%v\n", (power / 6000000))

				pipe := []tk.M{tk.M{}.Set("$unwind", "$detail"),
					tk.M{}.Set("$match", tk.M{}.Set("detail.detaildateinfo.monthid", imonthid)), tk.M{}.Set("$group", tk.M{}.Set("_id", "$projectname").Set("duration", tk.M{}.Set("$sum", "$detail.duration")).Set("powerlost", tk.M{}.Set("$sum", "$detail.powerlost")))}
				// log.Printf("#%v\n", pipe)
				csr1, _ := ctx.NewQuery().
					Command("pipe", pipe).
					From(new(Alarm).TableName()).
					Cursor(nil)
				defer csr1.Close()

				alarms := []tk.M{}
				e = csr1.Fetch(&alarms, 0, false)

				// log.Printf("#%v\n", alarms)

				if len(alarms) > 0 {
					alarm := alarms[0]
					ipowerlost := alarm["powerlost"]
					if ipowerlost != nil {
						lostEnergy = ipowerlost.(float64)
					}
					iduration := alarm["duration"]
					if iduration != nil {
						duration = iduration.(float64)
					}
				}
				//log.Println("Lost:", lostEnergy)
				//log.Println("Duration:", duration)

				powerlastyear := 0.0
				// powerlost := data["totalpowerlost"].(float64)
				// griddowntime := data["totalgriddowntime"].(float64)
				iwindspeed := data["avgwindspeed"]
				windspeed := 0.0
				if iwindspeed != nil {
					windspeed = iwindspeed.(float64)
				}

				itotaldata := data["totaltimestamp"]
				totaldata := 0
				if itotaldata != nil {
					totaldata = itotaldata.(int)
				}

				igriddowntime := data["totalgriddowntime"]
				griddowntime := 0.0
				if igriddowntime != nil {
					griddowntime = igriddowntime.(float64) / 3600
				}

				imachinedowntime := data["totalmachinedowntime"]
				machinedowntime := 0.0
				if imachinedowntime != nil {
					machinedowntime = imachinedowntime.(float64) / 3600
				}

				iunknowntime := data["totalunknowntime"]
				unknowntime := 0.0
				if iunknowntime != nil {
					unknowntime = iunknowntime.(float64) / 3600
				}
				_ = machinedowntime
				_ = griddowntime
				_ = unknowntime

				expwstimes := 0.133
				randno := tk.RandInt(5)
				//log.Printf("#%v\n", randno)
				if randno > 3 {
					expwstimes = -0.125
				}

				expWindSpeed := (windspeed + (windspeed * expwstimes))
				revenue := power * revenueTimes
				revenueInLacs := revenue / 100000

				tStart, _ := time.Parse("020601_150405", "01"+maxdate.UTC().Format("0601")+"_000000")
				daysInYear := GetDayInYear(tStart.Year())
				days := daysInYear.GetInt(tk.ToString(int(tStart.Month())))

				tEnd, _ := time.Parse("020601_150405", tk.ToString(days)+maxdate.UTC().Format("0601")+"_235959")

				hourValue := helper.GetHourValue(tStart.UTC(), tEnd.UTC(), mindate.UTC(), maxdate.UTC())

				machineAvail, gridAvail, scadaAvail, trueAvail, plf := helper.GetAvailAndPLF(noOfTurbine, oktime*3600, energy/1000, machinedowntime, griddowntime, float64(totaldata), hourValue, minutes, plfDivider)

				if plf > 100 {
					plf = 100
				}
				if gridAvail > 100 {
					gridAvail = 100
				}
				if scadaAvail > 100 {
					scadaAvail = 100
				}
				if machineAvail > 100 {
					machineAvail = 100
				}

				budget := budgetMonths[iMonth]

				mdl := new(ScadaSummaryByMonth).New()
				mdl.ProjectName = project
				mdl.DateInfo = dtinfo
				mdl.Production = ((power / 6) / divider)
				mdl.ProductionLastYear = (powerlastyear / divider)
				mdl.Revenue = revenue
				mdl.RevenueInLacs = revenueInLacs
				mdl.TrueAvail = trueAvail
				mdl.ScadaAvail = scadaAvail
				mdl.MachineAvail = machineAvail
				mdl.GridAvail = gridAvail
				mdl.PLF = plf
				mdl.Budget = budget * 1000
				mdl.AvgWindSpeed = windspeed
				mdl.ExpWindSpeed = expWindSpeed
				mdl.DowntimeHours = duration
				mdl.LostEnergy = lostEnergy / (divider * divider) // convert to giga
				mdl.RevenueLoss = (lostEnergy * revenueTimes)

				if mdl != nil {
					d.BaseController.Ctx.Insert(mdl)
				}

			}

		}

	}
}

func (d *GenScadaSummary) GenerateSummaryByProject(base *BaseController) {
	if base != nil {

		d.BaseController = base

		ctx, e := PrepareConnection()
		if e != nil {
			ErrorHandler(e, "Scada Summary")
			os.Exit(0)
		}

		d.BaseController.Ctx.DeleteMany(new(ScadaSummaryByProject), dbox.Ne("_id", ""))

		projectList := []ProjectOut{}
		projectList = append(projectList, ProjectOut{
			Name:   "",
			Value:  "Fleet",
			Coords: []float64{},
		})

		projects, _ := helper.GetProjectList()
		projectList = append(projectList, projects...)

		for _, v := range projectList {
			var turbineList []TurbineOut
			projectName := v.Value
			group := "projectname"

			filter := []*dbox.Filter{}
			filter = append(filter, dbox.Gte("power", -200))

			if projectName != "Fleet" {
				filter = append(filter, dbox.Eq("projectname", projectName))
				group = "turbine"
				turbineList, _ = helper.GetTurbineList([]interface{}{projectName})
			}

			csr, e := ctx.NewQuery().From(new(ScadaData).TableName()).
				Where(dbox.And(filter...)).
				Aggr(dbox.AggrSum, "$power", "totalpower").
				Aggr(dbox.AggrSum, "$energy", "energy").
				Aggr(dbox.AggrSum, "$energylost", "totalenergylost").
				Aggr(dbox.AggrSum, "$oktime", "totaloktime").
				Aggr(dbox.AggrSum, "$minutes", "totalminutes").
				Aggr(dbox.AggrSum, "$griddowntime", "totalgriddowntime").
				Aggr(dbox.AggrSum, "$unknowntime", "totalunknowntime").
				Aggr(dbox.AggrSum, "$machinedowntime", "totalmachinedowntime").
				Aggr(dbox.AggrAvr, "$avgwindspeed", "avgwindspeed").
				Aggr(dbox.AggrMax, "$dateinfo.dateid", "max").
				Aggr(dbox.AggrMin, "$dateinfo.dateid", "min").
				Group(group).
				Cursor(nil)
			defer csr.Close()

			_ = e

			datas := []tk.M{}
			e = csr.Fetch(&datas, 0, false)

			_, max, _ := GetDataDateAvailable(new(ScadaData).TableName(), "dateinfo.dateid", nil, d.Ctx.Connection)

			// daysInMonth := GetDayInYear(max.Year())
			// days := tk.ToString(daysInMonth.GetInt(tk.ToString(int(max.Month()))))
			// tmpdt, _ := time.Parse("060102_150405", max.UTC().Format("0601")+days+"_000000")
			tmpdt := max.UTC()
			endDate := tmpdt.UTC() //time.Parse("060102_150405", max.UTC().Format("0601")+"01_000000").UTC()
			startDate := GetNormalAddDateMonth(tmpdt.UTC(), -11)

			mdl := new(ScadaSummaryByProject).New()
			mdl.ID = projectName

			items := make([]ScadaSummaryByProjectItem, 0)
			for _, data := range datas {
				id := data["_id"].(tk.M)
				turbine := id[group].(string)
				idfield := "turbine"
				totalWtg := 0

				if projectName == "Fleet" {
					turbineList, _ = helper.GetTurbineList([]interface{}{turbine})
					idfield = "farm"
				}

				match := tk.M{}.
					Set(idfield, tk.M{}.Set("$eq", turbine)).
					Set("detail.detaildateinfo.dateid", tk.M{}.Set("$gte", startDate).Set("$lte", endDate))

				ioktime := data["totaloktime"]
				oktime := 0.0
				if ioktime != nil {
					oktime = (ioktime.(float64)) /// 3600 // divide by 3600 secs, result in hours
				}

				iminutes := data["totalminutes"]
				minutes := 0.0
				if iminutes != nil {
					valminutes, ok := iminutes.(float64) // divide by 60 secs, result in hours
					if !ok {
						ivalminutes := iminutes.(int)
						minutes = float64(ivalminutes) / 60.0
					} else {
						minutes = valminutes / 60.0
					}
				}
				_ = minutes

				downtimeHours := 0.0
				lostEnergy := 0.0

				// ilostEnergy := data["totalenergylost"]
				// if ilostEnergy != nil {
				// 	lostEnergy = ilostEnergy.(float64)
				// }

				pipe := []tk.M{
					tk.M{}.Set("$unwind", "$detail"),
					tk.M{}.Set("$match", match),
					tk.M{}.Set("$group", tk.M{}.Set("_id", "$"+idfield).
						Set("duration", tk.M{}.Set("$sum", "$detail.duration")).
						Set("powerlost", tk.M{}.Set("$sum", "$detail.powerlost"))),
					tk.M{}.Set("$sort", tk.M{}.Set("_id", 1)),
				}
				// log.Printf("#%v\n", pipe)
				csr1, _ := ctx.NewQuery().
					Command("pipe", pipe).
					From(new(Alarm).TableName()).
					Cursor(nil)
				defer csr1.Close()

				alarms := []tk.M{}
				e = csr1.Fetch(&alarms, 0, false)

				// log.Printf("#%v\n", alarms)

				if len(alarms) > 0 {
					alarm := alarms[0]
					ipowerlost := alarm["powerlost"]
					if ipowerlost != nil {
						lostEnergy = ipowerlost.(float64)
					}
					iduration := alarm["duration"]
					if iduration != nil {
						downtimeHours = iduration.(float64)
					}
				}

				ipower := data["totalpower"]
				power := 0.0
				if ipower != nil {
					power = ipower.(float64)
				}

				imachinedowntime := data["totalmachinedowntime"]
				machinedowntime := 0.0
				if imachinedowntime != nil {
					machinedowntime = imachinedowntime.(float64) / 3600
				}

				igriddowntime := data["totalgriddowntime"]
				griddowntime := 0.0
				if igriddowntime != nil {
					griddowntime = igriddowntime.(float64) / 3600
				}

				iunknowntime := data["totalunknowntime"]
				unknowntime := 0.0
				if iunknowntime != nil {
					unknowntime = iunknowntime.(float64) / 3600
				}

				_ = machinedowntime
				_ = griddowntime
				_ = unknowntime

				//downtimeHours = machinedowntime + griddowntime + unknowntime

				// machineAvail := (minutes - machinedowntime) / (durationInMonth * 24)

				maxDate := data.Get("max", time.Time{}).(time.Time)
				minDate := data.Get("min", time.Time{}).(time.Time)
				energy := data.GetFloat64("energy") / 1000

				hourValue := helper.GetHourValue(startDate.UTC(), endDate.UTC(), minDate.UTC(), maxDate.UTC())

				// log.Printf("%v | %v | %v \n", hourValue, minDate.String(), maxDate.String())
				var plfDivider float64
				for _, v := range turbineList {
					if projectName != "Fleet" {
						if v.Value == turbine {
							plfDivider += v.Capacity
							totalWtg += 1
						}
					} else {
						if v.Project == turbine {
{'fraction_non_alphanumeric': 0.169821222404926, 'fraction_numerical': 0.034006227477871465, 'mean_word_length': 3.0011198208286674, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4155685', 'n_tokens_mistral': 13887, 'n_tokens_neox': 10456, 'n_words': 1888}