Skip to content

Commit 4f1e949

Browse files
committed
ONLY_SAME_CONSTRUCT_BATTERIES option removed for performance reasons
Fix #1
1 parent 36e1c3d commit 4f1e949

File tree

5 files changed

+407
-0
lines changed

5 files changed

+407
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
//
2+
// XXX Battery-Monitor/Battery-Monitor_v1.1/_Customize.cs XXX
3+
//
4+
5+
//
6+
// VARIABLES (EDIT THESE)
7+
//
8+
public const string VERSION = "Battery Monitor v1.0",
9+
BATTERY_STRING = ".batteries",
10+
PANEL_HEADER_STRING = " Main Base Power Monitor";
11+
public const UpdateFrequency FREQ = UpdateFrequency.Update100;
12+
public const int PANEL_STD_ROW_COUNT = 23,
13+
PANEL_WIDE_ROW_COUNT = 23,
14+
PANEL_HEADER_ROW_COUNT = 7,
15+
PANEL_FOOTER_ROW_COUNT = 10;
16+
17+
//
18+
// XXX Battery-Monitor/Battery-Monitor_v1.1/_Main.cs XXX
19+
//
20+
21+
List<IMyTextPanel> lcds;
22+
List<IMyBatteryBlock> batteries;
23+
24+
public Program() {
25+
Reprogram();
26+
}
27+
28+
public void Reprogram() {
29+
Runtime.UpdateFrequency = FREQ;
30+
// Run all the Program__ methods
31+
Program__Programmable_Block_Display();
32+
Program__GetBatteries();
33+
Program__GetLCDs();
34+
Program__SetupLCDs();
35+
}
36+
37+
public void Save() {
38+
// Called when the program needs to save its state.
39+
// Use this method to save your state to the Storage field or some other means.
40+
} // Save()
41+
42+
public void Main(string argument, UpdateType updateSource) {
43+
// NOTE: multiple triggers can roll in on the same tick
44+
// Test each one individually
45+
46+
if((updateSource & UpdateType.Update100) != 0) {
47+
Main__WriteLCDs();
48+
} // if trigger via self
49+
if((updateSource & (UpdateType.Trigger | UpdateType.Terminal)) != 0) {
50+
Reprogram(); // run setup again
51+
} // if trigger via button or "run" command
52+
Main__WriteDiagnostics();
53+
} // Main()
54+
55+
public void Program__GetBatteries() {
56+
batteries = GetBlocksOfTypeWithNames(batteries, BATTERY_STRING)
57+
.FindAll(battery => battery.IsSameConstructAs(Me))
58+
.OrderBy(battery => battery.CustomName).ToList();
59+
} // Program__GetBatteries()
60+
61+
public void Program__GetLCDs() {
62+
lcds = GetBlocksOfTypeWithNames(lcds, BATTERY_STRING)
63+
.FindAll(lcd => lcd.IsSameConstructAs(Me))
64+
.OrderBy(lcd => lcd.CustomName).ToList();
65+
} // Program__GetLCDs()
66+
67+
public void Program__SetupLCDs() {
68+
foreach (IMyTextPanel lcd in lcds) {
69+
lcd.ContentType = ContentType.TEXT_AND_IMAGE;
70+
lcd.Font = "Monospace";
71+
lcd.FontSize = 0.75f;
72+
}
73+
} // Program__SetupLCDs()
74+
75+
public void Main__WriteLCDs() {
76+
int idxBattery = 0;
77+
foreach(IMyTextPanel lcd in lcds) {
78+
int idxLine = PANEL_HEADER_ROW_COUNT;
79+
WriteLCD_Header(lcd, StripClassesFromName(lcd));
80+
while(idxBattery < batteries.Count) {
81+
if(idxLine < PANEL_STD_ROW_COUNT) {
82+
WriteLCD_BatteryInfo(lcd, batteries[idxBattery]);
83+
idxLine++;
84+
} else {
85+
continue; // to next LCD
86+
}
87+
idxBattery++;
88+
} // while idxBattery
89+
if(idxLine + PANEL_FOOTER_ROW_COUNT > PANEL_STD_ROW_COUNT) {
90+
continue; // to next LCD
91+
}
92+
WriteLCD_Footer(lcd);
93+
break; // out of the foreach, incase there are extra panels
94+
} // foreach lcd
95+
} // Main__WriteLCDs()
96+
97+
public void WriteLCD_Header(IMyTextPanel panel, string customName = null) {
98+
if(customName == null) {
99+
customName = panel.CustomName;
100+
}
101+
// Display a header, including the screen's name
102+
panel.WriteText(
103+
PANEL_HEADER_STRING + HR +
104+
customName + HR,
105+
false
106+
);
107+
}
108+
109+
public void WriteLCD_BatteryInfo(IMyTextPanel screen, IMyBatteryBlock battery) {
110+
float kWh_f = battery.CurrentStoredPower * 1000,
111+
percent_f = battery.CurrentStoredPower * 100 / battery.MaxStoredPower;
112+
string kWh_s = kWh_f.ToString("#,##0").PadLeft(6),
113+
percent_s = percent_f.ToString("##0.0").PadLeft(5),
114+
batteryName = StripClassesFromName(battery);
115+
// Display the name of a battery block, then the charge level
116+
screen.WriteText($"{batteryName} = {kWh_s} kWh {percent_s}%\n", true);
117+
}
118+
119+
public void WriteLCD_Footer(IMyTextPanel panel) {
120+
float inputkW = 0.0f,
121+
outputkW = 0.0f,
122+
storedkWh = 0.0f,
123+
maxkWh = 0.0f,
124+
percent_f = 0.0f;
125+
foreach (IMyBatteryBlock battery in batteries) {
126+
storedkWh += (battery.CurrentStoredPower * 1000);
127+
maxkWh += (battery.MaxStoredPower * 1000);
128+
inputkW += (battery.CurrentInput * 1000);
129+
outputkW += (battery.CurrentOutput * 1000);
130+
}
131+
percent_f = storedkWh * 100 / maxkWh;
132+
string inputkW_s = inputkW.ToString("#,##0").PadLeft(6),
133+
outputkW_s = outputkW.ToString("#,##0").PadLeft(6),
134+
storedkWh_s = storedkWh.ToString("#,##0").PadLeft(6),
135+
maxkWh_s = maxkWh.ToString("#,##0").PadLeft(6),
136+
percent_s = percent_f.ToString("##0.0").PadLeft(6);
137+
float hourRaw = (inputkW > outputkW) ?
138+
((maxkWh - storedkWh)/(inputkW - outputkW)) : (storedkWh/(outputkW - inputkW));
139+
int secRaw = (int)(hourRaw * 3600),
140+
hr = (secRaw / 3600),
141+
min = (secRaw % 3600) / 60,
142+
sec = (secRaw % 60);
143+
string hr_s = hr.ToString("#,##0h:"),
144+
min_s = min.ToString("00m:"),
145+
sec_s = sec.ToString("00s"),
146+
timeUntil = "Time until " + (inputkW > outputkW ? "full" : "empty") + ": " +
147+
hr_s + min_s + sec_s;
148+
panel.WriteText(
149+
HR +
150+
$" Station Charge = {percent_s} %\n" +
151+
$" {storedkWh_s}/{maxkWh_s} kWh\n" +
152+
$" Input = {inputkW_s} kW\n" +
153+
$" Output = {outputkW_s} kW" +
154+
HR + timeUntil + "\n",
155+
true
156+
);
157+
// end?
158+
}
159+
160+
//
161+
// XXX Battery-Monitor/Battery-Monitor_v1.1/_Template_v0.1.cs XXX
162+
//
163+
164+
// XXX START (DO NOT EDIT) XXX
165+
// This portion of the file should not be edited
166+
// Rather, the Template should be revised and re-released with a new version
167+
// Submit a pull-request for edits to the Template
168+
169+
//
170+
// CLASS DEFINITIONS
171+
//
172+
public class Dict<TKey, TValue> : Dictionary<TKey, TValue> {}
173+
public class Dict<TKey1, TKey2, TValue> : Dictionary<TKey1, Dictionary<TKey2, TValue>> {}
174+
175+
public const int PROGRAMMABLE_BLOCK_SCREEN_SURFACE_NUM = 0; // TODO unverified
176+
public const int PROGRAMMABLE_BLOCK_KEYBOARD_SURFACE_NUM = 1; // TODO unverified
177+
public const float FONT_SIZE_REGULAR = 0.50f;
178+
public const string HR_NO_NL = "====================================", // TODO = or - instead?
179+
HR = "\n" + HR_NO_NL + "\n",
180+
FONT = "Monospace";
181+
//
182+
// HELPER METHODS
183+
// these are shared across many scripts
184+
// if there is a bug, report it or make a PR on github
185+
// TODO github link
186+
//
187+
188+
// TODO need to be made static?
189+
private void Program__Programmable_Block_Display() {
190+
IMyTextSurface display = Me.GetSurface(PROGRAMMABLE_BLOCK_SCREEN_SURFACE_NUM);
191+
string timeString = DateTime.Now.ToString("yyy-MM-dd HH:mm:ss tt");
192+
193+
// write out to display
194+
display.ContentType = ContentType.TEXT_AND_IMAGE;
195+
display.WriteText($"\nCurrent Program: {VERSION}\n", false);
196+
display.WriteText($"\nLast Compiled: {timeString}\n", true);
197+
} // Program_Programmable_Block_Display()
198+
199+
// TODO need to be made static?
200+
private void Main__WriteDiagnostics() {
201+
double LastRunTimeNs = Runtime.LastRunTimeMs * 1000;
202+
203+
// write out to the programmable block's internal console
204+
Echo($"Last run: {LastRunTimeNs.ToString("n0")}ns");
205+
Echo($"Instruction limit: ");
206+
Echo($"{Runtime.CurrentInstructionCount}/{Runtime.MaxInstructionCount}");
207+
} // WriteDiagnostics()
208+
209+
// TODO need to be made static
210+
private string Match(string input, string pattern, string errMsg) {
211+
System.Text.RegularExpressions.Match match;
212+
match = System.Text.RegularExpressions.Regex.Match(input, pattern);
213+
if(match.Success) {
214+
return match.Value;
215+
} else {
216+
Echo(errMsg);
217+
return (string)(null);
218+
}
219+
} // Match()
220+
221+
public List<Type> GetBlocksOfTypeWithNames<Type>(List<Type> blocks,
222+
params string[] strings)
223+
where Type : class, IMyTerminalBlock {
224+
// create an empty list of blocks of a specific type
225+
List<Type> blks = new List<Type>();
226+
// populate that list with all those blocks
227+
GridTerminalSystem.GetBlocksOfType(blks);
228+
// filter that list by the strings provided
229+
return blocks = FilterBlocksOfTypeWithNames(blks, strings);
230+
}
231+
232+
public List<Type> FilterBlocksOfTypeWithNames<Type>(List<Type> blocks,
233+
params string[] strings)
234+
where Type : class, IMyTerminalBlock {
235+
// find the subset of blocks which match all strings provided
236+
return blocks = blocks.FindAll(block => strings.All(str => block.CustomName.Contains(str)));
237+
}
238+
239+
public List<IMyTerminalBlock> GetBlocksOfNames(params string[] strings) {
240+
// create an empty list of blocks of all types
241+
List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
242+
// populate that list with all blocks on the grid
243+
GridTerminalSystem.GetBlocks(blocks);
244+
// filter that list by the strings provided
245+
return FilterBlocksOfTypeWithNames(blocks, strings);
246+
}
247+
248+
public string StripClassesFromName(IMyTerminalBlock blk) {
249+
string name = blk.CustomName;
250+
if(name.Contains('.')) {
251+
name = name.Substring(0, name.IndexOf('.')).Trim();
252+
}
253+
return name;
254+
} // StripClassesFromName()
255+
256+
// XXX END (DO NOT EDIT) XXX
257+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//
2+
// VARIABLES (EDIT THESE)
3+
//
4+
public const string VERSION = "Battery Monitor v1.0",
5+
BATTERY_STRING = ".batteries",
6+
PANEL_HEADER_STRING = " Main Base Power Monitor";
7+
public const UpdateFrequency FREQ = UpdateFrequency.Update100;
8+
public const int PANEL_STD_ROW_COUNT = 23,
9+
PANEL_WIDE_ROW_COUNT = 23,
10+
PANEL_HEADER_ROW_COUNT = 7,
11+
PANEL_FOOTER_ROW_COUNT = 10;

0 commit comments

Comments
 (0)