Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Twinkie Industries™ Automation Presents
- * Airlock Automation v2.1
- *
- * This script will allow you to set up airlocks with vents and lights that will operate properly with a single button press or sensor trigger.
- *
- * On the vent and any lights add the following to CustomData
- * [Airlock]
- * Name=airlockName
- *
- * Also add it to the doors but include if the door is the outside door or not
- * [Airlock]
- * Name=airlockName
- * IsOutside=true
- *
- * When you run the script using the name of the airlock as the argument it will properly cycle the airlock.
- */
- // SETTINGS ---------------------------------------------------------------------------------------------------
- // If you set a value for GRID_NAME, each block will require it in the name. This is used to prevent blocks from
- // other grids being added.
- public const string GRID_NAME = "";
- // This timeout prevents the airlock getting stuck because the vent can't depressurize. For example, if there is
- // no free space in an oxygen tank or no oxygen tank connected the vent won't be able to remove the air.
- public const double VENT_TIMEOUT_SECONDS = 4.0;
- // The normal color for the airlock light when it is pressurized
- public static readonly Color PRESSURIZED_COLOR = Light.FLORESCENT_WARM;
- // The color for the airlock light when it is depressurized
- public static readonly Color UNPRESSURIZED_COLOR = Color.Red;
- // END SETTINGS - PLEASE DO NOT EDIT BELOW --------------------------------------------------------------------
- private Dictionary<string, Airlock> _airlocks = new Dictionary<string, Airlock>();
- private List<string> _invalidAirlocks = new List<string>();
- public Program()
- {
- Refresh();
- Runtime.UpdateFrequency = UpdateFrequency.Update10;
- }
- public void Main(string argument, UpdateType updateSource)
- {
- if (_invalidAirlocks.Count != 0)
- {
- Echo("Invalid airlocks:");
- foreach (string invalidAirlock in _invalidAirlocks)
- {
- Echo(invalidAirlock);
- }
- _invalidAirlocks.Clear();
- }
- if (string.IsNullOrWhiteSpace(argument))
- {
- foreach (var airlock in _airlocks.Values)
- {
- airlock.Update();
- }
- return;
- }
- string lower = argument.ToLowerInvariant();
- if (lower == "lock")
- {
- foreach (var airlock in _airlocks)
- {
- Echo($"Locking {airlock.Key}");
- airlock.Value.Lock();
- }
- return;
- }
- if (lower == "reset")
- {
- foreach (var airlock in _airlocks)
- {
- Echo($"Resetting {airlock.Key}");
- airlock.Value.Reset();
- }
- return;
- }
- if (lower == "refresh")
- {
- Echo($"Refresh arg");
- Refresh();
- return;
- }
- if (_airlocks.ContainsKey(argument))
- {
- Airlock airlock;
- if (_airlocks.TryGetValue(argument, out airlock))
- {
- Echo($"Cycling {argument}");
- airlock.Cycle();
- }
- else
- {
- Echo($"{argument} not found");
- }
- }
- }
- public void Refresh()
- {
- _airlocks.Clear();
- var airlockBlocks = new List<IMyTerminalBlock>();
- GridTerminalSystem.GetBlocksOfType(airlockBlocks, block => block.CustomName.Contains(GRID_NAME) && MyIni.HasSection(block.CustomData, CustomData.AIRLOCK));
- foreach (IMyTerminalBlock block in airlockBlocks)
- {
- CustomData customData;
- try
- {
- customData = new CustomData(block, Echo);
- }
- catch (Exception)
- {
- continue;
- }
- string airlockName = customData.Name;
- Airlock airlock;
- if (!_airlocks.TryGetValue(airlockName, out airlock))
- {
- airlock = _airlocks[airlockName] = new Airlock();
- }
- airlock.Add(block, customData);
- }
- foreach (KeyValuePair<string, Airlock> airlock in _airlocks)
- {
- if (!airlock.Value.IsFunctional)
- {
- _airlocks.Remove(airlock.Key);
- _invalidAirlocks.Add(airlock.Key);
- }
- else
- {
- airlock.Value.Reset();
- }
- }
- }
- /* Twinkie Industries™ Automation Presents
- * Airlock Automation v1.0*/
- /*
- * This script will allow you to set up airlocks with vents and lights that will operate properly with a single button press or sensor trigger.
- *
- * On the vent and any lights add the following to CustomData
- * [Airlock]
- * Name=airlockName
- *
- * Also add it to the doors but include if the door is the outside door or not
- * [Airlock]
- * Name=airlockName
- * IsOutside=true
- *
- * When you run the script using the name of the airlock as the argument it will properly cycle the airlock.
- */
- private class Airlock
- {
- private enum State
- {
- /// <summary> Waiting for the doors to close </summary>
- Locking,
- /// <summary> Airlock is offline </summary>
- Locked,
- /// <summary> Closing both doors and pressurizing </summary>
- Resetting,
- /// <summary> Nothing happening </summary>
- Idle,
- /// <summary> Waiting for the door to close </summary>
- Closing,
- /// <summary> Waiting for venting </summary>
- Venting,
- /// <summary> Waiting for the door to open </summary>
- Opening,
- }
- public List<Door> DoorsIn = new List<Door>();
- public List<Door> DoorsOut = new List<Door>();
- public List<Vent> AirVents = new List<Vent>();
- public List<Light> Lights = new List<Light>();
- private State _state = State.Idle;
- private bool _openOut;
- private DateTime _nextAction;
- public bool IsFunctional => DoorsIn.Count != 0 && DoorsOut.Count != 0 && AirVents.Count != 0;
- public List<Door> AllDoors
- {
- get
- {
- var rv = new List<Door>(DoorsIn.Count + DoorsOut.Count);
- rv.AddRange(DoorsIn);
- rv.AddRange(DoorsOut);
- return rv;
- }
- }
- public void Add(IMyTerminalBlock block, CustomData customData)
- {
- if (block is IMyDoor)
- {
- MyIniValue isOutside = customData.Get(CustomData.IS_OUTSIDE);
- if (isOutside.IsEmpty)
- return;
- var door = new Door(block as IMyDoor);
- if (isOutside.ToBoolean())
- {
- DoorsOut.Add(door);
- }
- else
- {
- DoorsIn.Add(door);
- }
- }
- else if (block is IMyAirVent)
- {
- AirVents.Add(new Vent(block as IMyAirVent));
- }
- else if (block is IMyLightingBlock)
- {
- Lights.Add(new Light(block as IMyLightingBlock));
- }
- }
- public void Update()
- {
- if (_state == State.Idle || _state == State.Locked)
- return;
- // Un-timed states
- if (_state == State.Venting)
- {
- if (_openOut && Vent.AllDepressurized(AirVents) ||
- !_openOut && Vent.AllPressurized(AirVents) ||
- DateTime.UtcNow > _nextAction) // timeout
- {
- _nextAction = Door.OpenDoors(_openOut ? DoorsOut : DoorsIn);
- RefreshLights();
- _state = State.Opening;
- }
- return;
- }
- if (DateTime.UtcNow < _nextAction)
- return;
- // Timed states
- switch (_state)
- {
- // Cycle
- case State.Closing:
- {
- PowerOff();
- Vent.SetDepressurize(AirVents, _openOut);
- _nextAction = DateTime.UtcNow + TimeSpan.FromSeconds(VENT_TIMEOUT_SECONDS);
- _state = State.Venting;
- break;
- }
- case State.Opening:
- {
- PowerOff();
- RefreshLights();
- _state = State.Idle;
- break;
- }
- // Lock
- case State.Locking:
- {
- PowerOff();
- _state = State.Locked;
- break;
- }
- // Reset
- case State.Resetting:
- {
- Light.SetEnabled(Lights, true);
- RefreshLights();
- _state = State.Idle;
- break;
- }
- }
- }
- public void Cycle()
- {
- if (_state != State.Idle)
- return;
- _openOut = !_openOut;
- _nextAction = Door.CloseDoors(AllDoors);
- Light.SetColor(Lights, Color.Red);
- _state = State.Closing;
- }
- public void Reset()
- {
- _nextAction = Door.CloseDoors(AllDoors);
- Light.SetEnabled(Lights, true);
- _state = State.Resetting;
- }
- public void Lock()
- {
- _nextAction = Door.CloseDoors(AllDoors);
- Light.SetEnabled(Lights, false);
- _state = State.Locking;
- }
- private void PowerOff()
- {
- Door.SetEnabled(AllDoors, false);
- }
- private void RefreshLights()
- {
- Color color = Vent.AllPressurized(AirVents) ? PRESSURIZED_COLOR : UNPRESSURIZED_COLOR;
- Light.SetColor(Lights, color);
- }
- }
- private class CustomData
- {
- public const string AIRLOCK = "Airlock";
- public const string IS_OUTSIDE = "IsOutside";
- private const string NAME = "Name";
- public MyIni Ini { get; } = new MyIni();
- public string Name => Ini.Get(AIRLOCK, NAME).ToString();
- public CustomData(IMyTerminalBlock block, Action<string> echo)
- {
- MyIniParseResult parseResult;
- if (!Ini.TryParse(block.CustomData, out parseResult))
- {
- echo?.Invoke("Failed to parse ini");
- throw new Exception(parseResult.ToString());
- }
- MyIniValue nameResult = Get(NAME);
- if (nameResult.IsEmpty)
- {
- string message = $"Can't find {NAME} setting for {block.CustomName}";
- echo?.Invoke(message);
- throw new Exception(message);
- }
- }
- public MyIniValue Get(string key) => Ini.Get(AIRLOCK, key);
- }
- // Mixin
- public class Door
- {
- public const int DELAY_STANDARD_MILLIS = 1000;
- public const int DELAY_HANGAR_MILLIS = 10000;
- private int _customDelay;
- private bool _isHangar;
- public IMyDoor Block { get; }
- public bool Enabled { get { return Block.Enabled; } set { Block.Enabled = value; } }
- public DoorStatus Status => Block.Status;
- public float OpenRatio => Block.OpenRatio;
- public bool IsOpen => Block.Status == DoorStatus.Open;
- public bool IsClosed => Block.Status == DoorStatus.Closed;
- public bool IsTransitioning => !IsOpen && !IsClosed;
- public Door(IMyDoor block, int customDelay = 0)
- {
- Block = block;
- _customDelay = customDelay;
- _isHangar = block is IMyAirtightHangarDoor;
- }
- public static void SetEnabled(List<Door> doors, bool value)
- {
- foreach (Door door in doors)
- {
- door.Enabled = value;
- }
- }
- public static bool AnyOpened(List<Door> doors)
- {
- foreach (var door in doors)
- {
- if (door.Status == DoorStatus.Open)
- return true;
- }
- return false;
- }
- public static bool AnyClosed(List<Door> doors)
- {
- foreach (var door in doors)
- {
- if (door.Status == DoorStatus.Closed)
- return true;
- }
- return false;
- }
- public static DateTime OpenDoors(List<Door> doors)
- {
- DateTime maxDelay = DateTime.MinValue;
- foreach (Door door in doors)
- {
- DateTime delay = door.OpenDoor();
- if (delay > maxDelay)
- maxDelay = delay;
- }
- return maxDelay;
- }
- public static DateTime CloseDoors(List<Door> doors)
- {
- DateTime maxDelay = DateTime.MinValue;
- foreach (Door door in doors)
- {
- DateTime delay = door.CloseDoor();
- if (delay > maxDelay)
- maxDelay = delay;
- }
- return maxDelay;
- }
- public DateTime OpenDoor()
- {
- if (Block.Status != DoorStatus.Open)
- {
- Block.Enabled = true;
- Block.OpenDoor();
- return Delay();
- }
- return DateTime.MinValue;
- }
- public DateTime CloseDoor()
- {
- if (Block.Status != DoorStatus.Closed)
- {
- Block.Enabled = true;
- Block.CloseDoor();
- return Delay();
- }
- return DateTime.MinValue;
- }
- public DateTime ToggleDoor()
- {
- if (Block.Status == DoorStatus.Closed ||
- Block.Status == DoorStatus.Closing)
- {
- return OpenDoor();
- }
- return CloseDoor();
- }
- private DateTime Delay()
- {
- int standardDelay = _isHangar ? DELAY_HANGAR_MILLIS : DELAY_STANDARD_MILLIS;
- int delay = _customDelay != 0 ? _customDelay : standardDelay;
- return DateTime.UtcNow + TimeSpan.FromMilliseconds(delay);
- }
- }
- // Mixin
- public class Light
- {
- public static readonly Color SODIUM = new Color(255, 183, 76);
- public static readonly Color INCANDESCENT = new Color(255, 255, 210);
- public static readonly Color FLORESCENT_WARM = new Color(230, 255, 255);
- public static readonly Color FLORESCENT_COOL = new Color(175, 215, 255);
- public IMyLightingBlock Block { get; private set; }
- public bool OriginalEnabled { get; private set; }
- public float OriginalRadius { get; private set; }
- public float OriginalIntensity { get; private set; }
- public float OriginalFalloff { get; private set; }
- public float OriginalBlinkInterval { get; private set; }
- public float OriginalBlinkLength { get; private set; }
- public float OriginalBlinkOffset { get; private set; }
- public Color OriginalColor { get; private set; }
- public bool Enabled { get { return Block.Enabled;} set { Block.Enabled = value; } }
- public float Radius { get { return Block.Radius; } set { Block.Radius = value; } }
- float Intensity { get { return Block.Intensity; } set { Block.Intensity = value; } }
- float Falloff { get { return Block.Falloff; } set { Block.Falloff = value; } }
- float BlinkIntervalSeconds { get { return Block.BlinkIntervalSeconds; } set { Block.BlinkIntervalSeconds = value; } }
- float BlinkLength { get { return Block.BlinkLength; } set { Block.BlinkLength = value; } }
- float BlinkOffset { get { return Block.BlinkOffset; } set { Block.BlinkOffset = value; } }
- Color Color { get { return Block.Color; } set { Block.Color = value; } }
- public Light(IMyLightingBlock block)
- {
- Block = block;
- OriginalEnabled = Block.Enabled;
- OriginalRadius = Block.Radius;
- OriginalIntensity = Block.Intensity;
- OriginalFalloff = Block.Falloff;
- OriginalBlinkInterval = Block.BlinkIntervalSeconds;
- OriginalBlinkLength = Block.BlinkLength;
- OriginalBlinkOffset = Block.BlinkOffset;
- OriginalColor = Block.Color;
- }
- public static void SetEnabled(List<Light> lights, bool value)
- {
- foreach (var light in lights)
- {
- light.Enabled = value;
- }
- }
- public static void SetColor(List<Light> lights, Color color)
- {
- foreach (var light in lights)
- {
- light.Color = color;
- }
- }
- public void Reset()
- {
- ResetEnabled();
- ResetRadius();
- ResetIntensity();
- ResetFalloff();
- ResetBlinkInterval();
- ResetBlinkLength();
- ResetBlinkOffset();
- ResetColor();
- }
- public void ResetEnabled() => Block.Enabled = OriginalEnabled;
- public void ResetRadius() => Block.Radius = OriginalRadius;
- public void ResetIntensity() => Block.Intensity = OriginalIntensity;
- public void ResetFalloff() => Block.Falloff = OriginalFalloff;
- public void ResetBlinkInterval() => Block.BlinkIntervalSeconds = OriginalBlinkInterval;
- public void ResetBlinkLength() => Block.BlinkLength = OriginalBlinkLength;
- public void ResetBlinkOffset() => Block.BlinkOffset = OriginalBlinkOffset;
- public void ResetColor() => Block.Color = OriginalColor;
- }
- // Mixin
- public class Vent
- {
- private const int DELAY_MILLIS = 2000;
- private int _customDelay;
- public IMyAirVent Block { get; }
- public bool Enabled { get { return Block.Enabled; } set { Block.Enabled = value; } }
- public bool CanPressurize => Block.CanPressurize;
- public float OxygenLevel => Block.GetOxygenLevel();
- public VentStatus Status => Block.Status;
- public bool PressurizationEnabled => Block.PressurizationEnabled;
- public bool Depressurize => Block.Depressurize;
- public bool IsPressurized => Block.Status == VentStatus.Pressurized;
- public bool IsDepressurized => Block.Status == VentStatus.Depressurized;
- public bool IsPressureUncertain => !IsPressurized && !IsDepressurized;
- public Vent(IMyAirVent block, int customDelay = 0)
- {
- Block = block;
- _customDelay = customDelay;
- }
- public static void SetEnabled(List<Door> doors, bool value)
- {
- foreach (Door door in doors)
- {
- door.Enabled = value;
- }
- }
- public static float OxygenLevelMin(List<Vent> vents)
- {
- float level = float.MaxValue;
- foreach (var vent in vents)
- {
- if (vent.OxygenLevel < level)
- level = vent.OxygenLevel;
- }
- return level;
- }
- public static float OxygenLevelMax(List<Vent> vents)
- {
- float level = float.MinValue;
- foreach (var vent in vents)
- {
- if (vent.OxygenLevel > level)
- level = vent.OxygenLevel;
- }
- return level;
- }
- public static float OxygenLevelAve(List<Vent> vents)
- {
- float level = 0;
- foreach (var vent in vents)
- {
- level += vent.OxygenLevel;
- }
- return level / (float)vents.Count;
- }
- public static bool AnyDepressurizing(List<Vent> vents)
- {
- foreach (var vent in vents)
- {
- if (vent.Depressurize)
- return true;
- }
- return false;
- }
- public static DateTime SetDepressurize(List<Vent> vents, bool value)
- {
- DateTime maxDelay = DateTime.MinValue;
- for (int i = 0; i < vents.Count; i++)
- {
- if (vents[i]?.Block == null)
- continue;
- DateTime delay = vents[i].SetDepressurize(value);
- if (delay > maxDelay)
- maxDelay = delay;
- }
- return maxDelay;
- }
- public static bool AllPressurized(List<Vent> vents)
- {
- foreach (var vent in vents)
- {
- if (vent.Status != VentStatus.Pressurized)
- return false;
- }
- return true;
- }
- public static bool AllDepressurized(List<Vent> vents)
- {
- foreach (var vent in vents)
- {
- if (vent.Status != VentStatus.Depressurized)
- return false;
- }
- return true;
- }
- public DateTime SetDepressurize(bool value)
- {
- if (Block.Depressurize != value)
- {
- Block.Depressurize = value;
- return Delay();
- }
- return DateTime.MinValue;
- }
- private DateTime Delay()
- {
- int delay = _customDelay != 0 ? _customDelay : DELAY_MILLIS;
- return DateTime.UtcNow + TimeSpan.FromMilliseconds(delay);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement