灵符lingfu

LingSys

↓ 0 downloads

Your machine's memory, GPU, motherboard and network, drawn and played in the Ling design system: LingSys, a small build for USB liquid-cooler displays, LingNet for IPv4/IPv6, DNS and packets, and a LingOS edition. 64-bit and 32-bit Windows builds included.

Keywords system-monitor, visualization, network, ipv6, gpu, lcd, lingos, ling
lingfu install LingSys
LicenseMIT
AuthorsLing Lin <taellinglin@gmail.com>
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (48)

src/30_data.ling
# ───────────────────────────── generic snapshot helpers ──────────────────────
# The *.snap files are written by sampler.ps1 (memory) and sampler_hw.ps1 (gpu, board, net).
# One record per line, fields split by '|'. A row is a list of strings.

fn nf(row, i) {
    if i < len(row) { return to_number(row[i]) }
    return 0.0
}

fn sf(row, i) {
    if i < len(row) { return row[i] }
    return ""
}

fn nums(row, from) {
    bind out = []
    bind i = from
    while i < len(row) {
        bind out = list_push(out, to_number(row[i]))
        bind i = i + 1
    }
    return out
}

fn zeros(n) {
    bind out = []
    bind i = 0
    while i < n {
        bind out = list_push(out, 0.0)
        bind i = i + 1
    }
    return out
}

fn pad_to(l, n) {
    bind out = l
    while len(out) < n {
        bind out = list_push(out, 0.0)
    }
    return out
}

fn snap_rows(text) {
    bind lines = split(text, "\n")
    bind out = []
    bind i = 0
    while i < len(lines) {
        bind ln = trim(lines[i])
        if str_len(ln) > 2 { bind out = list_push(out, split(ln, "|")) }
        bind i = i + 1
    }
    return out
}

# the sampler's wall-clock stamp: if it stops changing, the sampler has stopped
fn snap_time(rows) {
    bind i = 0
    while i < len(rows) {
        bind r = rows[i]
        if r[0] == "t" { return nf(r, 1) }
        bind i = i + 1
    }
    return 0.0
}

# glide a list of numbers (or a list of such lists) toward its target
fn glide(cur, tgt, k) {
    if len(cur) != len(tgt) { return tgt }
    bind out = []
    bind i = 0
    while i < len(cur) {
        bind out = list_push(out, mix(cur[i], tgt[i], k))
        bind i = i + 1
    }
    return out
}

fn glide_ll(cur, tgt, k) {
    if len(cur) != len(tgt) { return tgt }
    bind out = []
    bind i = 0
    while i < len(cur) {
        bind out = list_push(out, glide(cur[i], tgt[i], k))
        bind i = i + 1
    }
    return out
}

# log scale to 0..1: full is log10 of the value that fills the strip
fn lg(x, full) { return clamp(log10(1.0 + max(x, 0.0)) / full, 0.0, 1.0) }

fn fmt_bytes(v) {
    if v >= 1000000000.0 { return num_str(round(v / 100000000.0) / 10.0) + "G" }
    if v >= 1000000.0 { return num_str(round(v / 100000.0) / 10.0) + "M" }
    if v >= 1000.0 { return num_str(round(v / 1000.0)) + "K" }
    return num_str(round(v))
}

fn fmt_up(s) {
    bind d = floor(s / 86400.0)
    bind h = floor((s - d * 86400.0) / 3600.0)
    bind m = floor((s - d * 86400.0 - h * 3600.0) / 60.0)
    if d > 0 { return num_str(d) + "D " + num_str(h) + "H" }
    return num_str(h) + "H " + num_str(m) + "M"
}

fn pct(x) { return num_str(round(x)) }

fn short_gpu(name) {
    bind s = str_replace(name, "NVIDIA ", "")
    bind s = str_replace(s, "GEFORCE ", "")
    bind s = str_replace(s, "AMD ", "")
    bind s = str_replace(s, "RADEON ", "")
    bind s = str_replace(s, "INTEL(R) ", "")
    return str_slice(s, 0, 14)
}

# ───────────────────────────── history strips ────────────────────────────────
fn hs_new() {
    bind hs = []
    bind i = 0
    while i < HS_COUNT {
        bind hs = list_push(hs, zeros(HS_N))
        bind i = i + 1
    }
    return hs
}

fn hs_push(hs, id, v) {
    bind old = hs[id]
    bind nw = []
    bind i = 1
    while i < len(old) {
        bind nw = list_push(nw, old[i])
        bind i = i + 1
    }
    bind nw = list_push(nw, clamp(v, 0.0, 1.0))
    return list_set(hs, id, nw)
}

