コード例 #1
0
        double getSolarpanelPowerWatt(IMySolarPanel SolarPanel)
        {
            debug("Detail (" + SolarPanel.CustomName + ") > " + SolarPanel.DetailedInfo);
            DetailedInfo DI = new DetailedInfo(SolarPanel);

            return(parsePower(DI.getValue(1).getValue()));
        }
コード例 #2
0
            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);
            }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
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));
}
コード例 #5
0
 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);
 }
コード例 #6
0
ファイル: RotoredSolars.cs プロジェクト: BlackFIlms/LearnCS
    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;
    }
コード例 #7
0
 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();
 }
コード例 #8
0
 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);
     }
 }
コード例 #9
0
 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;
 }
コード例 #10
0
        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;
            }
        }
コード例 #11
0
        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;
        }
コード例 #12
0
    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);
    }
コード例 #13
0
ファイル: solarhack.cs プロジェクト: ZerothAngel/SEScripts
 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;
 }
コード例 #14
0
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();
}
コード例 #15
0
 public SolarPanel(IMyTerminalBlock oBlock) : base(oBlock)
 {
     m_oBlock = (IMySolarPanel)oBlock;
 }
コード例 #16
0
 public SolarPanel(IMySolarPanel oBlock) : base(oBlock)
 {
     m_oBlock = oBlock;
 }
コード例 #17
0
ファイル: rev4a.cs プロジェクト: KamuiXenom/spas
	void UpdateName(IMySolarPanel solarPanel, out float oldPower) {
		float __ignore;
		UpdateName(solarPanel, out oldPower, out __ignore);
	}
コード例 #18
0
ファイル: rev4a.cs プロジェクト: KamuiXenom/spas
	// 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;
	}
コード例 #19
0
    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");
        }
    }
コード例 #20
0
 public PowerInfo(IMySolarPanel panel) : this(0, 0)
 {
     ParseFromDetailedInfo(panel);
 }
コード例 #21
0
        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;
                    }
                }
            }
        }
コード例 #22
0
ファイル: rev7.cs プロジェクト: KamuiXenom/spas
        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;
        }
コード例 #23
0
ファイル: rev4a.cs プロジェクト: KamuiXenom/spas
	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;
	}
コード例 #24
0
ファイル: rev4a.cs プロジェクト: KamuiXenom/spas
	void UpdateName(IMySolarPanel solarPanel) {
		float __ignore;
		UpdateName(solarPanel, out __ignore);
	}
コード例 #25
0
        double getSolarpanelPowerWatt(IMySolarPanel SolarPanel)
        {
            DetailedInfo DI = new DetailedInfo(SolarPanel);

            return(parsePower(DI.getValue(1).getValue()));
        }
コード例 #26
0
ファイル: rev5.cs プロジェクト: KamuiXenom/spas
	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;
	}
コード例 #27
0
ファイル: rev4a.cs プロジェクト: KamuiXenom/spas
	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();
	}
コード例 #28
0
ファイル: rev5.cs プロジェクト: KamuiXenom/spas
	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;
	}
コード例 #29
0
ファイル: rev5.cs プロジェクト: KamuiXenom/spas
	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;
		}
	}
コード例 #30
0
ファイル: rev5.cs プロジェクト: KamuiXenom/spas
	static void UpdateName(IMySolarPanel solarPanel) {
		float oldPower, currentPower;
		UpdateName(solarPanel, out oldPower, out currentPower);
	}
コード例 #31
0
ファイル: rev4a.cs プロジェクト: KamuiXenom/spas
	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);
		}
	}
コード例 #32
0
ファイル: rev5.cs プロジェクト: KamuiXenom/spas
	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);
	}
コード例 #33
0
 bool FuncTest(IMySolarPanel block)
 {
     //Solar Panel
     //Interface name: IMySolarPanel
     return(true);
 }