Files
CHOMPStation2/code/modules/power/sensors/powernet_sensor.dm
ShadowLarkens 951f37d2e3 TGUI Engineering: Squashed Edition (Commits Below)
TGUI APCs

 TGUI vending machines

 Fix AI default_tgui_interaction

 TGUI Airlocks

 Station & Atmospheric Alert TGUI + Misc NTOS-TGUI Fixes

 TGUI Air Alarms & Central Atmospheric Control

 Airlock TGUI

 TG... got rid of UI for fire alarm. í´·

 TGUI Gas Heating/Cooling System

 TGUI Gas Pump & Passive Gate + Fixes

 TGUI Omni Atmospherics

 TGUI Pipe Dispensers & RPD

 TGUI IntelliCore & Vending Fix

 TGUI Handheld Tanks

 TGUI Portable Pump & Scrubber

 TGUI Tank Dispenser & Canisters

 TGUI Radios

 TGUI SMES & Air Alarm adjustment

 Tweak vending machine interfaces a tad

 TGUI Algae Farm

 TGUI general_air_control

 - Distro & Waste Console
 - Riot Control Console
 - Atmos Intake Console
 - Engine Cooling Console

 TGUI Heavy Scrubber Control (and body scanner fix)

 TGUI trinary devices & shutoff monitor

 TGUI Telecomms Log Browser

 TGUI Telecomms Machine Browser

 TGUI Spaceheater Internal Panel

 TGUI Gravity Generator

 TGUI Id Cards & Fix ID Card Images

 TGUI Id Card Redesign

 TGUI Turbolift

 TGUI Suit Cycler & Suit Storage Unit & Vending Fixes

 TGUI Power Monitor

 TGUI Signalers

 TGUI Employment Records

 TGUI Drone Console

 TGUI RIGSuits

 TGUI PA & PACMAN, and Margin Fix

 TGUI Solar Panels & Fix Power Monitor

 Adjust TGUI modules & their interaction with NTOS

 TGUI RCON

 TGUI Message Monitor

 Bump TGUI line limit to 120 (ParadiseSS13/Paradise#14002)

 TGUI Exonet & NTNet Relay

 TGUI Telecomms Multitool Menu

 TGUI Shield Capacitor & Shield Generator

 TGUI Supermatter-everything & Refactors
2020-08-09 04:46:31 -07:00

274 lines
8.6 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// POWERNET SENSOR
//
// Last Change 31.12.2014 by Atlantis
//
// Powernet sensors are devices which relay information about connected powernet. This information may be relayed
// via two procs. Proc return_reading_text will return fully HTML styled string which contains all information. This
// may be used in PDAs or similar applications. Second proc, return_reading_data will return list containing needed data.
// This is used in NanoUI, for example.
/obj/machinery/power/sensor
name = "Powernet Sensor"
desc = "Small machine which transmits data about specific powernet"
anchored = 1
density = 0
layer = ABOVE_UTILITY
icon = 'icons/obj/objects.dmi'
icon_state = "floor_beacon" // If anyone wants to make better sprite, feel free to do so without asking me.
var/name_tag = "#UNKN#" // ID tag displayed in list of powernet sensors. Each sensor should have it's own tag!
var/long_range = 0 // If 1, sensor reading will show on all computers, regardless of Zlevel
var/list/history = list()
var/record_size = 60
var/record_interval = 50
var/next_record = 0
var/is_secret_monitor = FALSE
// Proc: New()
// Parameters: None
// Description: Automatically assigns name according to ID tag.
/obj/machinery/power/sensor/New()
..()
auto_set_name()
/obj/machinery/power/sensor/Initialize()
. = ..()
history["supply"] = list()
history["demand"] = list()
// Proc: auto_set_name()
// Parameters: None
// Description: Sets name of this sensor according to the ID tag.
/obj/machinery/power/sensor/proc/auto_set_name()
name = "[name_tag] - Powernet Sensor"
/obj/machinery/power/sensor/Destroy()
. = ..()
// TODO - Switch power_monitor to register deletion events instead of this.
for(var/obj/machinery/computer/power_monitor/PM in machines)
if(PM.power_monitor)
PM.power_monitor.refresh_sensors()
history.Cut()
history = null
// Proc: check_grid_warning()
// Parameters: None
// Description: Checks connected powernet for warnings. If warning is found returns 1
/obj/machinery/power/sensor/proc/check_grid_warning()
connect_to_network()
if(powernet)
if(powernet.problem)
return 1
return 0
// Proc: process()
// Parameters: None
// Description: This tracks historical usage, for TGUI power monitors
/obj/machinery/power/sensor/process()
if(!powernet)
use_power = USE_POWER_IDLE
connect_to_network()
else
use_power = USE_POWER_ACTIVE
record()
return 1
// This tracks historical usage, for TGUI power monitors
/obj/machinery/power/sensor/proc/record()
if(world.time >= next_record)
next_record = world.time + record_interval
var/datum/powernet/connected_powernet = powernet
var/list/supply = history["supply"]
if(connected_powernet)
supply += connected_powernet.viewavail
if(supply.len > record_size)
supply.Cut(1, 2)
var/list/demand = history["demand"]
if(connected_powernet)
demand += connected_powernet.viewload
if(demand.len > record_size)
demand.Cut(1, 2)
/obj/machinery/power/sensor/tgui_data()
var/list/data = list()
data["name"] = name_tag
data["stored"] = record_size
data["interval"] = record_interval / 10
data["attached"] = !!powernet
data["history"] = history
data["areas"] = list()
if(powernet)
for(var/obj/machinery/power/terminal/term in powernet.nodes)
if(istype(term.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = term.master
if(istype(A))
var/cell_charge
if(!A.cell)
cell_charge = 0
else
cell_charge = A.cell.percent()
data["areas"] += list(list(
"name" = A.area.name,
"charge" = cell_charge,
"load" = DisplayPower(A.lastused_total),
"charging" = A.charging,
"eqp" = A.equipment,
"lgt" = A.lighting,
"env" = A.environ,
))
return data
// Proc: reading_to_text()
// Parameters: 1 (amount - Power in Watts to be converted to W, kW or MW)
// Description: Helper proc that converts reading in Watts to kW or MW (returns string version of amount parameter)
/obj/machinery/power/sensor/proc/reading_to_text(var/amount = 0)
var/units = ""
// 10kW and less - Watts
if(amount < 10000)
units = "W"
// 10MW and less - KiloWatts
else if(amount < 10000000)
units = "kW"
amount = (round(amount/100) / 10)
// More than 10MW - MegaWatts
else
units = "MW"
amount = (round(amount/10000) / 100)
if (units == "W")
return "[amount] W"
else
return "~[amount] [units]" //kW and MW are only approximate readings, therefore add "~"
// Proc: find_apcs()
// Parameters: None
// Description: Searches powernet for APCs and returns them in a list.
/obj/machinery/power/sensor/proc/find_apcs()
if(!powernet)
return
var/list/L = list()
for(var/obj/machinery/power/terminal/term in powernet.nodes)
if(istype(term.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = term.master
L += A
return L
// Proc: return_reading_text()
// Parameters: None
// Description: Generates string which contains HTML table with reading data.
/obj/machinery/power/sensor/proc/return_reading_text()
// No powernet. Try to connect to one first.
if(!powernet)
connect_to_network()
var/out = ""
if(!powernet) // No powernet.
out = "# SYSTEM ERROR - NO POWERNET #"
return out
var/list/L = find_apcs()
var/total_apc_load = 0
if(L.len <= 0) // No APCs found.
out = "<b>No APCs located in connected powernet!</b>"
else // APCs found. Create very ugly (but working!) HTML table.
out += "<table><tr><th>Name<th>EQUIP<th>LIGHT<th>ENVIRON<th>CELL<th>LOAD"
// These lists are used as replacement for number based APC settings
var/list/S = list("M-OFF","A-OFF","M-ON", "A-ON")
var/list/chg = list("N","C","F")
// Split to multiple lines to make it more readable
for(var/obj/machinery/power/apc/A in L)
out += "<tr><td>\The [A.area]" // Add area name
out += "<td>[S[A.equipment+1]]<td>[S[A.lighting+1]]<td>[S[A.environ+1]]" // Show status of channels
if(A.cell)
out += "<td>[round(A.cell.percent())]% - [chg[A.charging+1]]"
else
out += "<td>NO CELL"
var/load = A.lastused_total // Load.
total_apc_load += load
load = reading_to_text(load)
out += "<td>[load]"
out += "<br><b>TOTAL AVAILABLE: [reading_to_text(powernet.avail)]</b>"
out += "<br><b>APC LOAD: [reading_to_text(total_apc_load)]</b>"
out += "<br><b>OTHER LOAD: [reading_to_text(max(powernet.load - total_apc_load, 0))]</b>"
out += "<br><b>TOTAL GRID LOAD: [reading_to_text(powernet.viewload)] ([round((powernet.load / powernet.avail) * 100)]%)</b>"
if(powernet.problem)
out += "<br><b>WARNING: Abnormal grid activity detected!</b>"
return out
// Proc: return_reading_data()
// Parameters: None
// Description: Generates list containing all powernet data. Optimised for usage with NanoUI
/obj/machinery/power/sensor/proc/return_reading_data()
// No powernet. Try to connect to one first.
if(!powernet)
connect_to_network()
var/list/data = list()
data["name"] = name_tag
if(!powernet)
data["error"] = "# SYSTEM ERROR - NO POWERNET #"
data["alarm"] = 0 // Runtime Prevention
return data
var/list/L = find_apcs()
var/total_apc_load = 0
var/list/APC_data = list()
if(L.len > 0)
// These lists are used as replacement for number based APC settings
var/list/S = list("M-OFF","A-OFF","M-ON", "A-ON")
var/list/chg = list("N","C","F")
for(var/obj/machinery/power/apc/A in L)
var/list/APC_entry = list()
// Channel Statuses
APC_entry["s_equipment"] = S[A.equipment+1]
APC_entry["s_lighting"] = S[A.lighting+1]
APC_entry["s_environment"] = S[A.environ+1]
// Cell Status
APC_entry["cell_charge"] = A.cell ? round(A.cell.percent()) : "NO CELL"
APC_entry["cell_status"] = A.cell ? chg[A.charging+1] : "N"
// Location
APC_entry["x"] = A.x
APC_entry["y"] = A.y
APC_entry["z"] = A.z
// Other info
APC_entry["total_load"] = reading_to_text(A.lastused_total)
// Hopefully removes those goddamn \improper s which are screwing up the UI
var/N = A.area.name
if(findtext(N, "<22>"))
N = copytext(N, 3)
APC_entry["name"] = N
// Add data into main list of APC data.
APC_data += list(APC_entry)
// Add load of this APC to total APC load calculation
total_apc_load += A.lastused_total
data["apc_data"] = APC_data
data["total_avail"] = reading_to_text(max(powernet.avail, 0))
data["total_used_apc"] = reading_to_text(max(total_apc_load, 0))
data["total_used_other"] = reading_to_text(max(powernet.viewload - total_apc_load, 0))
data["total_used_all"] = reading_to_text(max(powernet.viewload, 0))
// Prevents runtimes when avail is 0 (division by zero)
if(powernet.avail)
data["load_percentage"] = round((powernet.viewload / powernet.avail) * 100)
else
data["load_percentage"] = 100
data["alarm"] = powernet.problem ? 1 : 0
return data