# ───────────────────────────── GPU ───────────────────────────────────────────
# pack GP: [good, n, names, drvs, vecs, engs, procs, sel]
bind GP_N = 1
bind GP_NAME = 2
bind GP_DRV = 3
bind GP_VEC = 4
bind GP_ENG = 5
bind GP_PROC = 6
bind GP_SEL = 7

fn parse_gpu(text) {
    bind rows = snap_rows(text)
    bind n = 0
    bind i = 0
    while i < len(rows) {
        bind r = rows[i]
        if r[0] == "n" { bind n = max(n, floor(nf(r, 1)) + 1) }
        bind i = i + 1
    }
    bind n = min(n, 8)
    bind names = []
    bind drvs = []
    bind vecs = []
    bind engs = []
    bind procs = []
    bind g = 0
    while g < n {
        bind names = list_push(names, "GPU")
        bind drvs = list_push(drvs, "")
        bind vecs = list_push(vecs, zeros(GV_LEN))
        bind engs = list_push(engs, zeros(6))
        bind procs = list_push(procs, [[], [], [], []])
        bind g = g + 1
    }
    bind i = 0
    while i < len(rows) {
        bind r = rows[i]
        bind tag = r[0]
        bind g = floor(nf(r, 1))
        if g >= 0 {
            if g < n {
                if tag == "n" {
                    bind names = list_set(names, g, str_upper(sf(r, 2)))
                    bind drvs = list_set(drvs, g, sf(r, 3))
                }
                if tag == "v" { bind vecs = list_set(vecs, g, pad_to(nums(r, 2), GV_LEN)) }
                if tag == "e" { bind engs = list_set(engs, g, pad_to(nums(r, 2), 6)) }
                if tag == "a" {
                    bind pg = procs[g]
                    bind pg = [list_push(pg[0], str_upper(sf(r, 2))), list_push(pg[1], nf(r, 4)), list_push(pg[2], nf(r, 5)), list_push(pg[3], nf(r, 6))]
                    bind procs = list_set(procs, g, pg)
                }
            }
        }
        bind i = i + 1
    }
    bind good = 0
    if n > 0 { bind good = 1 }
    return [good, n, names, drvs, vecs, engs, procs, 0, snap_time(rows)]
}

bind SIM_NAMES = ["chrome", "code", "firefox", "explorer", "python", "node", "slack", "spotify", "ling", "audiodg",
                  "svchost", "dwm", "teams", "steam", "obs", "docker", "mysqld", "discord", "winword", "excel"]

fn sim_gpu(t) {
    bind names = []
    bind drvs = []
    bind vecs = []
    bind engs = []
    bind procs = []
    bind g = 0
    while g < 4 {
        bind u = 22.0 + 20.0 * sin(t * 0.31 + g * 2.0) + 55.0 * pow(abs(sin(t * 0.07 + g * 1.3)), 4.0)
        bind u = clamp(u, 1.0, 100.0)
        bind vu = 9000.0 + 5000.0 * sin(t * 0.05 + g) + 40.0 * u
        bind names = list_push(names, "SIM GPU " + num_str(g))
        bind drvs = list_push(drvs, "0.0")
        bind vecs = list_push(vecs, [36.0 + 0.4 * u, 28.0 + 0.55 * u, 18.0 + 4.1 * u, 450.0, 210.0 + 28.0 * u, 3105.0, 405.0 + 100.0 * u, 10501.0, u, u * 0.4, vu, 24564.0, 4.0, 16.0, 0.0, 0.0])
        bind engs = list_push(engs, [u * 0.95, u * 0.3 * (1.0 + sin(t * 0.4)), 12.0 * pow(abs(sin(t * 0.21 + g)), 3.0), 6.0 * pow(abs(sin(t * 0.13)), 5.0), 25.0 * pow(abs(sin(t * 0.09 + g)), 6.0), 3.0])
        bind pn = []
        bind pd = []
        bind ps = []
        bind pu = []
        bind q = 0
        while q < 8 {
            bind pn = list_push(pn, str_upper(SIM_NAMES[(q + g * 5) % 20]))
            bind pd = list_push(pd, vu * 0.5 / (1.0 + q * 0.9))
            bind ps = list_push(ps, 30.0 / (1.0 + q))
            bind pu = list_push(pu, u * 0.7 / (1.0 + q))
            bind q = q + 1
        }
        bind procs = list_push(procs, [pn, pd, ps, pu])
        bind g = g + 1
    }
    return [1, 4, names, drvs, vecs, engs, procs, 0, 0.0]
}

