double getSolarpanelPowerWatt(IMySolarPanel SolarPanel) { debug("Detail (" + SolarPanel.CustomName + ") > " + SolarPanel.DetailedInfo); DetailedInfo DI = new DetailedInfo(SolarPanel); return(parsePower(DI.getValue(1).getValue())); }
private void ParseFromDetailedInfo(IMySolarPanel panel) { string [] lines = panel.DetailedInfo.Split(new char [] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); string [] [] dictionary = new string [lines.Length] []; string maxoutput = ""; string currentoutput = ""; for (int i = 0; i < lines.Length; i++) { dictionary [i] = lines [i].Split(new string [] { ": " }, StringSplitOptions.None); switch (dictionary [i] [0]) { case "Max Output": maxoutput = dictionary [i] [1]; break; case "Current Output": currentoutput = dictionary [i] [1]; break; } } MaxWatts = GetWattValue(maxoutput); Watts = GetWattValue(currentoutput); }
private void UpdatePower(IMySolarPanel solarPanel, RealisticSolarPanelData data = null) { if (solarPanel == null) { return; } if (data == null) { if (solarPanelData.ContainsKey(solarPanel.EntityId) == false) { return; } data = solarPanelData[solarPanel.EntityId]; } float airDensity = data.CurrentAirDensity != null ? data.CurrentAirDensity.Value : 1f; float modifier = 1f - (densityMultiplier * airDensity); if (modifier < 0f) { modifier = 0f; } float currentOutput = data.OriginalMaxOutput * modifier; //only set it if our calculated max output changed if (currentOutput != data.CurrentMaxOutput) { data.CurrentMaxOutput = currentOutput; solarPanel.SourceComp.SetMaxOutput(data.CurrentMaxOutput); } }
const float SOLARPANEL_MAXPOWER_SMALLGRID = 30000f / 25; // Small-grid solar-panel consist of 10x5 small-blocks, producing max 30kW total float getSolarPanelMaximumPower(IMySolarPanel sol) { Vector3I s = new Vector3I(1, 1, 1); s += sol.Max; s -= sol.Min; // Counting number of 'cubes' a solarpanel consist of, we use to determine its maximum power potential return(s.Size * (sol.CubeGrid.GridSizeEnum == 0 ? SOLARPANEL_MAXPOWER_LARGEGRID : SOLARPANEL_MAXPOWER_SMALLGRID)); }
public SolarPanel(string oBlockName) { m_oBlock = gts.GetBlockWithName(oBlockName) as IMySolarPanel; if (m_oBlock == null) { throw new Exception(oBlockName + " block not found, check name"); } Init(m_oBlock); }
public Program() { //Ищем блоки. rotorAz = GridTerminalSystem.GetBlockWithName("[SSB-s] RotorAzimuth") as IMyMotorStator; solar = GridTerminalSystem.GetBlockWithName("[SSB-s] Solar panel 1") as IMySolarPanel; text = Me.GetSurface(0); textPanel = GridTerminalSystem.GetBlockWithName("[SSB-s] LCD-Solar") as IMyTextPanel; Runtime.UpdateFrequency = UpdateFrequency.Update1; }
public SolarTracker( IMySolarPanel solarPanel_, IMyMotorStator rotorInclination_, IMyMotorStator rotorAzimuth_, IMyTextPanel textPanel_ = null ) { solarPanel = solarPanel_; rotorAzimuth = new TrackerRotor(rotorAzimuth_); rotorInclination = new TrackerRotor(rotorInclination_); textPanel = textPanel_; previousPowerOutput = solarPanel.MaxOutput; Initialize(); }
public bool addSolar(IMySolarPanel _SPanel) { if (!solars.Contains(_SPanel)) { solars.Add(_SPanel); MaxOutput += (_SPanel.MaxOutput * MEGAWATT); CurrentOutput += (_SPanel.CurrentOutput * MEGAWATT); return(true); } else { return(false); } }
public void Main(string argument, UpdateType updateSource) { if (_solarPanel == null) { _solarPanel = (IMySolarPanel)GridTerminalSystem.GetBlockWithName("太阳能板-基准"); } if (_motorRotorBottom == null) { _motorRotorBottom = (IMyMotorBase)GridTerminalSystem.GetBlockWithName("太阳能转子"); } if (_solarPanel.MaxOutput < upSolarPanelPanelMaxOutput) { _motorRotorBottom.ApplyAction("Reverse"); } upSolarPanelPanelMaxOutput = _solarPanel.MaxOutput; }
void calcCurrentSolar() { if (solarList.Count > 0) { maxSolarPower = 0; } currentSolarOutput = 0; // Echo("Solars:"); foreach (var tb in solarList) { IMySolarPanel r = tb as IMySolarPanel; // Echo(r.CustomName + " Max=" + r.MaxOutput.ToString("0.000") + " c=" + r.CurrentOutput.ToString("0.000")); maxSolarPower += r.MaxOutput; currentSolarOutput += r.CurrentOutput; } }
public void Main(string argument, UpdateType updateSource) { IMyMotorStator rotor = GridTerminalSystem.GetBlockWithName("Solar Panel Rotor") as IMyMotorStator; IMySolarPanel solarPanel = GridTerminalSystem.GetBlockWithName("Solar Panel Reference") as IMySolarPanel; if (solarPanel.MaxOutput < _lastOutput) { rotor.TargetVelocityRPM *= -1.0f; } _PanelTextSurface.WriteText(String.Format( "Last: {0}\nOutput: {1}\nRotor: {2}", _lastOutput, solarPanel.MaxOutput, rotor.TargetVelocityRPM )); _lastOutput = solarPanel.MaxOutput; }
public static float?GetSolarPanelMaxOutput(IMySolarPanel panel) { var lines = panel.DetailedInfo.Split(new char[] { '\n' }); if (lines.Length == 3) { // Second line var parts = lines[1].Split(new char[] { ':' }); if (parts.Length == 2) { // Right half var maxOutputText = parts[1].Trim(); var match = System.Text.RegularExpressions.Regex.Match(maxOutputText, "([0-9]+(\\.[0-9]+)?) *([kM]?W)"); if (match.Success) { var power = float.Parse(match.Groups[1].Value); var units = match.Groups[3].Value; switch (units) { case "W": power /= 1000000.0f; break; case "kW": power /= 1000.0f; break; case "MW": break; default: throw new Exception("Unknown power units: " + units); } return(power); } else { throw new Exception("Regex match fail: " + maxOutputText); } } } return(null); }
public static float? GetSolarPanelMaxOutput(IMySolarPanel panel) { var lines = panel.DetailedInfo.Split(new char[] { '\n' }); if (lines.Length == 3) { // Second line var parts = lines[1].Split(new char[] { ':' }); if (parts.Length == 2) { // Right half var maxOutputText = parts[1].Trim(); var match = System.Text.RegularExpressions.Regex.Match(maxOutputText, "([0-9]+(\\.[0-9]+)?) *([kM]?W)"); if (match.Success) { var power = float.Parse(match.Groups[1].Value); var units = match.Groups[3].Value; switch (units) { case "W": power /= 1000000.0f; break; case "kW": power /= 1000.0f; break; case "MW": break; default: throw new Exception("Unknown power units: " + units); } return power; } else throw new Exception("Regex match fail: " + maxOutputText); } } return null; }
void Main(string arg) { Echo(DateTime.Now.ToString("HH\\:mm\\:ss\\.fff")); //profileStart(); _log.Clear(); _debug.Clear(); // batMax = batCur = batIn = batOut = otherBatIn = otherBatOut = 0; slrMax = slrCur = slrOut = slrPitchMax = slrPitchCur = 0; uint slrPnls = 0; uint slrPitchPnls = 0; float tmpMax = 0; float tmpCur = 0; float tmpOut = 0; int tagIdx; // Action <IMySolarPanel, bool> sumSolar = (IMySolarPanel slrPnl, bool useTagged) => { slrPnls += 1; slrMax += (tmpMax = getSolarPanelMaximumPower(slrPnl)); slrCur += (tmpCur = Watt(slrPnl.MaxOutput)); slrOut += (tmpOut = Watt(slrPnl.CurrentOutput)); if (useTagged) { slrPitchPnls += 1; slrPitchMax += tmpMax; slrPitchCur += tmpCur; } }; Action <IMyBatteryBlock> sumBattery = (IMyBatteryBlock btyBlk) => { batIn += Watt(btyBlk.CurrentInput); batOut += Watt(btyBlk.CurrentOutput); batCur += Watt(btyBlk.CurrentStoredPower); batMax += Watt(btyBlk.MaxStoredPower); }; //profileStep("a2"); IMyMotorStator rtr; IMyBatteryBlock bb; IMySolarPanel pnl; IMyTextPanel tp; // Loop through the grid's block-list "only once" per program-run. GridTerminalSystem.GetBlocksOfType <IMyTerminalBlock>(blockList, blk => { if (blk.IsFunctional) { if (null != (pnl = blk as IMySolarPanel)) { tagIdx = blk.CustomName.IndexOf(TAG_PREFIX); if (tagIdx > -1 && NameContains(blk, TAG_SOLARPANEL_IGNORE)) { // Ignore it } else if (tagIdx > -1 && NameContains(blk, TAG_SOLARPANEL_YAW)) { solarYaws.Add(pnl); } else { sumSolar(pnl, (tagIdx > -1 && NameContains(blk, TAG_SOLARPANEL_PITCH))); } } else if (null != (bb = blk as IMyBatteryBlock)) { if (SameGrid(Me, blk)) { sumBattery(bb); batteries.Add(bb); } else { otherBatIn += Watt(bb.CurrentInput); otherBatOut += Watt(bb.CurrentOutput); } } else if (null != (rtr = blk as IMyMotorStator)) { if (blk.CustomName.IndexOf(TAG_PREFIX) > -1) { if (NameContains(blk, TAG_ROTOR_YAW)) { rotorYaw.Add(rtr); } else if (NameContains(blk, TAG_ROTOR_PITCH_LEFT)) { rotorPitchL.Add(rtr); } else if (NameContains(blk, TAG_ROTOR_PITCH_RIGHT)) { rotorPitchR.Add(rtr); } } } else if (null != (tp = blk as IMyTextPanel)) { if (NameContains(blk, TAG_LCDPANEL_INFO)) { lcdPanel.Add(tp); } else if (NameContains(blk, TAG_LCDPANEL_IMAGE)) { lcdImage.Add(tp); } } } return(false); // Do not add any blocks to `blockList`, as we do not use it anyway. }); //profileStep("a3"); // Simple sanity check bool allOk = true; if (solarYaws.Count != 1) { allOk = false; Echo("ERROR: No exact '" + TAG_SOLARPANEL_YAW + "' solar-panel found!"); } else { solarYaw = solarYaws[0]; } solarYaws.Clear(); if (rotorYaw.Count <= 0) { allOk = false; Echo("ERROR: No '" + TAG_ROTOR_YAW + "' rotor found!"); } if (!allOk) { return; } if (rotorPitchL.Count <= 0 && rotorPitchR.Count <= 0) { //allOk = false; Echo("WARNING: No '" + TAG_ROTOR_PITCH_LEFT + "' nor '" + TAG_ROTOR_PITCH_RIGHT + "' rotors found!"); } memory.load(this); if (arg == "reset") { Storage = ""; SetYawSpeed(0); UpdatePitchAngle(0); powerHistory.clear(); return; } // If no explicit named 'PITCH' solar-panels, then use all that was detected if (slrPitchPnls <= 0) { slrPitchMax = slrMax; slrPitchCur = slrCur; } //profileStep("a4"); bool hasDayLight = false; if (slrPitchMax > 0f) { hasDayLight = (slrPitchCur / slrPitchMax > 0.8f); } if (hasDayLight != memory.getBool("hasDayLight", !hasDayLight)) { const string ON = "OnOff_On"; const string OFF = "OnOff_Off"; GridTerminalSystem.GetBlocksOfType <IMyTerminalBlock>(blockList, blk => { if (NameContains(blk, TAG_DAYLIGHT_ENABLE)) { blk.ApplyAction(hasDayLight ? ON : OFF); } else if (NameContains(blk, TAG_DAYLIGHT_DISABLE)) { blk.ApplyAction(!hasDayLight ? ON : OFF); } return(false); }); List <IMyBlockGroup> blkGrps = new List <IMyBlockGroup>(); List <IMyTerminalBlock> blks = new List <IMyTerminalBlock>(); GridTerminalSystem.GetBlockGroups(blkGrps, x => x.Name.Contains(TAG_DAYLIGHT_ENABLE)); blkGrps.ForEach(g => { g.GetBlocks(blks); blks.ForEach(blk => blk.ApplyAction(hasDayLight ? ON : OFF)); }); GridTerminalSystem.GetBlockGroups(blkGrps, x => x.Name.Contains(TAG_DAYLIGHT_DISABLE)); blkGrps.ForEach(g => { g.GetBlocks(blks); blks.ForEach(blk => blk.ApplyAction(!hasDayLight ? ON : OFF)); }); memory.setBool("hasDayLight", hasDayLight); } // float slrYawMax = getSolarPanelMaximumPower(solarYaw); float slrYawCur = solarYaw.MaxOutput * 1000000f; float factor = (slrYawMax > 0 ? slrYawCur / slrYawMax : 0f); // avoid division-by-zero float yawAlignPct = (1f - factor); float multiply = 1 + MyMath.FastSin(factor); float yawSpeed = Math.Min(factor * multiply, 1.0f) * (YAW_ROTATE_ANTICLOCKWISE ? -1f : 1f); Debug("YawFactor=" + factor); Debug("YawSpeed=" + yawSpeed); if (Math.Abs(yawSpeed) < 0.01f) { yawSpeed = 0; } SetYawSpeed(yawSpeed); //profileStep("a5"); // float pitchAlignPct = (slrPitchMax > 0 ? (slrPitchCur / slrPitchMax) : 1f); // avoid division-by-zero float pitchWantedAngle = memory.getFloat("pitchWantedAngle", 0f); // If yaw alignment less than 80% optimal, then reset pitch. if (yawAlignPct < 0.8f) { pitchWantedAngle = 0f; pitchState = 0; } //profileStep("a5b"); float pitchAnglePrecision = UpdatePitchAngle(MathHelper.ToRadians(pitchWantedAngle), true); //profileStep("a6"); if (pitchAnglePrecision > 0.99f) { float pitchPrevAngle = pitchWantedAngle; if (pitchAlignPct < 0.01f) { pitchState = 0; pitchWantedAngle = 0f; powerHistory.clear(); } else if (yawAlignPct > 0.85f) { /* * float newAngle = Math.Max(1f, 5f * (1f - pitchAlignPct)); * switch (pitchState++) { * case 0: // Initiate "search" * pitchSearchAngles.Enqueue(Math.Max(-90f, pitchWantedAngle - newAngle)); * pitchSearchAngles.Enqueue(Math.Min( 90f, pitchWantedAngle + newAngle)); * pitchWantedAngle = pitchSearchAngles.Dequeue(); * break; * case 1: * pitchWantedAngle = pitchSearchAngles.Dequeue(); * break; * case 2: * pitchWantedAngle = powerHistory.getBestAngle(); * pitchState = 0; * break; * } */ switch (pitchState++) { case 0: // Initiate "search" pitchWantedAngle = powerHistory.getBestAngle(); pitchSearchAngles.Enqueue(Math.Max(-90f, pitchWantedAngle - 2f)); pitchSearchAngles.Enqueue(Math.Min(90f, pitchWantedAngle + 2f)); break; case 1: pitchWantedAngle = pitchSearchAngles.Dequeue(); break; case 2: pitchWantedAngle = pitchSearchAngles.Dequeue(); break; case 3: pitchWantedAngle = powerHistory.getBestAngle(); pitchSearchAngles.Enqueue(Math.Max(-90f, pitchWantedAngle - 1f)); pitchSearchAngles.Enqueue(Math.Min(90f, pitchWantedAngle + 1f)); pitchState = 1; break; } } powerHistory.append(pitchPrevAngle, slrPitchCur); memory.setInt("pitchState", pitchState); } UpdatePitchAngle(MathHelper.ToRadians(pitchWantedAngle)); memory.setFloat("pitchWantedAngle", pitchWantedAngle); Debug("pitchState=" + pitchState); // Batteries discharge/recharge management if (true) { bool allRecharging = true; bool allDischarging = true; batteries.ForEach(b => { if (b.Enabled) { allRecharging &= b.OnlyRecharge; allDischarging &= b.OnlyDischarge; } }); bool change = false; bool doRecharge = false; bool doDischarge = false; if (allDischarging && slrCur > batOut) { change = doRecharge = true; //} else if (allRecharging && ((slrCur - batIn)/slrCur > 0.5f)) { } else if (allRecharging && batIn < slrCur * 0.1f) { change = doDischarge = true; } if (change) { batteries.ForEach(b => { if (b.Enabled) { if (doRecharge != b.OnlyRecharge) { b.ApplyAction("Recharge"); } if (doDischarge != b.OnlyDischarge) { b.ApplyAction("Discharge"); } } }); } } // //profileStep("a7"); memory.save(this); // //profileStep("a8"); Log("Batteries: " + powerAsString(batCur, 3) + "h of " + powerAsString(batMax, 3) + "h"); Log(" Grid In/Out: +" + powerAsString(batIn, 3) + " / -" + powerAsString(batOut, 3)); Log(" Other In/Out: +" + powerAsString(otherBatIn, 3) + " / -" + powerAsString(otherBatOut, 3)); Log("SolarPower: " + powerAsString(slrOut, 3) + " of " + powerAsString(slrCur, 3)); Log(" Yaw-rotation is: " + (YAW_ROTATE_ANTICLOCKWISE ? "Anti-clockwise" : "Clockwise")); Log(" Alignment yaw : " + (yawAlignPct * 100f).ToString("N1") + "% (" + powerAsString(slrYawCur) + ")"); Log(" Alignment pitch: " + (pitchAlignPct * 100f).ToString("N1") + "% (" + powerAsString(slrPitchCur) + ")"); if (slrPitchPnls > 0) { Log(" Using " + slrPitchPnls + " tagged panel" + (slrPitchPnls != 1 ? "s" : "") + " for pitch alignment"); } Log(" SolarPanels optimum max: " + powerAsString(slrMax, 3)); lcdImage.ForEach(p => { p.ClearImagesFromSelection(); int pct = (int)(pitchAlignPct * 100); pct = pct - (pct % 5); p.AddImageToSelection(string.Format("Incline {0}", pct.ToString("D3"))); }); lcdImage.Clear(); // if (debugOn) { Log("\n<<-- DebugInfo -->>"); Log(_debug.ToString(), false); _debug.Clear(); } string txt = _log.ToString(); _log.Clear(); //-- Echo is now nerfed, as it causes huge FPS-drops apparently. //Echo(txt); //profileStep("a9"); // Clean up solarYaw = null; rotorYaw.Clear(); rotorPitchL.Clear(); rotorPitchR.Clear(); batteries.Clear(); //profileStep("a0"); //txt = profileEnd(); lcdPanel.ForEach(p => p.WritePublicText(txt)); lcdPanel.Clear(); }
public SolarPanel(IMyTerminalBlock oBlock) : base(oBlock) { m_oBlock = (IMySolarPanel)oBlock; }
public SolarPanel(IMySolarPanel oBlock) : base(oBlock) { m_oBlock = oBlock; }
void UpdateName(IMySolarPanel solarPanel, out float oldPower) { float __ignore; UpdateName(solarPanel, out oldPower, out __ignore); }
// currently unused bool CurrentOutput(IMySolarPanel solarPanel, out float power) { power = 0.0f; if (solarPanel == null) throw new Exception(" CurrentOutput(IMySolarPanel, float): solarPanel is null"); int start = StartIndexCurrentOutput(solarPanel); int end = solarPanel.DetailedInfo.Length; string currentOutput = solarPanel.DetailedInfo.Substring(start, end - start); bool success = float.TryParse(System.Text.RegularExpressions.Regex.Replace(currentOutput, @"[^0-9.]", ""), out power); // power should be in kW if (success) { if (currentOutput.Contains(" W")) { // W -> kW: * 0.001 power *= 0.001f; } else if (currentOutput.Contains(" kW")) { // kW -> kW: * 1 power *= 1.0f; } else if (currentOutput.Contains(" MW")) { // MW -> kW: * 1,000 power *= 1000.0f; } else if (currentOutput.Contains(" GW")) { // GW -> kW: * 1,000,000 power *= 1000000.0f; } else throw new Exception(" CurrentOutput(IMySolarPanel, float): current power output is too high (" + currentOutput + ")"); } return success; }
public SolarController() { // Get all solar panels List <IMyTerminalBlock> panels = new List <IMyTerminalBlock>(); GridTerminalSystem.GetBlocksOfType <IMySolarPanel>(panels); // Get current and total power output int panelCnt = 0; float curUse = 0f; // Amount of power currently being used float genOut = 0f; // Power output potential float lowestOut = 0f; for (int i = 0; i < panels.Count; i++) { IMySolarPanel panel = panels[i] as IMySolarPanel; if (panel != null && panel.IsFunctional) { panelCnt++; float cur = panel.CurrentOutput; float max = panel.MaxOutput; curUse += cur; genOut += max; if (lowestOut == 0f || max < lowestOut) { lowestOut = max; } } } // Display status pr(String.Format("Solar Panel Count: {0}", panelCnt)); pr(String.Format("Solar Power Usage: {0:0.0}/{1:0.0} MW", curUse, genOut)); // Nothing else to do if no panels if (panelCnt == 0) { return; } // Rotor control IMyMotorStator rotor = (IMyMotorStator)GridTerminalSystem.GetBlockWithName("Solar Panel Rotor"); float thresh = target * maxOut; if (lowestOut < thresh) { float speed = ((thresh - lowestOut) / thresh) * 1.5f; if (speed < 0.05f) { speed = 0.05f; } rotor.SetValue("Velocity", speed); rotor.ApplyAction("OnOff_On"); pr(String.Format("Rotor Status: On ({0:0.00} rpm)", speed)); } else { rotor.ApplyAction("OnOff_Off"); pr("Rotor Status: Off"); } }
public PowerInfo(IMySolarPanel panel) : this(0, 0) { ParseFromDetailedInfo(panel); }
private void MyEntities_OnEntity(MyEntity entity, bool create) { if (entity == null) { return; } if (entity is IMySolarPanel) { IMySolarPanel solarPanel = entity as IMySolarPanel; if (solarPanel == null || solarPanel.SourceComp == null) { return; } if (create == true) { //shouldn't happen, should always be new? if (solarPanelData.ContainsKey(solarPanel.EntityId) == false) { solarPanelData.Add(solarPanel.EntityId, new RealisticSolarPanelData() { EntityId = solarPanel.EntityId, GridEntityId = solarPanel.CubeGrid.EntityId, CurrentAirDensity = null, OriginalMaxOutput = 0f, CurrentMaxOutput = 0f, IsStatic = solarPanel.CubeGrid.IsStatic }); } solarPanel.SourceComp.MaxOutputChanged += SolarPanel_MaxOutputChanged; solarPanel.CubeGrid.OnIsStaticChanged += SolarPanelGrid_OnIsStaticChanged; } else { //shouldn't happen, should always exist if (solarPanelData.ContainsKey(solarPanel.EntityId) == true) { solarPanelData.Remove(solarPanel.EntityId); } solarPanel.SourceComp.MaxOutputChanged -= SolarPanel_MaxOutputChanged; solarPanel.CubeGrid.OnIsStaticChanged -= SolarPanelGrid_OnIsStaticChanged; } if (entity is IMyTerminalBlock) { IMyTerminalBlock solarPanelTerminal = entity as IMyTerminalBlock; if (solarPanelTerminal == null) { return; } if (create == true) { solarPanelTerminal.AppendingCustomInfo += SolarPanelTerminal_AppendingCustomInfo; } else { solarPanelTerminal.AppendingCustomInfo -= SolarPanelTerminal_AppendingCustomInfo; } } } }
public static bool MaxOutput(IMySolarPanel panel, out float power) { power = 0.0f; int start = panel.DetailedInfo.IndexOf(Configuration.Localization.MaxOutput); int end = panel.DetailedInfo.IndexOf(Configuration.Localization.CurrentOutput); if (start < 0 || end < 0 || end < start) return false; start += Configuration.Localization.MaxOutput.Length; string maxOutput = panel.DetailedInfo.Substring(start, end - start); if (float.TryParse(System.Text.RegularExpressions.Regex.Replace(maxOutput, @"[^0-9.]", ""), out power)) { float factor = 0.0f; if (maxOutput.Contains(" W")) factor = 0.001f; else if (maxOutput.Contains(" kW")) factor = 1.0f; else if (maxOutput.Contains(" MW")) factor = 1000.0f; else if (maxOutput.Contains(" GW")) factor = 1000000.0f; else { power = float.NaN; return true; } power *= factor; return true; } return false; }
int StartIndexMaxOutput(IMySolarPanel solarPanel) { if (solarPanel == null) throw new Exception(" StartIndexMaxOutput(IMySolarPanel): solarPanel is null"); int ret = solarPanel.DetailedInfo.IndexOf(lang_maxOutput); if (ret < 0) throw new Exception(" StartIndexMaxOutput(IMySolarPanel): incompatible solar panel"); return ret + lang_maxOutput.Length; }
void UpdateName(IMySolarPanel solarPanel) { float __ignore; UpdateName(solarPanel, out __ignore); }
double getSolarpanelPowerWatt(IMySolarPanel SolarPanel) { DetailedInfo DI = new DetailedInfo(SolarPanel); return(parsePower(DI.getValue(1).getValue())); }
static bool CurrentOutput(IMySolarPanel solarPanel, out float power) { if (solarPanel == null) throw new Exception(" CurrentOutput(IMySolarPanel, out float): solarPanel is null"); int start = StartIndexCurrentOutput(solarPanel); int end = solarPanel.DetailedInfo.Length; string currentOutput = solarPanel.DetailedInfo.Substring(start, end - start); if (float.TryParse(System.Text.RegularExpressions.Regex.Replace(currentOutput, @"[^0-9.]", ""), out power)) { // convert to kW if (currentOutput.Contains(" W")) { // W -> kW: * 0.001 power *= 0.001f; } else if (currentOutput.Contains(" kW")) { // kW -> kW: * 1 power *= 1f; } else if (currentOutput.Contains(" MW")) { // MW -> kW: * 1000 power *= 1000f; } else if (currentOutput.Contains(" GW")) { // GW -> kW: * 1000000 power *= 1000000f; } else throw new Exception(" CurrentOutput(IMySolarPanel, out float): current power output is too high (" + currentOutput + ")"); return true; } return false; }
void Main() { // get a list of all blocks in the grid terminal system List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>(); GridTerminalSystem.GetBlocks(blocks); // initialize the reference solar panel if it hasn't been initialized yet if (referencePanel == null) { // search all available blocks for one containing the reference panel name for (int i = 0; i < blocks.Count; i++) { if (blocks[i].CustomName.Contains(referencePanelName)) { referencePanel = blocks[i] as IMySolarPanel; if (referencePanel != null) break; } } if (referencePanel == null) throw new Exception(" Main(): failed to find solar panel with name '" + referencePanelName + "'"); } // initialize the timer if it hasn't been initialized yet if (timer == null) { // search all available blocks for one containing the timer name for (int i = 0; i < blocks.Count; i++) { if (blocks[i].CustomName.Contains(timerName)) { timer = blocks[i] as IMyTimerBlock; if (timer != null) break; } } if (timer == null) throw new Exception(" Main(): failed to find timer block with name '" + timerName + "'"); } // initialize the rotors list if no rotors have been registered yet if (rotors.Count <= 0) { for (int i = 0; i < rotorNames.Length; i++) { IMyTerminalBlock rotor = GridTerminalSystem.GetBlockWithName(rotorNames[i]); // only add rotors that actually exist and haven't been added yet if (rotor != null && !rotors.Contains(rotor)) { rotors.Add(rotor); rotor.SetValue("Velocity", rotorSpeed); ToggleOff(rotor); } } if (rotors.Count <= 0) throw new Exception(" Main(): failed to find any rotors with the specified names"); } // rotate the current rotor float currentPower; if (!MaxOutput(referencePanel, out currentPower)) throw new Exception(" Main(): failed to read current power output from DetailedInfo"); if (currentPower >= targetPowerOutput) { for (int i = 0; i < rotors.Count; i++) { ToggleOff(rotors[i]); } UpdateName(referencePanel); TriggerTimerIdle(); return; } if (currentRotor == null) { currentRotor = rotors[currentIndex] as IMyMotorStator; updatedRotor = true; } if (currentRotor == null) throw new Exception(" Main(): block '" + rotors[currentIndex].CustomName + "' is not a rotor but was registered as rotor to use"); if (updatedRotor) { if (!testingDirection) { // set the best rotation direction UpdateName(referencePanel); ToggleOn(currentRotor); testingDirection = true; TriggerTimer(); return; } ToggleOff(currentRotor); float oldPowerWDIHTCT; UpdateName(referencePanel, out oldPowerWDIHTCT, out currentPower); if (oldPowerWDIHTCT > currentPower) Reverse(currentRotor); updatedRotor = false; testingDirection = false; } // get the optimal rotation if (!setting) { ToggleOn(currentRotor); setting = true; UpdateName(referencePanel); TriggerTimer(); return; } float oldPower; UpdateName(referencePanel, out oldPower, out currentPower); if (oldPower > currentPower) { ToggleOff(currentRotor); currentRotor = null; currentIndex = (currentIndex + 1) % rotors.Count; } setting = false; TriggerTimer(); }
static int StartIndexCurrentOutput(IMySolarPanel solarPanel) { if (solarPanel == null) throw new Exception(" StartIndexCurrentOutput(IMySolarPanel): solarPanel is null"); int ret = solarPanel.DetailedInfo.IndexOf(Configuration.Localization.CurrentOutput); if (ret < 0 || ret <= StartIndexMaxOutput(solarPanel)) throw new Exception(" StartIndexCurrentOutput(IMySolarPanel): incompatible solar panel"); return ret + Configuration.Localization.CurrentOutput.Length; }
void Main() { // initialize the reference solar panel if (ReferencePanel == null) { // get a list of all available solar panels List<IMyTerminalBlock> solarPanels = new List<IMyTerminalBlock>(); GridTerminalSystem.GetBlocksOfType<IMySolarPanel>(solarPanels); // search all available blocks for one containing the reference solar panel's name for (int i = 0; i < solarPanels.Count; i++) { IMySolarPanel solarPanel = solarPanels[i] as IMySolarPanel; if (solarPanel != null && solarPanel.CustomName.StartsWith(Configuration.ReferencePanelName)) { ReferencePanel = solarPanel; if (ReferencePanel != null) break; } } if (ReferencePanel == null) throw new Exception(" Main(): Failed to find solar panel with name \"" + Configuration.ReferencePanelName + "\""); } // initialize the timer if (Timer == null) { Timer = GridTerminalSystem.GetBlockWithName(Configuration.TimerName) as IMyTimerBlock; if (Timer == null) throw new Exception(" Main(): Failed to find timer block with name \"" + Configuration.TimerName + "\""); } // initialize rotors list if (Rotors.Count <= 0) { for (int i=0; i < Configuration.RotorNames.Length; i++) { IMyMotorStator rotor = GridTerminalSystem.GetBlockWithName(Configuration.RotorNames[i]) as IMyMotorStator; // only add rotors that exist and haven't been added yet if (rotor != null && !Rotors.Contains(rotor)) { Rotors.Add(rotor); rotor.SetValue("Velocity", Configuration.RotorSpeed); ToggleOff(rotor); } } if (Rotors.Count < Configuration.RotorNames.Length) throw new Exception(" Main(): Failed to find all rotors - found " + Rotors.Count + " rotors, " + Configuration.RotorNames.Length + " were specified"); } // rotate the current rotor float currentPower; if (!MaxOutput(ReferencePanel, out currentPower)) throw new Exception(" Main(): Failed to read maximum power output from the solar panel's information"); // check if the target power output has been reached if (currentPower >= Configuration.TargetPowerOutput) { for (int i=0; i < Rotors.Count; i++) { ToggleOff(Rotors[i]); } UpdateName(ReferencePanel); TriggerTimerIdle(); return; } // update the rotor and test which direction yields the higher power output if (CurrentRotor == null || CurrentStatus == Status.UPDATING) { CurrentRotor = Rotors[CurrentRotorIndex]; UpdateName(ReferencePanel); ToggleOn(CurrentRotor); CurrentStatus = Status.TESTING; TriggerTimer(); return; } // set the direction towards the higher power output if (CurrentStatus == Status.TESTING) { ToggleOff(CurrentRotor); float oldPower; UpdateName(ReferencePanel, out oldPower, out currentPower); if (oldPower > currentPower) Reverse(CurrentRotor); CurrentStatus = Status.ALIGNING; } // rotate towards maximum power output if (CurrentStatus == Status.ALIGNING) { ToggleOn(CurrentRotor); UpdateName(ReferencePanel); CurrentStatus = Status.CHECKING; TriggerTimer(); return; } if (CurrentStatus == Status.CHECKING) { float oldPower; UpdateName(ReferencePanel, out oldPower, out currentPower); if (oldPower > currentPower) { ToggleOff(CurrentRotor); CurrentStatus = Status.UPDATING; CurrentRotorIndex = (CurrentRotorIndex + 1) % Rotors.Count; } TriggerTimer(); return; } }
static void UpdateName(IMySolarPanel solarPanel) { float oldPower, currentPower; UpdateName(solarPanel, out oldPower, out currentPower); }
void UpdateName(IMySolarPanel solarPanel, out float oldPower, out float currentPower) { oldPower = 0.0f; if (!MaxOutput(solarPanel, out currentPower)) throw new Exception(" UpdateName(IMySolarPanel, float): failed to read current power output from DetailedInfo"); if (solarPanel == null) throw new Exception(" UpdateName(IMySolarPanel, float): solarPanel is null"); string[] array = solarPanel.CustomName.Split('~'); if (array.Length > 1) { // old power has been set float.TryParse(array[array.Length - 1], out oldPower); // update current power output string newName = ""; for (int i = 0; i < array.Length - 1; i++) { newName += array[i]; } newName += "~" + currentPower; solarPanel.SetCustomName(newName); } else { // set current power output solarPanel.SetCustomName(solarPanel.CustomName + " ~" + currentPower); } }
static void UpdateName(IMySolarPanel solarPanel, out float oldPower, out float currentPower) { if (solarPanel == null) throw new Exception(" UpdateName(IMySolarPanel, out float, out float): solarPanel is null"); if (!MaxOutput(solarPanel, out currentPower)) throw new Exception(" UpdateName(IMySolarPanel, out float, out float): Failed to read maximum power output from the solar panel's information"); string[] array = solarPanel.CustomName.Split('~'); if (array.Length > 1) { // old power was set float.TryParse(array[array.Length - 1], out oldPower); // update current power output string newName = ""; for (int i=0; i < array.Length - 1; i++) { newName += array[i]; } newName += "~" + currentPower; solarPanel.SetCustomName(newName); return; } oldPower = 0.0f; solarPanel.SetCustomName(solarPanel.CustomName + " ~" + currentPower); }
bool FuncTest(IMySolarPanel block) { //Solar Panel //Interface name: IMySolarPanel return(true); }