# ───────────────────────────── board ─────────────────────────────────────────
# pack BP: [good, info, bv, cutil, cfreq, dimms, disks, dio, sens, t]
bind BP_INFO = 1
bind BP_BV = 2
bind BP_CU = 3
bind BP_CF = 4
bind BP_DIMM = 5
bind BP_DISK = 6
bind BP_DIO = 7
bind BP_SENS = 8
# info: [maker, product, bios vendor, bios version, bios date, cpu, cores, threads, max MHz, sockets, dimm slots, max GB]
bind BI_MAKER = 0
bind BI_PROD = 1
bind BI_BIOSV = 2
bind BI_BIOSVER = 3
bind BI_BIOSDATE = 4
bind BI_CPU = 5
bind BI_CORES = 6
bind BI_THR = 7
bind BI_MHZ = 8
bind BI_SOCK = 9
bind BI_SLOTS = 10
bind BI_MAXGB = 11

fn parse_board(text) {
    bind rows = snap_rows(text)
    bind info = ["", "", "", "", "", "", 0, 0, 0, 1, 0, 0]
    bind bv = []
    bind nc = 0
    bind i = 0
    while i < len(rows) {
        bind r = rows[i]
        if r[0] == "k" { bind nc = max(nc, floor(nf(r, 1)) + 1) }
        bind i = i + 1
    }
    bind nc = min(nc, 128)
    bind cu = zeros(nc)
    bind cf = zeros(nc)
    bind dimms = []
    bind disks = []
    bind dio = []
    bind sens = []
    bind i = 0
    while i < len(rows) {
        bind r = rows[i]
        bind tag = r[0]
        if tag == "b" {
            bind info = list_set(info, BI_MAKER, str_upper(sf(r, 1)))
            bind info = list_set(info, BI_PROD, str_upper(sf(r, 2)))
        }
        if tag == "i" {
            bind info = list_set(info, BI_BIOSV, str_upper(sf(r, 1)))
            bind info = list_set(info, BI_BIOSVER, sf(r, 2))
            bind info = list_set(info, BI_BIOSDATE, sf(r, 3))
        }
        if tag == "c" {
            bind info = list_set(info, BI_CPU, str_upper(sf(r, 1)))
            bind info = list_set(info, BI_CORES, nf(r, 2))
            bind info = list_set(info, BI_THR, nf(r, 3))
            bind info = list_set(info, BI_MHZ, nf(r, 4))
            bind info = list_set(info, BI_SOCK, nf(r, 5))
        }
        if tag == "y" {
            bind info = list_set(info, BI_SLOTS, nf(r, 1))
            bind info = list_set(info, BI_MAXGB, nf(r, 2))
        }
        if tag == "m" { bind dimms = list_push(dimms, [str_upper(sf(r, 1)), nf(r, 2), nf(r, 3)]) }
        if tag == "d" { bind disks = list_push(disks, [str_upper(sf(r, 1)), nf(r, 2)]) }
        if tag == "l" { bind bv = pad_to(nums(r, 1), BV_LEN) }
        if tag == "k" {
            bind c = floor(nf(r, 1))
            if c >= 0 {
                if c < nc {
                    bind cu = list_set(cu, c, nf(r, 2))
                    bind cf = list_set(cf, c, nf(r, 3))
                }
            }
        }
        if tag == "s" { bind dio = list_push(dio, [str_upper(sf(r, 1)), nf(r, 2), nf(r, 3), nf(r, 4)]) }
        if tag == "h" { bind sens = list_push(sens, [sf(r, 1), str_upper(sf(r, 2)), nf(r, 3)]) }
        bind i = i + 1
    }
    bind good = 0
    if len(bv) >= BV_LEN {
        if nc > 0 { bind good = 1 }
    }
    return [good, info, bv, cu, cf, dimms, disks, dio, sens, snap_time(rows)]
}

fn sim_board(t) {
    bind u = clamp(30.0 + 25.0 * sin(t * 0.3) + 35.0 * pow(abs(sin(t * 0.11)), 5.0), 2.0, 100.0)
    bind info = ["SIMCORP", "HATCH SIM Z999", "SIM BIOS", "1.0", "2030-01-01", "SIM CORE 16", 8, 16, 4800, 1, 4, 128]
    bind bv = [u, 2800.0 + 2000.0 * u / 100.0, 100.0, 32.0 + 28.0 * u / 100.0, 18000.0 + 160000.0 * u / 100.0, 2000.0 + 30000.0 * pow(abs(sin(t * 0.4)), 4.0),
               90000.0 + 600000.0 * u / 100.0, 800000.0 + 6000000.0 * u / 100.0, 420.0, 5200.0, 86400.0 * 3.0 + t,
               1000000.0 * pow(abs(sin(t * 0.23)), 6.0) * 300.0, 1000000.0 * pow(abs(sin(t * 0.19 + 1.0)), 6.0) * 200.0,
               30.0 * pow(abs(sin(t * 0.2)), 3.0), 1.0]
    bind cu = []
    bind cf = []
    bind i = 0
    while i < 16 {
        bind ci = clamp(u + 45.0 * sin(t * 0.5 + i * 0.9) - 15.0, 0.0, 100.0)
        bind cu = list_push(cu, ci)
        bind cf = list_push(cf, 1200.0 + 3600.0 * ci / 100.0)
        bind i = i + 1
    }
    bind dimms = [["DIMM_A1", 16.0, 5600.0], ["DIMM_B1", 16.0, 5600.0]]
    bind disks = [["SIM NVME 1000", 1000.0], ["SIM SATA 2000", 2000.0]]
    bind dio = [["0 C:", bv[BV_DRD], bv[BV_DWR], bv[BV_DBUSY]], ["1 D:", 0.0, 0.0, 0.0]]
    return [1, info, bv, cu, cf, dimms, disks, dio, [], 0.0]
}

# ───────────────────────────── network ───────────────────────────────────────
# pack NP: [good, adapters, nv, nodes, procs, t]; adapter [name, rx, tx, bits/s, pkts in, pkts out, errors];
# node [hash 0..1, port, state 0 est / 1 syn, process]; proc [name, connections]
bind NP_AD = 1
bind NP_NV = 2
bind NP_NODE = 3
bind NP_PROC = 4

# remote port -> one of the seven classes (= the seven Ling hues)
fn port_class(p) {
    if p == 443 { return 0 }
    if p == 80 { return 1 }
    if p == 8080 { return 1 }
    if p == 8000 { return 1 }
    if p == 53 { return 2 }
    if p == 5353 { return 2 }
    if p == 22 { return 3 }
    if p == 3389 { return 3 }
    if p == 5900 { return 3 }
    if p == 25 { return 4 }
    if p == 110 { return 4 }
    if p == 143 { return 4 }
    if p == 465 { return 4 }
    if p == 587 { return 4 }
    if p == 993 { return 4 }
    if p == 995 { return 4 }
    if p >= 1024 { return 5 }
    return 6
}

bind PORT_NAME = ["HTTPS", "HTTP", "DNS", "REMOTE", "MAIL", "HIGH", "OTHER"]

fn parse_net(text) {
    bind rows = snap_rows(text)
    bind ads = []
    bind nodes = []
    bind procs = []
    bind kk = [0.0, 0.0, 0.0, 0.0, 0.0]
    bind cc = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    bind rtt = 0.0 - 1.0
    bind i = 0
    while i < len(rows) {
        bind r = rows[i]
        bind tag = r[0]
        if tag == "i" { bind ads = list_push(ads, [sf(r, 1), nf(r, 2), nf(r, 3), nf(r, 4), nf(r, 5), nf(r, 6), nf(r, 7)]) }
        if tag == "k" { bind kk = pad_to(nums(r, 1), 5) }
        if tag == "r" { bind rtt = nf(r, 1) }
        if tag == "c" { bind cc = pad_to(nums(r, 1), 7) }
        if tag == "x" { bind procs = list_push(procs, [str_upper(sf(r, 1)), nf(r, 3)]) }
        if tag == "d" {
            bind st = 0
            if sf(r, 3) != "ESTABLISHED" { bind st = 1 }
            bind nodes = list_push(nodes, [nf(r, 1), nf(r, 2), st, str_upper(sf(r, 4))])
        }
        bind i = i + 1
    }
    bind rx = 0.0
    bind tx = 0.0
    bind prx = 0.0
    bind ptx = 0.0
    bind bw = 0.0
    bind a = 0
    while a < len(ads) {
        bind ad = ads[a]
        bind rx = rx + ad[1]
        bind tx = tx + ad[2]
        bind prx = prx + ad[4]
        bind ptx = ptx + ad[5]
        if a == 0 { bind bw = ad[3] }
        bind a = a + 1
    }
    bind nv = [rx, tx, prx, ptx, bw, kk[0], kk[1], kk[4], rtt, cc[1], cc[2], cc[3], cc[4], cc[6], kk[2]]
    bind good = 0
    if len(ads) > 0 { bind good = 1 }
    return [good, ads, nv, nodes, procs, snap_time(rows)]
}

fn sim_net(t) {
    bind b1 = pow(abs(sin(t * 0.21)), 5.0)
    bind b2 = pow(abs(sin(t * 0.33 + 1.0)), 6.0)
    bind rx = 40000.0 + 90000.0 * (1.0 + sin(t * 0.5)) + 40000000.0 * b1
    bind tx = 8000.0 + 20000.0 * (1.0 + sin(t * 0.4)) + 6000000.0 * b2
    bind ads = [["SIM ETHERNET", rx, tx, 1000000000.0, rx / 1200.0, tx / 900.0, 0.0]]
    bind nodes = []
    bind ports = [443, 443, 443, 80, 53, 22, 8333, 25565, 443, 993, 443, 3389, 8080, 51820]
    bind i = 0
    while i < 28 {
        bind nodes = list_push(nodes, [fract(i * 0.6180339 + 0.1), ports[i % 14], 0, str_upper(SIM_NAMES[(i * 7) % 20])])
        bind i = i + 1
    }
    bind procs = []
    bind i = 0
    while i < 8 {
        bind procs = list_push(procs, [str_upper(SIM_NAMES[i]), 12.0 - i])
        bind i = i + 1
    }
    bind nv = [rx, tx, rx / 1200.0, tx / 900.0, 1000000000.0, 90.0 + 20.0 * sin(t * 0.2), 2.0 + 30.0 * b2, 15.0 + 60.0 * b1, 8.0 + 10.0 * b2, 12.0, 6.0, 2.0, 0.0, 40.0, 3.0]
    return [1, ads, nv, nodes, procs, 0.0]
}

# ───────────────────────────── history sampling ──────────────────────────────
# push one 0..1 sample into every strip; GP, BP, NP are the smoothed packs
fn hs_sample(hs, GP, BP, NP, memUsed, memFlt) {
    bind g = 0
    while g < min(GP[GP_N], 8) {
        bind v = GP[GP_VEC][g]
        bind b = HS_GPU + g * 4
        bind hs = hs_push(hs, b, v[GV_UTIL] / 100.0)
        bind hs = hs_push(hs, b + 1, v[GV_TEMP] / 100.0)
        bind hs = hs_push(hs, b + 2, v[GV_POWER] / max(v[GV_PLIM], 1.0))
        bind hs = hs_push(hs, b + 3, v[GV_VUSED] / max(v[GV_VTOTAL], 1.0))
        bind g = g + 1
    }
    bind bv = BP[BP_BV]
    bind hs = hs_push(hs, HS_BRD, bv[BV_UTIL] / 100.0)
    bind hs = hs_push(hs, HS_BRD + 1, bv[BV_TEMP] / 100.0)
    bind hs = hs_push(hs, HS_BRD + 2, lg(bv[BV_INTR], 6.0))
    bind hs = hs_push(hs, HS_BRD + 3, lg(bv[BV_DPC], 5.0))
    bind hs = hs_push(hs, HS_BRD + 4, lg(bv[BV_CTX], 6.5))
    bind hs = hs_push(hs, HS_BRD + 5, lg(bv[BV_DRD], 9.0))
    bind hs = hs_push(hs, HS_BRD + 6, lg(bv[BV_DWR], 9.0))
    bind nv = NP[NP_NV]
    bind hs = hs_push(hs, HS_NET, lg(nv[NV_RX], 9.0))
    bind hs = hs_push(hs, HS_NET + 1, lg(nv[NV_TX], 9.0))
    bind hs = hs_push(hs, HS_NET + 2, lg(nv[NV_PRX], 6.0))
    bind hs = hs_push(hs, HS_NET + 3, lg(nv[NV_PTX], 6.0))
    bind hs = hs_push(hs, HS_NET + 4, lg(nv[NV_EST], 3.5))
    bind hs = hs_push(hs, HS_NET + 5, lg(nv[NV_UDP], 4.0))
    bind rt = 0.0
    if nv[NV_RTT] > 0.0 { bind rt = nv[NV_RTT] / 500.0 }
    bind hs = hs_push(hs, HS_NET + 6, rt)
    bind hs = hs_push(hs, HS_NET + 7, lg(nv[NV_RETX], 3.0))
    bind hs = hs_push(hs, HS_MEM, memUsed)
    bind hs = hs_push(hs, HS_MEM + 1, lg(memFlt, 6.0))
    return hs
}

← Back to index